1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1106 @@
1.4 +// Copyright (c) 2007-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 + @file
1.21 + @test
1.22 + @internalComponent - Internal Symbian test code
1.23 +*/
1.24 +
1.25 +
1.26 +#include "egltest_surface.h"
1.27 +#include "egltest_endpoint_images.h"
1.28 +#include <graphics/surfaceconfiguration.h>
1.29 +#include <e32std.h>
1.30 +#include <e32math.h>
1.31 +#include <VG/vgu.h>
1.32 +
1.33 +
1.34 +#define SURF_ASSERT(x) { if (!(x)) { RDebug::Printf("ASSERT(%s) failed at %s:%d", #x, __FILE__, __LINE__); User::Panic(_L("ASSERT SURF"), __LINE__); }}
1.35 +
1.36 +// Macros for indicating what is what.
1.37 +#define SIZE(x, y) x, y
1.38 +#define Buffers(x) x
1.39 +#define DefaultAlignment 32 // Pick some value that is valid.
1.40 +#define Alignment(x) x
1.41 +#define Stride(x) x
1.42 +#define DefaultStride 0
1.43 +// Note: Offset to first buffer.
1.44 +#define Offset(x) x
1.45 +#define WindowPos(x, y) x, y
1.46 +#define WindowMode(m) m
1.47 +
1.48 +#define LARGEST_POSSIBLE_FLAG 0x80000000
1.49 +
1.50 +static const TSurfaceParamsCommon KSurfaceParams[] =
1.51 +{
1.52 + {
1.53 + EStandardSurface,
1.54 + SIZE(100, 100),
1.55 + Buffers(2),
1.56 + DefaultAlignment,
1.57 + DefaultStride,
1.58 + Offset(0),
1.59 + EUidPixelFormatARGB_8888_PRE,
1.60 + EFalse,
1.61 + { 0 },
1.62 + WindowPos(0, 0),
1.63 + WindowMode(EColor16MAP)
1.64 + },
1.65 + {
1.66 + EBadAttribSurface,
1.67 + SIZE(100, 100),
1.68 + Buffers(2),
1.69 + DefaultAlignment,
1.70 + DefaultStride,
1.71 + Offset(0),
1.72 + EUidPixelFormatARGB_8888_PRE,
1.73 + ETrue,
1.74 + { 1, 1, EGL_NONE },
1.75 + WindowPos(0, 0),
1.76 + WindowMode(EColor16MAP)
1.77 + },
1.78 + {
1.79 + EEmptyAttribSurface,
1.80 + SIZE(100, 100),
1.81 + Buffers(2),
1.82 + DefaultAlignment,
1.83 + DefaultStride,
1.84 + Offset(0),
1.85 + EUidPixelFormatARGB_8888_PRE,
1.86 + ETrue,
1.87 + { EGL_NONE },
1.88 + WindowPos(0, 0),
1.89 + WindowMode(EColor16MAP)
1.90 + },
1.91 + {
1.92 + EStandard128sqSurface,
1.93 + SIZE(128, 128),
1.94 + Buffers(3),
1.95 + DefaultAlignment,
1.96 + DefaultStride,
1.97 + Offset(0),
1.98 + EUidPixelFormatARGB_8888_PRE,
1.99 + EFalse,
1.100 + { 0 },
1.101 + WindowPos(20, 20),
1.102 + WindowMode(EColor16MAP)
1.103 + },
1.104 + {
1.105 + EUnusualStrideSurface,
1.106 + SIZE(167,263),
1.107 + Buffers(2),
1.108 + Alignment(8),
1.109 + Stride(167*4+64),
1.110 + Offset(200),
1.111 + EUidPixelFormatARGB_8888_PRE,
1.112 + EFalse,
1.113 + { 0 },
1.114 + WindowPos(0, 0),
1.115 + WindowMode(EColor16MAP)
1.116 + },
1.117 + {
1.118 + EUnalignedPixelSizeSurface,
1.119 + SIZE(103, 107),
1.120 + Buffers(2),
1.121 + Alignment(8),
1.122 + Stride(103*4),
1.123 + Offset(0),
1.124 + EUidPixelFormatARGB_8888_PRE,
1.125 + EFalse,
1.126 + { 0 },
1.127 + WindowPos(0, 0),
1.128 + WindowMode(EColor16MAP)
1.129 + },
1.130 + {
1.131 + ELargeSurface,
1.132 + SIZE(800, 600),
1.133 + Buffers(2),
1.134 + DefaultAlignment,
1.135 + DefaultStride,
1.136 + Offset(0),
1.137 + EUidPixelFormatARGB_8888_PRE,
1.138 + EFalse,
1.139 + { 0 },
1.140 + WindowPos(0, 0),
1.141 + WindowMode(EColor16MAP)
1.142 + },
1.143 + {
1.144 + ELargestPossibleSurface,
1.145 + SIZE(LARGEST_POSSIBLE_FLAG, LARGEST_POSSIBLE_FLAG),
1.146 + Buffers(2),
1.147 + DefaultAlignment,
1.148 + DefaultStride,
1.149 + Offset(0),
1.150 + EUidPixelFormatARGB_8888_PRE,
1.151 + EFalse,
1.152 + { 0 },
1.153 + WindowPos(0, 0),
1.154 + WindowMode(EColor16MAP)
1.155 + },
1.156 + {
1.157 + ESmallSurface,
1.158 + SIZE(16, 16),
1.159 + Buffers(1),
1.160 + DefaultAlignment,
1.161 + DefaultStride,
1.162 + Offset(0),
1.163 + EUidPixelFormatARGB_8888_PRE,
1.164 + EFalse,
1.165 + { 0 },
1.166 + WindowPos(0, 0),
1.167 + WindowMode(EColor16MAP)
1.168 + },
1.169 + {
1.170 + ETinySurface,
1.171 + SIZE(8, 8),
1.172 + Buffers(1),
1.173 + DefaultAlignment,
1.174 + DefaultStride,
1.175 + Offset(0),
1.176 + EUidPixelFormatARGB_8888_PRE,
1.177 + EFalse,
1.178 + { 0 },
1.179 + WindowPos(0, 0),
1.180 + WindowMode(EColor16MAP)
1.181 + },
1.182 +};
1.183 +
1.184 +const TInt KSurfaceMaxIndex = sizeof(KSurfaceParams) / sizeof(KSurfaceParams[0]);
1.185 +
1.186 +struct TSurfaceSize
1.187 + {
1.188 + TInt iWidth;
1.189 + TInt iHeight;
1.190 + };
1.191 +
1.192 +static const TSurfaceSize KSurfaceSizes[] =
1.193 + {
1.194 + { 320, 240 },
1.195 + { 640, 480 },
1.196 + { 720, 480 },
1.197 + { 854, 480 },
1.198 + { 720, 576 },
1.199 + { 854, 576 },
1.200 + { 1280, 720 },
1.201 + { 1024, 768 },
1.202 + { 1280, 1024 },
1.203 + { 1920, 1080 },
1.204 + { 1600, 1200 },
1.205 +#if 0
1.206 + { 2048, 1536 },
1.207 + { 2560, 1920 },
1.208 + { 3648, 2736 },
1.209 + { 4216, 2638 },
1.210 + { 4000, 3000 },
1.211 + { 4616, 2600 },
1.212 +#endif
1.213 + };
1.214 +
1.215 +const TInt KMaxSurfaceSizes = sizeof(KSurfaceSizes) / sizeof(KSurfaceSizes[0]);
1.216 +
1.217 +LOCAL_C TUint RandomNumberInRange(TUint aLow, TUint aHigh)
1.218 + {
1.219 + TReal32 rand = Math::Random();
1.220 + rand /= KMaxTUint;
1.221 + rand *= aHigh - aLow;
1.222 + rand += aLow;
1.223 + return TUint(rand);
1.224 + }
1.225 +
1.226 +
1.227 +void CSurface::CreateL(TInt aIndex)
1.228 + {
1.229 + CreateL(aIndex, TPoint(0, 0));
1.230 + }
1.231 +
1.232 +
1.233 +TSize CSurface::Size()
1.234 + {
1.235 + return iActualSize;
1.236 + }
1.237 +
1.238 +
1.239 +TInt CSurface::SizeInBytes() const
1.240 + {
1.241 + RSurfaceManager::TInfoBuf infoBuf;
1.242 + RSurfaceManager surfMgr;
1.243 + TInt err = surfMgr.Open();
1.244 + if (err != KErrNone)
1.245 + {
1.246 + RDebug::Printf("Error opening surface manager... Err=%d", err);
1.247 + return 0;
1.248 + }
1.249 + err = surfMgr.SurfaceInfo(SurfaceId(), infoBuf);
1.250 + if (err != KErrNone)
1.251 + {
1.252 + RDebug::Printf("Could not get surface info - err = %d", err);
1.253 + return 0;
1.254 + }
1.255 + TInt size = infoBuf().iBuffers * infoBuf().iSize.iHeight * infoBuf().iStride;
1.256 + surfMgr.Close();
1.257 + return size;
1.258 + }
1.259 +
1.260 +
1.261 +CRawSurface* CRawSurface::NewL()
1.262 + {
1.263 + CRawSurface* obj = new (ELeave) CRawSurface();
1.264 + CleanupStack::PushL(obj);
1.265 + obj->ConstructL();
1.266 + CleanupStack::Pop(obj);
1.267 + return obj;
1.268 + }
1.269 +
1.270 +
1.271 +
1.272 +CRawSurface::CRawSurface() : iDrawBuffer(0), iBuffers(0)
1.273 + {
1.274 + }
1.275 +
1.276 +
1.277 +void CRawSurface::ConstructL()
1.278 + {
1.279 + iSurfaceId = TSurfaceId::CreateNullId();
1.280 + User::LeaveIfError(iSurfaceManager.Open());
1.281 + User::LeaveIfError(iSurfaceUpdate.Connect());
1.282 + }
1.283 +
1.284 +
1.285 +CRawSurface::~CRawSurface()
1.286 + {
1.287 + iSurfaceUpdate.Close();
1.288 + if(!iSurfaceId.IsNull())
1.289 + {
1.290 + iSurfaceManager.CloseSurface(iSurfaceId);
1.291 + }
1.292 + iSurfaceManager.Close();
1.293 + }
1.294 +
1.295 +
1.296 +TInt CRawSurface::PixelSize(TUidPixelFormat aPixelFormat)
1.297 + {
1.298 + switch(aPixelFormat)
1.299 + {
1.300 + case EUidPixelFormatARGB_8888_PRE:
1.301 + case EUidPixelFormatARGB_8888:
1.302 + case EUidPixelFormatABGR_8888:
1.303 + case EUidPixelFormatABGR_8888_PRE:
1.304 + return 4;
1.305 +
1.306 + case EUidPixelFormatARGB_4444:
1.307 + case EUidPixelFormatRGB_565:
1.308 + return 2;
1.309 +
1.310 + default:
1.311 + SURF_ASSERT(0);
1.312 + break;
1.313 + }
1.314 + return 0; // Make sure no compiler moans about "not all paths return a value".
1.315 + }
1.316 +
1.317 +
1.318 +void CRawSurface::GetSurfAttribs(RSurfaceManager::TSurfaceCreationAttributesBuf &aSurfaceAttribs,
1.319 + TInt aIndex, TInt aSizeIndex)
1.320 + {
1.321 + SURF_ASSERT(aIndex < KSurfaceMaxIndex);
1.322 + SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
1.323 + iParamIndex = aIndex;
1.324 + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
1.325 + {
1.326 +
1.327 + aSurfaceAttribs().iSize =
1.328 + TSize(KSurfaceSizes[aSizeIndex].iWidth, KSurfaceSizes[aSizeIndex].iHeight);
1.329 + }
1.330 + else
1.331 + {
1.332 + aSurfaceAttribs().iSize =
1.333 + TSize(KSurfaceParams[aIndex].iXSize, KSurfaceParams[aIndex].iYSize);
1.334 + }
1.335 + iBuffers = KSurfaceParams[aIndex].iBuffers;
1.336 + aSurfaceAttribs().iBuffers = iBuffers;
1.337 + aSurfaceAttribs().iPixelFormat = KSurfaceParams[aIndex].iPixelFormat;
1.338 + TInt stride = KSurfaceParams[aIndex].iStrideInBytes;
1.339 + if (stride == 0)
1.340 + {
1.341 + stride = aSurfaceAttribs().iSize.iWidth * PixelSize(KSurfaceParams[aIndex].iPixelFormat);
1.342 + }
1.343 + aSurfaceAttribs().iStride = stride;
1.344 + aSurfaceAttribs().iOffsetToFirstBuffer = KSurfaceParams[aIndex].iOffsetToFirstBuffer;
1.345 + aSurfaceAttribs().iAlignment = KSurfaceParams[aIndex].iAlignment;
1.346 + aSurfaceAttribs().iContiguous = EFalse;
1.347 + aSurfaceAttribs().iCacheAttrib = RSurfaceManager::ECached;
1.348 + aSurfaceAttribs().iOffsetBetweenBuffers = 0;
1.349 + aSurfaceAttribs().iSurfaceHints = NULL;
1.350 + aSurfaceAttribs().iHintCount = 0;
1.351 + aSurfaceAttribs().iMappable = ETrue;
1.352 + }
1.353 +
1.354 +
1.355 +void CRawSurface::CreateL(TInt aIndex, const TPoint &/* aPoint */)
1.356 + {
1.357 + RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
1.358 + SURF_ASSERT(aIndex < KSurfaceMaxIndex);
1.359 + TInt sizeIndex = 0;
1.360 + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
1.361 + {
1.362 + sizeIndex = KMaxSurfaceSizes-1;
1.363 +
1.364 + }
1.365 + TInt err = KErrNone;
1.366 + do
1.367 + {
1.368 + GetSurfAttribs(surfaceAttribs, aIndex, sizeIndex);
1.369 + err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
1.370 + iActualSize = surfaceAttribs().iSize;
1.371 + sizeIndex--;
1.372 + }
1.373 + while(err != KErrNone && sizeIndex >= 0);
1.374 + User::LeaveIfError(err);
1.375 + }
1.376 +
1.377 +
1.378 +TUint8* CRawSurface::MapSurfaceAndGetInfoLC(RSurfaceManager::TSurfaceInfoV01& aInfo)
1.379 + {
1.380 + SURF_ASSERT(!iSurfaceId.IsNull());
1.381 + User::LeaveIfError(iSurfaceManager.MapSurface(iSurfaceId, iSurfaceChunk));
1.382 + CleanupClosePushL(iSurfaceChunk);
1.383 + RSurfaceManager::TInfoBuf infoBuf;
1.384 + User::LeaveIfError(iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf));
1.385 + aInfo = infoBuf();
1.386 + TInt offset = -1000; // So we hopefully detect when it goes horribly wrong.
1.387 + User::LeaveIfError(iSurfaceManager.GetBufferOffset(iSurfaceId, iDrawBuffer, offset));
1.388 + SURF_ASSERT(offset >= 0);
1.389 + return iSurfaceChunk.Base() + offset;
1.390 + }
1.391 +
1.392 +
1.393 +void CRawSurface::DrawContentL(TInt aImageIndex)
1.394 + {
1.395 + CTestCFbsImage *image = CTestCFbsImage::NewL(aImageIndex);
1.396 + CleanupStack::PushL(image);
1.397 +
1.398 + RSurfaceManager::TSurfaceInfoV01 info;
1.399 + TUint8 *dataAddress = MapSurfaceAndGetInfoLC(info);
1.400 + TInt stride = info.iStride;
1.401 +
1.402 + CFbsBitmap *bitmap = image->Bitmap();
1.403 + TDisplayMode displaymode = bitmap->DisplayMode();
1.404 + TInt pixelStride = stride / CFbsBitmap::ScanLineLength(1, displaymode);
1.405 + for(TInt y = 0; y < image->Size().iHeight; y++)
1.406 + {
1.407 + TPtr8 buf(dataAddress + y * stride, stride);
1.408 +
1.409 + // TODO: We need to check that the bitsperpixel matches between the surface and bitmap.
1.410 + bitmap->GetScanLine(buf, TPoint(0, y), pixelStride, displaymode);
1.411 + }
1.412 +
1.413 + CleanupStack::PopAndDestroy(2, image);
1.414 + }
1.415 +
1.416 +void CRawSurface::DrawContentL(const TRgb& aColour)
1.417 + {
1.418 + //Map the surface and get its info.
1.419 + RSurfaceManager::TSurfaceInfoV01 surfaceInfo;
1.420 + TUint32* buffer = (TUint32*)MapSurfaceAndGetInfoLC(surfaceInfo);
1.421 +
1.422 + //Currently this function only supports drawing into ARGB_8888_PRE surfaces.
1.423 + //This is because the only test that uses this function uses this type of surface.
1.424 + //If this functionallity needs expanding, you must correctly convert the TRgb colour
1.425 + //and pack it into the surface buffer correctly.
1.426 + SURF_ASSERT(surfaceInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE);
1.427 +
1.428 + TUint32 fillColour = aColour._Color16MAP();
1.429 +
1.430 + //Loop over each pixel in the surface and colour it.
1.431 + //This is deliberately slow since it is only used for the tearing test
1.432 + //and we want to spend most of our time drawing so that the chances of the other thread
1.433 + //picking up a buffer in the middle of drawing is increased.
1.434 + for(TInt y=0; y < surfaceInfo.iSize.iHeight; ++y)
1.435 + {
1.436 + for(TInt x=0; x < surfaceInfo.iSize.iWidth; ++x)
1.437 + {
1.438 + buffer[x] = fillColour;
1.439 + }
1.440 + buffer += surfaceInfo.iStride >> 2;
1.441 + }
1.442 +
1.443 + CleanupStack::PopAndDestroy();
1.444 + }
1.445 +
1.446 +
1.447 +void CRawSurface::DrawComplexL(const TRgb& aColour)
1.448 + {
1.449 + DrawContentL(aColour);
1.450 + }
1.451 +
1.452 +
1.453 +TInt CRawSurface::SubmitContent(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
1.454 + {
1.455 + TRequestStatus displayNotify = KRequestPending;
1.456 + TTimeStamp timeStamp;
1.457 +
1.458 + if(aShouldWaitForDisplay)
1.459 + {
1.460 + Notify(ENotifyWhenDisplayed, displayNotify, 0);
1.461 + }
1.462 +
1.463 + TInt err = iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceId, iDrawBuffer, NULL);
1.464 + if (err != KErrNone)
1.465 + {
1.466 + if (err != KErrNone)
1.467 + {
1.468 + RDebug::Printf("%s:%d: SubmitUpdate gave unexpected error %d", __FILE__, __LINE__, err);
1.469 + }
1.470 + return err;
1.471 + }
1.472 + iDrawBuffer = (iDrawBuffer + 1) % iBuffers;
1.473 +
1.474 + if(aShouldWaitForDisplay)
1.475 + {
1.476 + TUint32 dummy;
1.477 + err = WaitFor(ENotifyWhenDisplayed, displayNotify, 100 * 1000, dummy);
1.478 + if (err != KErrNone && err != KErrNotVisible && err != KErrOverflow)
1.479 + {
1.480 +// RDebug::Printf("%s:%d: NotifyWhenDisplayed gave unexpected error %d", __FILE__, __LINE__, err);
1.481 + return err;
1.482 + }
1.483 + }
1.484 + return KErrNone;
1.485 + }
1.486 +
1.487 +
1.488 +TSurfaceId CRawSurface::SurfaceId() const
1.489 + {
1.490 + return iSurfaceId;
1.491 + }
1.492 +
1.493 +
1.494 +void CRawSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
1.495 + {
1.496 + aParams.iCommonParams = KSurfaceParams[iParamIndex];
1.497 + aParams.iCommonParams.iBuffers = iBuffers; // May have been changed if it's a single buffered surface...
1.498 + aParams.iSurfaceId = SurfaceId();
1.499 + }
1.500 +
1.501 +const TText *CRawSurface::GetSurfaceTypeStr() const
1.502 + {
1.503 + return _S("CRawSurface");
1.504 + }
1.505 +
1.506 +TInt CRawSurface::Notify(TNotification aWhen, TRequestStatus& aStatus, TUint32 aXTimes)
1.507 + {
1.508 + aStatus = KRequestPending;
1.509 + switch(aWhen)
1.510 + {
1.511 + case ENotifyWhenAvailable:
1.512 + iSurfaceUpdate.NotifyWhenAvailable(aStatus);
1.513 + break;
1.514 + case ENotifyWhenDisplayed:
1.515 + iSurfaceUpdate.NotifyWhenDisplayed(aStatus, iTimeStamp);
1.516 + break;
1.517 + case ENotifyWhenDispXTimes:
1.518 + iSurfaceUpdate.NotifyWhenDisplayedXTimes(aXTimes, aStatus);
1.519 + break;
1.520 + default:
1.521 + RDebug::Printf("%s:%d: Invalid notification: %d. Panicking...", __FILE__, __LINE__, aWhen);
1.522 + User::Panic(_L("CRawSurface::Notify()"), __LINE__);
1.523 + break;
1.524 + }
1.525 + return KErrNone;
1.526 + }
1.527 +
1.528 +
1.529 +TInt CRawSurface::WaitFor(TNotification aWhen, TRequestStatus& aStatus, TInt aTimeoutInMicroSeconds, TUint32& aTimeStamp)
1.530 + {
1.531 + RTimer timer;
1.532 + TInt err = timer.CreateLocal();
1.533 + if (err != KErrNone)
1.534 + {
1.535 + RDebug::Printf("%s:%d: Could not create timer... err= %d", __FILE__, __LINE__, err);
1.536 + return err;
1.537 + }
1.538 + TRequestStatus timerStatus = KRequestPending;
1.539 +#if __WINS__
1.540 + // Windows timer isn't very precise - add some "fuzz" to the timeout to ensure we do not wait "too little".
1.541 + const TInt KTimeOutExtra = 20000;
1.542 +#else
1.543 + // On hardware, we should be able to run with less "fuzz".
1.544 + const TInt KTimeOutExtra = 10000;
1.545 +#endif
1.546 + timer.HighRes(timerStatus, aTimeoutInMicroSeconds + KTimeOutExtra);
1.547 + User::WaitForRequest(timerStatus, aStatus);
1.548 + if (aStatus == KRequestPending)
1.549 + {
1.550 + if (aWhen == ENotifyWhenDisplayed)
1.551 + {
1.552 + aTimeStamp = User::FastCounter();
1.553 + }
1.554 + return KErrTimedOut;
1.555 + }
1.556 + if (aWhen == ENotifyWhenDisplayed)
1.557 + {
1.558 + aTimeStamp = iTimeStamp();
1.559 + }
1.560 + timer.Cancel();
1.561 + timer.Close();
1.562 + TInt result = aStatus.Int();
1.563 + aStatus = KRequestPending;
1.564 + return result;
1.565 + }
1.566 +
1.567 +const TText *CRawSingleBufferSurface::GetSurfaceTypeStr() const
1.568 + {
1.569 + return _S("CRawSingleBufferedSurface");
1.570 + }
1.571 +
1.572 +CRawSingleBufferSurface *CRawSingleBufferSurface::NewL()
1.573 + {
1.574 + CRawSingleBufferSurface* obj = new (ELeave) CRawSingleBufferSurface();
1.575 + CleanupStack::PushL(obj);
1.576 + obj->ConstructL();
1.577 + CleanupStack::Pop(obj);
1.578 + return obj;
1.579 + }
1.580 +
1.581 +
1.582 +void CRawSingleBufferSurface::CreateL(TInt aIndex, const TPoint & /*aPoint */)
1.583 + {
1.584 + RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
1.585 +
1.586 + TInt sizeIndex = 0;
1.587 + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
1.588 + {
1.589 + sizeIndex = KMaxSurfaceSizes-1;
1.590 + }
1.591 + TInt err = KErrNone;
1.592 + do
1.593 + {
1.594 + GetSurfAttribs(surfaceAttribs, aIndex, sizeIndex);
1.595 + iBuffers = 1;
1.596 + surfaceAttribs().iBuffers = 1;
1.597 + err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
1.598 + iActualSize = surfaceAttribs().iSize;
1.599 + sizeIndex--;
1.600 + }
1.601 + while(err != KErrNone && sizeIndex >= 0);
1.602 + }
1.603 +
1.604 +CRawSingleBufferSurface::~CRawSingleBufferSurface()
1.605 + {
1.606 + }
1.607 +
1.608 +
1.609 +TInt CEglSurfaceBase::Activate()
1.610 + {
1.611 + if (!eglMakeCurrent(iDisplay, iSurface, iSurface, iContext))
1.612 + {
1.613 + EGLint err = eglGetError();
1.614 + RDebug::Printf("%s:%d: eglMakeCurrent gave error 0x%x", __FILE__, __LINE__, err);
1.615 + return KErrBadHandle;
1.616 + }
1.617 + return KErrNone;
1.618 + }
1.619 +
1.620 +void CEglSurfaceBase::ActivateL()
1.621 + {
1.622 + User::LeaveIfError(Activate());
1.623 + }
1.624 +
1.625 +void CEglSurfaceBase::DrawComplexL(const TRgb& aColour)
1.626 + {
1.627 + ActivateL();
1.628 +
1.629 + TSize size;
1.630 + eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth);
1.631 + eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight);
1.632 +
1.633 + //Paint lots of random circles to keep the GPU busy.
1.634 + for(TInt i=0; i < 300; i++)
1.635 + {
1.636 + VGPaint paint = vgCreatePaint();
1.637 + VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_APPEND_TO);
1.638 +
1.639 + TInt minDim = Min(size.iWidth, size.iHeight);
1.640 + VGfloat cx = RandomNumberInRange(0, size.iWidth);
1.641 + VGfloat cy = RandomNumberInRange(0, size.iHeight);
1.642 + VGfloat diameter = RandomNumberInRange(minDim / 20, minDim / 3);
1.643 + TRgb fillColour(RandomNumberInRange(0, 255), RandomNumberInRange(0, 255), RandomNumberInRange(0, 255), RandomNumberInRange(0, 255));
1.644 +
1.645 + vguEllipse(path, cx, cy, diameter, diameter);
1.646 + vgSetPaint(paint, VG_FILL_PATH);
1.647 + vgSetColor(paint, fillColour.Value());
1.648 + vgDrawPath(path, VG_FILL_PATH);
1.649 +
1.650 + vgDestroyPath(path);
1.651 + vgDestroyPaint(paint);
1.652 + }
1.653 +
1.654 + //Paint the top corner with aColour so we can identify the drawing.
1.655 + VGfloat fillColour[4];
1.656 + fillColour[0] = (VGfloat)aColour.Red() / 255.0f;
1.657 + fillColour[1] = (VGfloat)aColour.Green() / 255.0f;
1.658 + fillColour[2] = (VGfloat)aColour.Blue() / 255.0f;
1.659 + fillColour[3] = (VGfloat)aColour.Alpha() / 255.0f;
1.660 +
1.661 + vgSetfv(VG_CLEAR_COLOR, 4, fillColour);
1.662 + vgClear(0, 0, 20, size.iHeight);
1.663 + }
1.664 +
1.665 +void CEglSurfaceBase::DrawContentL(const TRgb& aColour)
1.666 + {
1.667 + ActivateL();
1.668 +
1.669 + TSize size;
1.670 + eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth);
1.671 + eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight);
1.672 +
1.673 + VGfloat fillColour[4];
1.674 + fillColour[0] = (VGfloat)aColour.Red() / 255.0f;
1.675 + fillColour[1] = (VGfloat)aColour.Green() / 255.0f;
1.676 + fillColour[2] = (VGfloat)aColour.Blue() / 255.0f;
1.677 + fillColour[3] = (VGfloat)aColour.Alpha() / 255.0f;
1.678 +
1.679 + vgSetfv(VG_CLEAR_COLOR, 4, fillColour);
1.680 + vgClear(0, 0, size.iWidth, size.iHeight);
1.681 + }
1.682 +
1.683 +void CEglSurfaceBase::CreateL(TInt aIndex, const TPoint &aOffset)
1.684 + {
1.685 + SURF_ASSERT(aIndex < KSurfaceMaxIndex);
1.686 + SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
1.687 +
1.688 + TInt sizeIndex = 0;
1.689 + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
1.690 + {
1.691 + sizeIndex = KMaxSurfaceSizes-1;
1.692 + }
1.693 + TInt err = KErrNone;
1.694 + do
1.695 + {
1.696 + TRAP(err, DoCreateL(aIndex, aOffset, sizeIndex));
1.697 + sizeIndex--;
1.698 + }
1.699 + while(err != KErrNone && sizeIndex >= 0);
1.700 + if (err != KErrNone)
1.701 + {
1.702 +// RDebug::Printf("%s:%d: err=%d (%d x %d)", __FILE__, __LINE__, err, iActualSize.iWidth, iActualSize.iHeight);
1.703 + User::Leave(err);
1.704 + }
1.705 + }
1.706 +
1.707 +TInt CEglSurfaceBase::SubmitContent(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
1.708 + {
1.709 + TInt err = Activate();
1.710 + if (err != KErrNone)
1.711 + {
1.712 + return err;
1.713 + }
1.714 + if (!eglSwapBuffers(iDisplay, iSurface))
1.715 + {
1.716 + EGLint err = eglGetError();
1.717 + RDebug::Printf("%s:%d: eglSwapBuffers gave error 0x%x", __FILE__, __LINE__, err);
1.718 + return KErrBadHandle;
1.719 + }
1.720 + if (aShouldWaitForDisplay)
1.721 + {
1.722 + // We are cheating: We just wait for a bit to ensure that the swapbuffer is actually finished.
1.723 + // There is no way to determine how long this takes, so we just grab a number that should be
1.724 + // large enough...
1.725 + User::After(100 * 1000); // Wait 100ms.
1.726 + }
1.727 + return KErrNone;
1.728 + }
1.729 +
1.730 +void CEglSurfaceBase::DrawContentL(TInt aIndex)
1.731 + {
1.732 + ActivateL();
1.733 + CTestVgImage *vgImage = CTestVgImage::NewL(aIndex);
1.734 + CleanupStack::PushL(vgImage);
1.735 + vgDrawImage(vgImage->VGImage());
1.736 + CleanupStack::PopAndDestroy(vgImage);
1.737 + }
1.738 +
1.739 +void CEglSurfaceBase::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
1.740 + {
1.741 + RSurfaceManager surfaceManager;
1.742 + User::LeaveIfError(surfaceManager.Open());
1.743 + RSurfaceManager::TInfoBuf infoBuf;
1.744 + TInt err = surfaceManager.SurfaceInfo(SurfaceId(), infoBuf);
1.745 + User::LeaveIfError(err);
1.746 + surfaceManager.Close();
1.747 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.748 + aParams.iSurfaceId = SurfaceId();
1.749 + aParams.iCommonParams.iAlignment = -1; // N/A
1.750 + aParams.iCommonParams.iBuffers = info.iBuffers;
1.751 + aParams.iCommonParams.iOffsetToFirstBuffer = -1;
1.752 + aParams.iCommonParams.iPixelFormat = info.iPixelFormat;
1.753 + aParams.iCommonParams.iStrideInBytes = info.iStride;
1.754 + aParams.iCommonParams.iXSize = info.iSize.iWidth;
1.755 + aParams.iCommonParams.iYSize = info.iSize.iHeight;
1.756 + aParams.iCommonParams.iUseAttribList = KSurfaceParams[iParamIndex].iUseAttribList;
1.757 + for(TInt i = 0; i < KNumAttribs; i++)
1.758 + {
1.759 + aParams.iCommonParams.iAttribs[i] = KSurfaceParams[iParamIndex].iAttribs[i];
1.760 + }
1.761 + }
1.762 +
1.763 +
1.764 +TInt CEglSurfaceBase::Notify(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, TUint32 /*aXTImes*/)
1.765 + {
1.766 + return KErrNotSupported;
1.767 + }
1.768 +
1.769 +TInt CEglSurfaceBase::WaitFor(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/,
1.770 + TInt /*aTimeoutinMicroseconds*/, TUint32 & /*aTimeStamp*/)
1.771 + {
1.772 + return KErrNotSupported;
1.773 + }
1.774 +
1.775 +void CEglSurfaceBase::BaseCreateL(TInt aIndex, EGLint aSurfaceType)
1.776 + {
1.777 + iParamIndex = aIndex;
1.778 + iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1.779 +
1.780 + EGLint err;
1.781 + if (iDisplay == EGL_NO_DISPLAY)
1.782 + {
1.783 + err = eglGetError();
1.784 + RDebug::Printf("%s:%d: err = 0x%x", __FILE__, __LINE__, err);
1.785 + User::Leave(KErrNotSupported);
1.786 + }
1.787 +
1.788 + EGLint nConfigs = 0;
1.789 +
1.790 + // TODO: Need to use differnet config attribs based on aIndex.
1.791 + EGLint configAttribs[] =
1.792 + {
1.793 + EGL_BUFFER_SIZE, 32,
1.794 + EGL_RED_SIZE, 8,
1.795 + EGL_GREEN_SIZE, 8,
1.796 + EGL_BLUE_SIZE, 8,
1.797 + EGL_ALPHA_SIZE, 8,
1.798 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1.799 + EGL_RENDERABLE_TYPE,EGL_OPENVG_BIT,
1.800 + EGL_NONE
1.801 + };
1.802 +
1.803 + // Update surfacetype type to match
1.804 + for(TInt i = 0; configAttribs[i] != EGL_NONE; i += 2)
1.805 + {
1.806 + if (configAttribs[i] == EGL_SURFACE_TYPE)
1.807 + {
1.808 + configAttribs[i+1] = aSurfaceType;
1.809 + }
1.810 + }
1.811 + // Need some way to configure the attribs ...
1.812 + eglChooseConfig(iDisplay, configAttribs, &iConfig, 1, &nConfigs);
1.813 + if (!nConfigs)
1.814 + {
1.815 + err = eglGetError();
1.816 + RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
1.817 + User::Leave(KErrNotSupported);
1.818 + }
1.819 +
1.820 + if (!eglBindAPI(EGL_OPENVG_API))
1.821 + {
1.822 + err = eglGetError();
1.823 + RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
1.824 + User::Leave(KErrNotSupported);
1.825 + }
1.826 + iContext = eglCreateContext(iDisplay, iConfig, 0, NULL);
1.827 + if (iContext == EGL_NO_CONTEXT)
1.828 + {
1.829 + err = eglGetError();
1.830 + //RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
1.831 + User::Leave(KErrNotSupported);
1.832 + }
1.833 + }
1.834 +
1.835 +void CEglSurfaceBase::Destroy()
1.836 + {
1.837 + eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1.838 + if (iSurface != EGL_NO_SURFACE)
1.839 + {
1.840 + eglDestroySurface(iDisplay, iSurface);
1.841 + iSurface = EGL_NO_SURFACE;
1.842 + }
1.843 +
1.844 + if (iDisplay != EGL_NO_DISPLAY)
1.845 + {
1.846 + eglDestroyContext(iDisplay, iContext);
1.847 + }
1.848 + }
1.849 +
1.850 +
1.851 +class CWindow: public CBase
1.852 + {
1.853 +public:
1.854 + static CWindow *NewL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex);
1.855 + RWindow& Window();
1.856 + ~CWindow();
1.857 +private:
1.858 + void ConstructL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex);
1.859 + CWindow();
1.860 +
1.861 +private:
1.862 + RWindow iWindow;
1.863 + RWindowGroup iWindowGroup;
1.864 + RWsSession iWsSession;
1.865 + };
1.866 +
1.867 +
1.868 +CWindow* CWindow::NewL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex)
1.869 + {
1.870 + CWindow *self = new (ELeave) CWindow;
1.871 + CleanupStack::PushL(self);
1.872 + self->ConstructL(aIndex, aOffset, aSizeIndex);
1.873 + CleanupStack::Pop(self);
1.874 + return self;
1.875 + }
1.876 +
1.877 +
1.878 +void CWindow::ConstructL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex)
1.879 + {
1.880 + RFbsSession::Connect();
1.881 + if (aIndex >= KSurfaceMaxIndex)
1.882 + {
1.883 + User::Leave(KErrOverflow);
1.884 + }
1.885 + User::LeaveIfError(iWsSession.Connect());
1.886 + iWindowGroup = RWindowGroup(iWsSession);
1.887 + User::LeaveIfError(iWindowGroup.Construct((TUint32)this));
1.888 + iWindow = RWindow(iWsSession);
1.889 + User::LeaveIfError(iWindow.Construct(iWindowGroup, -1U));
1.890 + TSurfaceParamsCommon winAttrib = KSurfaceParams[aIndex];
1.891 + TSize winSize;
1.892 + if (winAttrib.iXSize & LARGEST_POSSIBLE_FLAG)
1.893 + {
1.894 + winSize = TSize(KSurfaceSizes[aSizeIndex].iWidth, KSurfaceSizes[aSizeIndex].iHeight);
1.895 + }
1.896 + else
1.897 + {
1.898 + winSize = TSize(winAttrib.iXSize, winAttrib.iYSize);
1.899 + }
1.900 + iWindow.SetExtent(TPoint(winAttrib.iXPos + aOffset.iX, winAttrib.iYPos + aOffset.iY), winSize);
1.901 + iWindow.SetRequiredDisplayMode(winAttrib.iDisplayMode);
1.902 + iWindow.Activate();
1.903 + }
1.904 +
1.905 +
1.906 +CWindow::~CWindow()
1.907 + {
1.908 + iWindow.Close();
1.909 + iWindowGroup.Close();
1.910 + iWsSession.Close();
1.911 + RFbsSession::Disconnect();
1.912 + }
1.913 +
1.914 +
1.915 +CWindow::CWindow()
1.916 + {
1.917 + }
1.918 +
1.919 +
1.920 +RWindow& CWindow::Window()
1.921 + {
1.922 + return iWindow;
1.923 + }
1.924 +
1.925 +
1.926 +CEglWindowSurface* CEglWindowSurface::NewL()
1.927 + {
1.928 + CEglWindowSurface* self = new (ELeave) CEglWindowSurface;
1.929 + CleanupStack::PushL(self);
1.930 + self->ConstructL();
1.931 + CleanupStack::Pop(self);
1.932 + return self;
1.933 + }
1.934 +
1.935 +
1.936 +void CEglWindowSurface::ConstructL()
1.937 + {
1.938 + }
1.939 +
1.940 +
1.941 +CEglWindowSurface::CEglWindowSurface()
1.942 + {
1.943 + }
1.944 +
1.945 +
1.946 +void CEglWindowSurface::DoCreateL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex)
1.947 + {
1.948 + iParamIndex = aIndex;
1.949 + iWindow = CWindow::NewL(aIndex, aOffset, aSizeIndex);
1.950 + iActualSize = iWindow->Window().Size();
1.951 +
1.952 + CEglSurfaceBase::BaseCreateL(aIndex, EGL_WINDOW_BIT);
1.953 +
1.954 + iSurface = eglCreateWindowSurface(iDisplay, iConfig, &iWindow->Window(), NULL);
1.955 + if (iSurface == EGL_NO_SURFACE)
1.956 + {
1.957 + EGLint err = eglGetError();
1.958 + RDebug::Printf("%s:%d: err = %x (%d x %d)", __FILE__, __LINE__, err, iActualSize.iWidth, iActualSize.iHeight);
1.959 + User::Leave(KErrNotSupported);
1.960 + }
1.961 + }
1.962 +
1.963 +
1.964 +CEglWindowSurface::~CEglWindowSurface()
1.965 + {
1.966 + Destroy();
1.967 + eglReleaseThread();
1.968 + delete iWindow;
1.969 + }
1.970 +
1.971 +
1.972 +TSurfaceId CEglWindowSurface::SurfaceId() const
1.973 + {
1.974 + // Default constructor for id sets it to a NULL-value, so if no window is created, we get
1.975 + // a defined surface id value that is invalid.
1.976 + TSurfaceId id;
1.977 + if (iWindow)
1.978 + {
1.979 + TSurfaceConfiguration surfConfig;
1.980 + iWindow->Window().GetBackgroundSurface(surfConfig);
1.981 + surfConfig.GetSurfaceId(id);
1.982 + }
1.983 + return id;
1.984 + }
1.985 +
1.986 +
1.987 +const TText *CEglWindowSurface::GetSurfaceTypeStr() const
1.988 + {
1.989 + return _S("CEglWindowSurface");
1.990 + }
1.991 +
1.992 +
1.993 +CEglPBufferSurface::CEglPBufferSurface()
1.994 + {
1.995 + }
1.996 +
1.997 +
1.998 +CEglPBufferSurface::~CEglPBufferSurface()
1.999 + {
1.1000 + Destroy();
1.1001 + eglReleaseThread();
1.1002 + }
1.1003 +
1.1004 +
1.1005 +CEglPBufferSurface* CEglPBufferSurface::NewL()
1.1006 + {
1.1007 + CEglPBufferSurface* self = new (ELeave) CEglPBufferSurface;
1.1008 + CleanupStack::PushL(self);
1.1009 + self->ConstructL();
1.1010 + CleanupStack::Pop(self);
1.1011 + return self;
1.1012 + }
1.1013 +
1.1014 +
1.1015 +void CEglPBufferSurface::ConstructL()
1.1016 + {
1.1017 + }
1.1018 +
1.1019 +
1.1020 +const TText *CEglPBufferSurface::GetSurfaceTypeStr() const
1.1021 + {
1.1022 + return _S("CEglPBufferSurface");
1.1023 + }
1.1024 +
1.1025 +
1.1026 +void CEglPBufferSurface::DoCreateL(TInt aIndex, const TPoint &/*aOffset*/, TInt aSizeIndex)
1.1027 + {
1.1028 + CEglSurfaceBase::BaseCreateL(aIndex, EGL_PBUFFER_BIT);
1.1029 +
1.1030 + EGLint attribs[] =
1.1031 + {
1.1032 + EGL_WIDTH, 0,
1.1033 + EGL_HEIGHT, 0,
1.1034 + EGL_NONE,
1.1035 + };
1.1036 + if (KSurfaceParams[aIndex].iXSize & ELargestPossibleSurface)
1.1037 + {
1.1038 + iActualSize.iWidth = KSurfaceSizes[aSizeIndex].iWidth;
1.1039 + iActualSize.iHeight = KSurfaceSizes[aSizeIndex].iHeight;
1.1040 + }
1.1041 + else
1.1042 + {
1.1043 + iActualSize.iWidth = KSurfaceParams[aIndex].iXSize;
1.1044 + iActualSize.iHeight = KSurfaceParams[aIndex].iYSize;
1.1045 + }
1.1046 + for(TInt i = 0; attribs[i] != EGL_NONE; i += 2)
1.1047 + {
1.1048 + switch(attribs[i])
1.1049 + {
1.1050 + case EGL_HEIGHT:
1.1051 + attribs[i+1] = iActualSize.iHeight;
1.1052 + break;
1.1053 + case EGL_WIDTH:
1.1054 + attribs[i+1] = iActualSize.iWidth;
1.1055 + break;
1.1056 + }
1.1057 + }
1.1058 +
1.1059 + iSurface = eglCreatePbufferSurface(iDisplay, iConfig, attribs);
1.1060 + if (iSurface == EGL_NO_SURFACE)
1.1061 + {
1.1062 + EGLint err = eglGetError();
1.1063 + User::Leave(KErrNotSupported);
1.1064 + }
1.1065 + }
1.1066 +
1.1067 +
1.1068 +TSurfaceId CEglPBufferSurface::SurfaceId() const
1.1069 + {
1.1070 + SURF_ASSERT(0); // We shouldn't call this!
1.1071 + return TSurfaceId::CreateNullId();
1.1072 + }
1.1073 +
1.1074 +TInt CEglPBufferSurface::SizeInBytes() const
1.1075 + {
1.1076 + // size of a pixel in bits.
1.1077 + EGLint size;
1.1078 + if (!eglGetConfigAttrib(iDisplay, iConfig, EGL_BUFFER_SIZE, &size))
1.1079 + {
1.1080 + RDebug::Printf("Unable to get EGL_BUFFER_SIZE from config %d, err = %04x", iConfig, eglGetError());
1.1081 + return 0;
1.1082 + }
1.1083 +
1.1084 + return (KSurfaceParams[iParamIndex].iXSize * KSurfaceParams[iParamIndex].iYSize * size) / 8;
1.1085 + }
1.1086 +
1.1087 +
1.1088 +// Factory function.
1.1089 +CSurface *CSurface::SurfaceFactoryL(TSurfaceType aSurfaceType)
1.1090 + {
1.1091 + switch(aSurfaceType)
1.1092 + {
1.1093 + case ESurfTypeRaw:
1.1094 + return CRawSurface::NewL();
1.1095 +
1.1096 + case ESurfTypeEglWindow:
1.1097 + return CEglWindowSurface::NewL();
1.1098 +
1.1099 + case ESurfTypeRawSingleBuffered:
1.1100 + return CRawSingleBufferSurface::NewL();
1.1101 +
1.1102 + case ESurfTypePBuffer:
1.1103 + return CEglPBufferSurface::NewL();
1.1104 +
1.1105 + default:
1.1106 + SURF_ASSERT(0);
1.1107 + return NULL;
1.1108 + }
1.1109 + }