os/graphics/graphicstest/uibench/s60/src/openvgengine.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicstest/uibench/s60/src/openvgengine.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,435 @@
     1.4 + // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 + // All rights reserved.
     1.6 + // This component and the accompanying materials are made available
     1.7 + // under the terms of "Eclipse Public License v1.0"
     1.8 + // which accompanies this distribution, and is available
     1.9 + // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 + //
    1.11 + // Initial Contributors:
    1.12 + // Nokia Corporation - initial contribution.
    1.13 + //
    1.14 + // Contributors:
    1.15 + //
    1.16 + // Description:
    1.17 + //
    1.18 +
    1.19 +
    1.20 +#include "openvgengine.h"
    1.21 +#include "eglrendering.h"
    1.22 +
    1.23 +#include <eikenv.h>
    1.24 +#include <e32math.h>
    1.25 +
    1.26 +
    1.27 +_LIT(KCoverBitmaps, "z:\\resource\\apps\\covers.mbm");
    1.28 +
    1.29 +
    1.30 +GLDEF_D VGUErrorCode vguComputeWarpQuadToQuadProxy(VGfloat dx0, VGfloat dy0,
    1.31 +                                                   VGfloat dx1, VGfloat dy1,
    1.32 +                                                   VGfloat dx2, VGfloat dy2,
    1.33 +                                                   VGfloat dx3, VGfloat dy3,
    1.34 +                                                   VGfloat sx0, VGfloat sy0,
    1.35 +                                                   VGfloat sx1, VGfloat sy1,
    1.36 +                                                   VGfloat sx2, VGfloat sy2,
    1.37 +                                                   VGfloat sx3, VGfloat sy3,
    1.38 +                                                   VGfloat * matrix)
    1.39 +	{
    1.40 +	vguComputeWarpQuadToQuad(
    1.41 +                                                   sx0, sy0,
    1.42 +                                                   sx1, sy1,
    1.43 +                                                   sx2, sy2,
    1.44 +                                                   sx3, sy3,
    1.45 +                                                   dx0, dy0,
    1.46 +                                                   dx1, dy1,
    1.47 +                                                   dx2, dy2,
    1.48 +                                                   dx3, dy3,
    1.49 +                                                   matrix);
    1.50 +	return VGU_NO_ERROR;
    1.51 +	}
    1.52 +
    1.53 +COpenVGEngine* COpenVGEngine::NewL(RWindow& aWindow,EGLDisplay& aDisplay, EGLSurface& aSurface, EGLContext& aContext)
    1.54 +	{
    1.55 +	COpenVGEngine* self = new(ELeave) COpenVGEngine(aWindow, aDisplay, aSurface, aContext);
    1.56 +	return self;
    1.57 +	}
    1.58 +
    1.59 +COpenVGEngine::COpenVGEngine(RWindow& aWindow,EGLDisplay& aDisplay, EGLSurface& aSurface, EGLContext& aContext) :
    1.60 +        iWindow(aWindow), iDisplay(aDisplay), iSurface(aSurface), iContext(aContext), iWantedCover(20),
    1.61 +        iHasPendingDraw(EFalse), iShowCoverImage(EFalse), iSpeedOffset(0), iShowMirror(ETrue), iSpeed(0),
    1.62 +        iCurrentImageIndex(0)
    1.63 +    {
    1.64 +#ifdef PORTRAIT_MODE
    1.65 +    iSurfaceSize.iWidth = iWindow.Size().iHeight;
    1.66 +    iSurfaceSize.iHeight = iWindow.Size().iWidth;
    1.67 +#else
    1.68 +    iSurfaceSize = iWindow.Size();
    1.69 +#endif  
    1.70 +    // initiate the location of each cover & make the wanted one the cover at the opposite end
    1.71 +    for(TInt i = 0; i < KMaxCoversExample3; ++i)
    1.72 +        {
    1.73 +        iCoverLocation[i] = i;
    1.74 +        }
    1.75 +    }
    1.76 +
    1.77 +COpenVGEngine::~COpenVGEngine()
    1.78 +	{
    1.79 +	Deactivate();
    1.80 +	}
    1.81 +
    1.82 +TInt COpenVGEngine::GetSpeed()
    1.83 +	{
    1.84 +	return static_cast<TInt>(iSpeed * 100000);
    1.85 +	}
    1.86 +
    1.87 +TBool COpenVGEngine::IsPending()
    1.88 +	{
    1.89 +	return iHasPendingDraw;
    1.90 +	}
    1.91 +
    1.92 +void COpenVGEngine::ActivateL()
    1.93 +	{
    1.94 +	CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
    1.95 +	
    1.96 +	// Setup initial OpenVG context state
    1.97 +	VGfloat clearColour[] = { 0.1f, 0.1f, 0.2f, 1.0f };
    1.98 +	vgSetfv(VG_CLEAR_COLOR, 4, clearColour);
    1.99 +	vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
   1.100 +	vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED);	
   1.101 +	vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
   1.102 +
   1.103 +	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap();
   1.104 +	CleanupStack::PushL(bitmap);
   1.105 +	TInt idx = 0;
   1.106 +	while(bitmap->Load(KCoverBitmaps, idx++) == KErrNone)
   1.107 +		{
   1.108 +		VGint width = bitmap->SizeInPixels().iWidth;
   1.109 +		VGint height = bitmap->SizeInPixels().iHeight;
   1.110 +		// Crate VGImage
   1.111 +		VGImage image = vgCreateImage(VG_sRGB_565, width, height, VG_IMAGE_QUALITY_NONANTIALIASED);
   1.112 +		CEGLRendering::VGCheckError();
   1.113 +		//Load Symbian bitmap into VGImage
   1.114 +		vgImageSubData(image, bitmap->DataAddress(), bitmap->DataStride(), VG_sRGB_565, 0, 0, width, height);
   1.115 +		CEGLRendering::VGCheckError();
   1.116 +		iImages.AppendL(image);		
   1.117 +		}
   1.118 +	CleanupStack::PopAndDestroy(bitmap);
   1.119 +	iHasPendingDraw = ETrue;
   1.120 +	
   1.121 +	//Checks if any images were loaded
   1.122 +	if(iImages.Count() == 0)
   1.123 +		{
   1.124 +		User::Leave(KErrNotFound);
   1.125 +		}
   1.126 +	
   1.127 +	iShadowPaint = vgCreatePaint();
   1.128 +	CEGLRendering::VGCheckError();
   1.129 +	if (iShadowPaint != VG_INVALID_HANDLE)
   1.130 +		{
   1.131 +		VGfloat paintColour[4] = { 0.4f, 0.4f, 0.6f, 1.0f };
   1.132 +		vgSetParameterfv(iShadowPaint, VG_PAINT_COLOR, 4, paintColour); 
   1.133 +		CEGLRendering::VGCheckError();
   1.134 +		}
   1.135 +	}
   1.136 +
   1.137 +void COpenVGEngine::Deactivate()
   1.138 +	{
   1.139 +	CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
   1.140 +	for (TInt i = iImages.Count() - 1; i >= 0; --i)
   1.141 +		{
   1.142 +		vgDestroyImage(iImages[i]);
   1.143 +		}
   1.144 +	vgDestroyPaint(iShadowPaint);
   1.145 +	eglWaitClient();
   1.146 +	iImages.Reset();
   1.147 +	iHasPendingDraw = EFalse;
   1.148 +	}
   1.149 +
   1.150 +void COpenVGEngine::Step()
   1.151 +	{
   1.152 +	CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
   1.153 +		
   1.154 +#ifdef PORTRAIT_MODE	
   1.155 +	vgClear(0, 0, iSurfaceSize.iHeight, iSurfaceSize.iWidth);
   1.156 +#else
   1.157 +	vgClear(0, 0, iSurfaceSize.iWidth, iSurfaceSize.iHeight);
   1.158 +#endif
   1.159 +	
   1.160 +	if (Abs(iCoverLocation[iWantedCover]) < 0.03)
   1.161 +		{
   1.162 +		iSpeed = 0.0f;
   1.163 +		iHasPendingDraw = EFalse;
   1.164 +		}
   1.165 +	else if (Abs(iCoverLocation[iWantedCover]) < 0.5)
   1.166 +		{
   1.167 +		iSpeed *= 0.7;
   1.168 +		}
   1.169 +	else
   1.170 +		{
   1.171 +		iSpeed = 0.05 * (2 + Abs(iCoverLocation[iWantedCover]) + (Abs(iCoverLocation[iWantedCover]) + 1)
   1.172 +                    * (Abs(iCoverLocation[iWantedCover]) + 1) / 2);
   1.173 +		}
   1.174 +	// For each Cover, update its location in the correct direction
   1.175 +	// Check if the wanted cover is already at the CenterStage point
   1.176 +
   1.177 +	VGfloat moveEachCover = iSpeed;
   1.178 +	if (iCoverLocation[iWantedCover] > 0.0)
   1.179 +		{
   1.180 +		moveEachCover *= -1;
   1.181 +		}	
   1.182 +	
   1.183 +	for (TInt i = 0; i < KMaxCoversExample3; ++i)
   1.184 +		{
   1.185 +		iCoverLocation[i] += moveEachCover;
   1.186 +		}
   1.187 +	
   1.188 +	TInt coverClippingCount = 10;
   1.189 +	TInt middleCoverPos = 0;
   1.190 +	VGfloat threshold = 0.50f;
   1.191 +
   1.192 +	while(Abs(iCoverLocation[middleCoverPos]) > threshold)
   1.193 +		{
   1.194 +		++middleCoverPos;
   1.195 +		}
   1.196 +	
   1.197 +	
   1.198 +	//left
   1.199 +	TInt cutOff = middleCoverPos - coverClippingCount;
   1.200 +	if (cutOff <0 )
   1.201 +		{
   1.202 +		cutOff = 0;
   1.203 +		}
   1.204 +	for (TInt i = cutOff; i < middleCoverPos; ++i)
   1.205 +		{
   1.206 +		DrawCover(i);
   1.207 +		}
   1.208 +	
   1.209 +	//right
   1.210 +	cutOff = coverClippingCount + middleCoverPos;
   1.211 +	if (cutOff >= KMaxCoversExample3)
   1.212 +		{
   1.213 +		cutOff = KMaxCoversExample3-1;
   1.214 +		}
   1.215 +	
   1.216 +	for (TInt j = cutOff; j >= middleCoverPos; --j)
   1.217 +	    {
   1.218 +		DrawCover(j);
   1.219 +        }
   1.220 +
   1.221 +	static TInt dir = 1;
   1.222 +	if (iWantedCover == (KMaxCoversExample3 - 1))
   1.223 +		{
   1.224 +		dir = -1;
   1.225 +		}
   1.226 +	else if (iWantedCover == 0)
   1.227 +		{
   1.228 +		dir = 1;
   1.229 +		}
   1.230 +
   1.231 +	iWantedCover += dir;
   1.232 +	iHasPendingDraw = ETrue;
   1.233 +	}
   1.234 +
   1.235 +void COpenVGEngine::DrawCover(TInt coverIndex)
   1.236 +	{ 	
   1.237 +		VGImage image = iImages[coverIndex % iImages.Count()];
   1.238 +		// Starting at the outside, render each visible (+/-  KMaxDisplayCoversExample3/2) Cover
   1.239 +		// Calculate its path
   1.240 +		vgLoadIdentity();
   1.241 +#ifdef PORTRAIT_MODE
   1.242 +		vgTranslate(iSurfaceSize.iHeight, 0);
   1.243 +		vgRotate(90);
   1.244 +#endif
   1.245 +		VGfloat coverPosition = iCoverLocation[coverIndex];
   1.246 +		VGfloat tempMatrix[3][3];
   1.247 +
   1.248 +		//flip coords
   1.249 +		VGfloat flipmatrix[] = 
   1.250 +			{
   1.251 +			1.0f, 0.0f, 0.0f, 
   1.252 +			0.0f, -1.0f, 0.0f,
   1.253 +			0.0f, 0.0f, 1.0f
   1.254 +			};
   1.255 +		vgMultMatrix(flipmatrix);		
   1.256 +		VGint imageWidth = vgGetParameteri(image, VG_IMAGE_WIDTH);
   1.257 +		VGint imageHeight = vgGetParameteri(image, VG_IMAGE_HEIGHT);
   1.258 +
   1.259 +		//VGint yTrans = -200;	
   1.260 +		
   1.261 +		//factors which must be multiplied with side of image which will be projected towards back
   1.262 +		//valid if projecting right image side to back
   1.263 +		//opposite is (1 - factor) for projecting left image side.
   1.264 +
   1.265 +		VGfloat bottomProjectXFactor= (0.75f);
   1.266 +		VGfloat bottomProjectYFactor = (0.20f);
   1.267 +		
   1.268 +		VGfloat topProjectXFactor = (0.75f);
   1.269 +		VGfloat topProjectYFactor = (0.90f);
   1.270 +				
   1.271 +		VGfloat imageSpacingFactor = 0.16;
   1.272 +		
   1.273 +		VGfloat translationOffset = 0.0;
   1.274 +		
   1.275 +
   1.276 +		//float yscale = 1.7;
   1.277 +		//float xscale = 4.4;
   1.278 +		//imageHeight = Min(iSurfaceSize.iWidth/xscale, iSurfaceSize.iHeight/yscale);
   1.279 +		//imageWidth = imageHeight;
   1.280 +		//TInt KImageSize = imageHeight/1.125;
   1.281 +		//VGint yTrans = iSurfaceSize.iHeight/-1.2;	
   1.282 +		
   1.283 +		TInt KImageSize = (imageHeight * 8) / 9; //KImageSize - secondary covers should be 8/9 of the size of the middle cover
   1.284 +		//VGint yTrans = -200;	
   1.285 +		VGint yTrans = - (iWindow.Size().iHeight * 5) / 6;	
   1.286 +		
   1.287 +		
   1.288 +		VGfloat middleTranslationOffset = KImageSize / 2;		
   1.289 +		VGfloat coverProjectionLimit = 10;
   1.290 +		
   1.291 +		if (coverPosition >= 1)
   1.292 +			{
   1.293 +			//if considering an image on the right side, this is offset from middle to place image on screen			
   1.294 +			translationOffset = middleTranslationOffset- KImageSize/2 + KImageSize*imageSpacingFactor * (coverPosition -1);
   1.295 +						
   1.296 +			//left side of image goes back.
   1.297 +			vguComputeWarpQuadToQuadProxy(0.0f, 0.0f, 
   1.298 +					   imageWidth, 0.0f, 
   1.299 +					   0.0f, imageHeight, 
   1.300 +					   imageWidth, imageHeight,					   
   1.301 +					   KImageSize * (1 - bottomProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)),KImageSize * bottomProjectYFactor,//left vertex
   1.302 +					   KImageSize, 0.0f,
   1.303 +					   KImageSize * (1 - topProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)), KImageSize * topProjectYFactor,//left vertex
   1.304 +					   KImageSize, KImageSize,			   
   1.305 +					   &tempMatrix[0][0]);
   1.306 +			}
   1.307 +		else if (coverPosition < -1)
   1.308 +			{			
   1.309 +			//must move an extra image width from center , as coordinates from bottom left corner of image. 
   1.310 +			translationOffset = - (middleTranslationOffset + (KImageSize * imageSpacingFactor) * ( -coverPosition - 1) + KImageSize/2) ;
   1.311 +			
   1.312 +			vguComputeWarpQuadToQuadProxy(  0.0f, 0.0f, 
   1.313 +					   imageWidth, 0.0f, 
   1.314 +					   0.0f, imageHeight, 
   1.315 +					   imageWidth, imageHeight,
   1.316 +					   
   1.317 +					   0.0f, 0.0f,
   1.318 +					   (bottomProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit))* KImageSize, bottomProjectYFactor * KImageSize, //Right Vertex
   1.319 +					   0.0f, (KImageSize),
   1.320 +					   (topProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)) * KImageSize, topProjectYFactor * KImageSize, //Right Vertex
   1.321 +					   
   1.322 +					   &tempMatrix[0][0]);			
   1.323 +			}
   1.324 +		else if((coverPosition > -1) && (coverPosition <= 0))// -0.07))
   1.325 +			{			
   1.326 +			translationOffset = -middleTranslationOffset * Abs(coverPosition) - KImageSize/2 ;
   1.327 +						
   1.328 +			vguComputeWarpQuadToQuadProxy(  0.0f, 0.0f, 
   1.329 +	    						   imageWidth, 0.0f, 
   1.330 +	    						   0.0f, imageHeight, 
   1.331 +	    						   imageWidth, imageHeight,	    						   
   1.332 +	    						   0.0f, 0.0f,
   1.333 +	    						   KImageSize * (1 - (1-bottomProjectXFactor) * Abs(coverPosition)), KImageSize * bottomProjectYFactor * Abs(coverPosition),
   1.334 +	    						   0.0f, KImageSize,
   1.335 +	    						   (KImageSize * (1 - ( 1 - topProjectXFactor) * Abs(coverPosition))) , KImageSize * (1 - (1 - topProjectYFactor) * Abs(coverPosition)),	    						   
   1.336 +	    						   &tempMatrix[0][0]);		
   1.337 +			}				
   1.338 +		else if ((coverPosition >=0) && (coverPosition <= 1))
   1.339 +			{
   1.340 +			translationOffset = middleTranslationOffset * Abs(coverPosition) - KImageSize / 2;				    						   			
   1.341 +			vguComputeWarpQuadToQuadProxy( 0.0f, 0.0f, 
   1.342 +	    						   imageWidth, 0.0f, 
   1.343 +	    						   0.0f, imageHeight, 
   1.344 +	    						   imageWidth, imageHeight,	    						   
   1.345 +	    						   KImageSize * (1-bottomProjectXFactor)* (coverPosition), KImageSize * (bottomProjectYFactor) * (coverPosition),
   1.346 +	    						   KImageSize, 0,
   1.347 +	    						   KImageSize * ( 1 - topProjectXFactor) * (coverPosition) , KImageSize * (1 - (1 - topProjectYFactor) * Abs(coverPosition)),
   1.348 +	    						   KImageSize, KImageSize,	    						   
   1.349 +	    						   &tempMatrix[0][0]);
   1.350 +			}
   1.351 +		iSpeedOffset = 140*(iSpeed)*(iSpeed);		
   1.352 +        if (iCoverLocation[iWantedCover] < 0)
   1.353 +            {
   1.354 +            iSpeedOffset *= -1;
   1.355 +            }
   1.356 +		vgTranslate(iWindow.Size().iWidth/2 + translationOffset + iSpeedOffset, yTrans);
   1.357 +						
   1.358 +		vgMultMatrix(&tempMatrix[0][0]);
   1.359 +		if (Abs(coverPosition) <= 1)
   1.360 +			{
   1.361 +			VGfloat scale = GetMiddleCoverScalingFactor(coverPosition);
   1.362 +			vgScale(scale,scale);
   1.363 +			vgTranslate(-(scale-1)/2 * KImageSize,-(scale-1)/2 * KImageSize);
   1.364 +			}
   1.365 +		vgDrawImage(image);
   1.366 +		CEGLRendering::VGCheckError();
   1.367 +		if (iShowMirror)
   1.368 +			{
   1.369 +			vgScale(1,-1);
   1.370 +			vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
   1.371 +			vgTranslate(0,-4*KImageSize+226); 
   1.372 +			//vgTranslate(0,iSurfaceSize.iHeight/-.839); 
   1.373 +					
   1.374 +			vgSetPaint(iShadowPaint, VG_FILL_PATH);
   1.375 +			vgDrawImage(image);
   1.376 +			CEGLRendering::VGCheckError();
   1.377 +				
   1.378 +			vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
   1.379 +			}
   1.380 +	}
   1.381 +
   1.382 +TKeyResponse COpenVGEngine::HandleKeyEventL(const TKeyEvent& aKeyEvent)
   1.383 +	{
   1.384 +	TKeyResponse response = EKeyWasConsumed;
   1.385 +	switch (aKeyEvent.iCode)
   1.386 +		{
   1.387 +	case EKeyRightArrow:
   1.388 +		NextCover();
   1.389 +		break;	
   1.390 +	case EKeyLeftArrow:
   1.391 +		PreviousCover();
   1.392 +		break;		
   1.393 +	case EKeyBackspace: 
   1.394 +		ToggleCoverReflection();
   1.395 +		break;		
   1.396 +	default:
   1.397 +		response = EKeyWasNotConsumed;
   1.398 +		break;
   1.399 +		};
   1.400 +	return response;
   1.401 +	}
   1.402 +
   1.403 +void COpenVGEngine::NextCover()
   1.404 +	{
   1.405 +	if (iWantedCover < (KMaxCoversExample3 - 1))
   1.406 +	    {
   1.407 +	    ++iWantedCover;
   1.408 +	    iHasPendingDraw = ETrue;
   1.409 +	    }		
   1.410 +	}
   1.411 +
   1.412 +void COpenVGEngine::PreviousCover()
   1.413 +	{
   1.414 +	if (iWantedCover > 0)
   1.415 +	    {
   1.416 +	    --iWantedCover;
   1.417 +	    iHasPendingDraw = ETrue;
   1.418 +	    }
   1.419 +	}
   1.420 +
   1.421 +void COpenVGEngine::ToggleCoverReflection()
   1.422 +	{
   1.423 +	iShowMirror = !iShowMirror;
   1.424 +	}
   1.425 +
   1.426 +VGfloat COpenVGEngine::GetMiddleCoverScalingFactor(VGfloat aCoverPosition)
   1.427 +	{
   1.428 +	if(Abs(aCoverPosition) > 1)
   1.429 +	    {
   1.430 +	    return 0.0f;
   1.431 +	    }
   1.432 +	return (-0.125 * Abs(aCoverPosition) + 1.125);	
   1.433 +	}
   1.434 +
   1.435 +void COpenVGEngine::Refresh()
   1.436 +	{
   1.437 +	iHasPendingDraw = ETrue;
   1.438 +	}