egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp
branchRCL_3
changeset 163 bbf46f59e123
equal deleted inserted replaced
150:57c618273d5c 163:bbf46f59e123
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @test
       
    19  @internalComponent - Internal Symbian test code
       
    20 */
       
    21 
       
    22 
       
    23 #include "egltest_surface.h"
       
    24 #include "egltest_endpoint_images.h"
       
    25 #include <graphics/surfaceconfiguration.h>
       
    26 #include <e32std.h>
       
    27 #include <e32math.h>
       
    28 #include <VG/vgu.h>
       
    29 
       
    30 
       
    31 #define SURF_ASSERT(x) { if (!(x)) { RDebug::Printf("ASSERT(%s) failed at %s:%d", #x, __FILE__, __LINE__); User::Panic(_L("ASSERT SURF"), __LINE__); }}
       
    32 
       
    33 // Macros for indicating what is what.
       
    34 #define SIZE(x, y) x, y
       
    35 #define Buffers(x) x
       
    36 #define DefaultAlignment 32  // Pick some value that is valid.
       
    37 #define Alignment(x) x
       
    38 #define Stride(x) x
       
    39 #define DefaultStride 0
       
    40 // Note: Offset to first buffer.
       
    41 #define Offset(x) x
       
    42 #define WindowPos(x, y)  x, y
       
    43 #define WindowMode(m) m
       
    44 
       
    45 #define LARGEST_POSSIBLE_FLAG 0x80000000
       
    46 
       
    47 static const TSurfaceParamsCommon KSurfaceParams[] =
       
    48 {
       
    49     {
       
    50         EStandardSurface,
       
    51         SIZE(100, 100),
       
    52         Buffers(2),
       
    53         DefaultAlignment,
       
    54         DefaultStride,
       
    55         Offset(0),
       
    56         EUidPixelFormatARGB_8888_PRE,
       
    57         EFalse,
       
    58         { 0 },
       
    59         WindowPos(0, 0),
       
    60         WindowMode(EColor16MAP)
       
    61     },
       
    62     {
       
    63         EBadAttribSurface,
       
    64         SIZE(100, 100),
       
    65         Buffers(2),
       
    66         DefaultAlignment,
       
    67         DefaultStride,
       
    68         Offset(0),
       
    69         EUidPixelFormatARGB_8888_PRE,
       
    70         ETrue,
       
    71         { 1, 1, EGL_NONE },
       
    72         WindowPos(0, 0),
       
    73         WindowMode(EColor16MAP)
       
    74     },
       
    75     {
       
    76         EEmptyAttribSurface,
       
    77         SIZE(100, 100),
       
    78         Buffers(2),
       
    79         DefaultAlignment,
       
    80         DefaultStride,
       
    81         Offset(0),
       
    82         EUidPixelFormatARGB_8888_PRE,
       
    83         ETrue,
       
    84         { EGL_NONE },
       
    85         WindowPos(0, 0),
       
    86         WindowMode(EColor16MAP)
       
    87     },
       
    88     {
       
    89         EStandard128sqSurface,
       
    90         SIZE(128, 128),
       
    91         Buffers(3),
       
    92         DefaultAlignment,
       
    93         DefaultStride,
       
    94         Offset(0),
       
    95         EUidPixelFormatARGB_8888_PRE,
       
    96         EFalse,
       
    97         { 0 },
       
    98         WindowPos(20, 20),
       
    99         WindowMode(EColor16MAP)
       
   100     },
       
   101     {
       
   102         EUnusualStrideSurface,
       
   103         SIZE(167,263),
       
   104         Buffers(2),
       
   105         Alignment(8),
       
   106         Stride(167*4+64),
       
   107         Offset(200),
       
   108         EUidPixelFormatARGB_8888_PRE,
       
   109         EFalse,
       
   110         { 0 },
       
   111         WindowPos(0, 0),
       
   112         WindowMode(EColor16MAP)
       
   113     },
       
   114     {
       
   115         EUnalignedPixelSizeSurface,
       
   116         SIZE(103, 107),
       
   117         Buffers(2),
       
   118         Alignment(8),
       
   119         Stride(103*4),
       
   120         Offset(0),
       
   121         EUidPixelFormatARGB_8888_PRE,
       
   122         EFalse,
       
   123         { 0 },
       
   124         WindowPos(0, 0),
       
   125         WindowMode(EColor16MAP)
       
   126     },
       
   127     {
       
   128         ELargeSurface,
       
   129         SIZE(800, 600),
       
   130         Buffers(2),
       
   131         DefaultAlignment,
       
   132         DefaultStride,
       
   133         Offset(0),
       
   134         EUidPixelFormatARGB_8888_PRE,
       
   135         EFalse,
       
   136         { 0 },
       
   137         WindowPos(0, 0),
       
   138         WindowMode(EColor16MAP)
       
   139     },
       
   140     {
       
   141         ELargestPossibleSurface,
       
   142         SIZE(LARGEST_POSSIBLE_FLAG, LARGEST_POSSIBLE_FLAG),
       
   143         Buffers(2),
       
   144         DefaultAlignment,
       
   145         DefaultStride,
       
   146         Offset(0),
       
   147         EUidPixelFormatARGB_8888_PRE,
       
   148         EFalse,
       
   149         { 0 },
       
   150         WindowPos(0, 0),
       
   151         WindowMode(EColor16MAP)
       
   152     },    
       
   153     {
       
   154         ESmallSurface,
       
   155         SIZE(16, 16),
       
   156         Buffers(1),
       
   157         DefaultAlignment,
       
   158         DefaultStride,
       
   159         Offset(0),
       
   160         EUidPixelFormatARGB_8888_PRE,
       
   161         EFalse,
       
   162         { 0 },
       
   163         WindowPos(0, 0),
       
   164         WindowMode(EColor16MAP)
       
   165     },
       
   166     {
       
   167         ETinySurface,
       
   168         SIZE(8, 8),
       
   169         Buffers(1),
       
   170         DefaultAlignment,
       
   171         DefaultStride,
       
   172         Offset(0),
       
   173         EUidPixelFormatARGB_8888_PRE,
       
   174         EFalse,
       
   175         { 0 },
       
   176         WindowPos(0, 0),
       
   177         WindowMode(EColor16MAP)
       
   178     },
       
   179 };
       
   180 
       
   181 const TInt KSurfaceMaxIndex = sizeof(KSurfaceParams) / sizeof(KSurfaceParams[0]);
       
   182 
       
   183 struct TSurfaceSize
       
   184     {
       
   185     TInt iWidth;
       
   186     TInt iHeight;
       
   187     };
       
   188 
       
   189 static const TSurfaceSize KSurfaceSizes[] =
       
   190     {
       
   191         {  320,  240 },
       
   192         {  640,  480 },
       
   193         {  720,  480 },
       
   194         {  854,  480 },
       
   195         {  720,  576 },
       
   196         {  854,  576 },
       
   197         { 1280,  720 },
       
   198         { 1024,  768 },
       
   199         { 1280, 1024 },
       
   200         { 1920, 1080 },
       
   201         { 1600, 1200 },
       
   202 #if 0
       
   203         { 2048, 1536 },
       
   204         { 2560, 1920 },
       
   205         { 3648, 2736 },
       
   206         { 4216, 2638 },
       
   207         { 4000, 3000 },
       
   208         { 4616, 2600 },
       
   209 #endif
       
   210     };
       
   211 
       
   212 const TInt KMaxSurfaceSizes =  sizeof(KSurfaceSizes) / sizeof(KSurfaceSizes[0]);
       
   213 
       
   214 LOCAL_C TUint RandomNumberInRange(TUint aLow, TUint aHigh)
       
   215     {
       
   216     TReal32 rand = Math::Random();
       
   217     rand /= KMaxTUint;
       
   218     rand *= aHigh - aLow;
       
   219     rand += aLow;
       
   220     return TUint(rand);
       
   221     }
       
   222 
       
   223 
       
   224 void CSurface::CreateL(TInt aIndex)
       
   225     {
       
   226     CreateL(aIndex, TPoint(0, 0));
       
   227     }
       
   228 
       
   229 
       
   230 TSize CSurface::Size()
       
   231     {
       
   232     return iActualSize;
       
   233     }
       
   234 
       
   235 
       
   236 TInt CSurface::SizeInBytes() const
       
   237     {
       
   238     RSurfaceManager::TInfoBuf infoBuf;
       
   239     RSurfaceManager surfMgr;
       
   240     TInt err = surfMgr.Open();
       
   241     if (err != KErrNone)
       
   242         {
       
   243         RDebug::Printf("Error opening surface manager... Err=%d", err);
       
   244         return 0;
       
   245         }
       
   246     err = surfMgr.SurfaceInfo(SurfaceId(), infoBuf);
       
   247     if (err != KErrNone)
       
   248         {
       
   249         RDebug::Printf("Could not get surface info - err = %d", err);
       
   250         return 0;
       
   251         }
       
   252     TInt size = infoBuf().iBuffers * infoBuf().iSize.iHeight * infoBuf().iStride;
       
   253     surfMgr.Close();
       
   254     return size;
       
   255     }
       
   256 
       
   257 
       
   258 CRawSurface* CRawSurface::NewL()
       
   259     {
       
   260     CRawSurface* obj = new (ELeave) CRawSurface();
       
   261     CleanupStack::PushL(obj);
       
   262     obj->ConstructL();
       
   263     CleanupStack::Pop(obj);
       
   264     return obj;
       
   265     }
       
   266 
       
   267 
       
   268 
       
   269 CRawSurface::CRawSurface() : iDrawBuffer(0), iBuffers(0)
       
   270     {
       
   271     }
       
   272 
       
   273 
       
   274 void CRawSurface::ConstructL()
       
   275     {
       
   276     iSurfaceId = TSurfaceId::CreateNullId();
       
   277     User::LeaveIfError(iSurfaceManager.Open());
       
   278     User::LeaveIfError(iSurfaceUpdate.Connect());
       
   279     }
       
   280 
       
   281 
       
   282 CRawSurface::~CRawSurface()
       
   283     {
       
   284     iSurfaceUpdate.Close();
       
   285     if(!iSurfaceId.IsNull())
       
   286         {
       
   287         iSurfaceManager.CloseSurface(iSurfaceId);
       
   288         }
       
   289     iSurfaceManager.Close();
       
   290     }
       
   291 
       
   292 
       
   293 TInt CRawSurface::PixelSize(TUidPixelFormat aPixelFormat)
       
   294     {
       
   295     switch(aPixelFormat)
       
   296         {
       
   297         case EUidPixelFormatARGB_8888_PRE:
       
   298         case EUidPixelFormatARGB_8888:
       
   299         case EUidPixelFormatABGR_8888:
       
   300         case EUidPixelFormatABGR_8888_PRE:
       
   301             return 4;
       
   302 
       
   303         case EUidPixelFormatARGB_4444:
       
   304         case EUidPixelFormatRGB_565:
       
   305             return 2;
       
   306 
       
   307         default:
       
   308             SURF_ASSERT(0);
       
   309             break;
       
   310         }
       
   311     return 0; // Make sure no compiler moans about "not all paths return a value".
       
   312     }
       
   313 
       
   314 
       
   315 void CRawSurface::GetSurfAttribs(RSurfaceManager::TSurfaceCreationAttributesBuf &aSurfaceAttribs, 
       
   316         TInt aIndex, TInt aSizeIndex)
       
   317     {
       
   318     SURF_ASSERT(aIndex < KSurfaceMaxIndex);
       
   319     SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
       
   320     iParamIndex = aIndex;
       
   321     if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
       
   322         {
       
   323         
       
   324         aSurfaceAttribs().iSize = 
       
   325                 TSize(KSurfaceSizes[aSizeIndex].iWidth, KSurfaceSizes[aSizeIndex].iHeight);
       
   326         }
       
   327     else
       
   328         {
       
   329         aSurfaceAttribs().iSize = 
       
   330                 TSize(KSurfaceParams[aIndex].iXSize, KSurfaceParams[aIndex].iYSize);
       
   331         }
       
   332     iBuffers = KSurfaceParams[aIndex].iBuffers;
       
   333     aSurfaceAttribs().iBuffers = iBuffers;
       
   334     aSurfaceAttribs().iPixelFormat = KSurfaceParams[aIndex].iPixelFormat;
       
   335     TInt stride = KSurfaceParams[aIndex].iStrideInBytes;
       
   336     if (stride == 0)
       
   337         {
       
   338         stride = aSurfaceAttribs().iSize.iWidth * PixelSize(KSurfaceParams[aIndex].iPixelFormat);
       
   339         }
       
   340     aSurfaceAttribs().iStride = stride;
       
   341     aSurfaceAttribs().iOffsetToFirstBuffer = KSurfaceParams[aIndex].iOffsetToFirstBuffer;
       
   342     aSurfaceAttribs().iAlignment = KSurfaceParams[aIndex].iAlignment;
       
   343     aSurfaceAttribs().iContiguous = EFalse;
       
   344     aSurfaceAttribs().iCacheAttrib = RSurfaceManager::ECached;
       
   345     aSurfaceAttribs().iOffsetBetweenBuffers = 0;
       
   346     aSurfaceAttribs().iSurfaceHints = NULL;
       
   347     aSurfaceAttribs().iHintCount = 0;
       
   348     aSurfaceAttribs().iMappable = ETrue;
       
   349     }
       
   350 
       
   351 
       
   352 void CRawSurface::CreateL(TInt aIndex, const TPoint &/* aPoint */)
       
   353     {
       
   354     RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
       
   355     SURF_ASSERT(aIndex < KSurfaceMaxIndex);
       
   356     TInt sizeIndex = 0;
       
   357     if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
       
   358         {
       
   359         sizeIndex = KMaxSurfaceSizes-1;
       
   360         
       
   361         }
       
   362     TInt err = KErrNone;
       
   363     do
       
   364         {
       
   365         GetSurfAttribs(surfaceAttribs, aIndex, sizeIndex);
       
   366         err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
       
   367         iActualSize = surfaceAttribs().iSize;
       
   368         sizeIndex--;
       
   369         }
       
   370     while(err != KErrNone && sizeIndex >= 0);
       
   371     User::LeaveIfError(err);
       
   372     }
       
   373 
       
   374 
       
   375 TUint8* CRawSurface::MapSurfaceAndGetInfoLC(RSurfaceManager::TSurfaceInfoV01& aInfo)
       
   376     {
       
   377     SURF_ASSERT(!iSurfaceId.IsNull());
       
   378     User::LeaveIfError(iSurfaceManager.MapSurface(iSurfaceId, iSurfaceChunk));
       
   379     CleanupClosePushL(iSurfaceChunk);
       
   380     RSurfaceManager::TInfoBuf infoBuf;
       
   381     User::LeaveIfError(iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf));
       
   382     aInfo = infoBuf();
       
   383     TInt offset = -1000;  // So we hopefully detect when it goes horribly wrong.
       
   384     User::LeaveIfError(iSurfaceManager.GetBufferOffset(iSurfaceId, iDrawBuffer, offset));
       
   385     SURF_ASSERT(offset >= 0);
       
   386     return iSurfaceChunk.Base() + offset;
       
   387     }
       
   388 
       
   389 
       
   390 void CRawSurface::DrawContentL(TInt aImageIndex)
       
   391     {
       
   392     CTestCFbsImage *image = CTestCFbsImage::NewL(aImageIndex);
       
   393     CleanupStack::PushL(image);
       
   394 
       
   395     RSurfaceManager::TSurfaceInfoV01 info;
       
   396     TUint8 *dataAddress = MapSurfaceAndGetInfoLC(info);
       
   397     TInt stride = info.iStride;
       
   398 
       
   399     CFbsBitmap *bitmap = image->Bitmap();
       
   400     TDisplayMode displaymode = bitmap->DisplayMode();
       
   401     TInt pixelStride = stride / CFbsBitmap::ScanLineLength(1, displaymode);
       
   402     for(TInt y = 0; y < image->Size().iHeight; y++)
       
   403         {
       
   404         TPtr8 buf(dataAddress + y * stride, stride);
       
   405 
       
   406         // TODO: We need to check that the bitsperpixel matches between the surface and bitmap.
       
   407         bitmap->GetScanLine(buf, TPoint(0, y), pixelStride, displaymode);
       
   408         }
       
   409 
       
   410     CleanupStack::PopAndDestroy(2, image);
       
   411     }
       
   412 
       
   413 void CRawSurface::DrawContentL(const TRgb& aColour)
       
   414     {
       
   415     //Map the surface and get its info.
       
   416     RSurfaceManager::TSurfaceInfoV01 surfaceInfo;
       
   417     TUint32* buffer = (TUint32*)MapSurfaceAndGetInfoLC(surfaceInfo);
       
   418 
       
   419     //Currently this function only supports drawing into ARGB_8888_PRE surfaces.
       
   420     //This is because the only test that uses this function uses this type of surface.
       
   421     //If this functionallity needs expanding, you must correctly convert the TRgb colour
       
   422     //and pack it into the surface buffer correctly.
       
   423     SURF_ASSERT(surfaceInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE);
       
   424 
       
   425     TUint32 fillColour = aColour._Color16MAP();
       
   426 
       
   427     //Loop over each pixel in the surface and colour it.
       
   428     //This is deliberately slow since it is only used for the tearing test
       
   429     //and we want to spend most of our time drawing so that the chances of the other thread
       
   430     //picking up a buffer in the middle of drawing is increased.
       
   431     for(TInt y=0; y < surfaceInfo.iSize.iHeight; ++y)
       
   432         {
       
   433         for(TInt x=0; x < surfaceInfo.iSize.iWidth; ++x)
       
   434             {
       
   435             buffer[x] = fillColour;
       
   436             }
       
   437         buffer += surfaceInfo.iStride >> 2;
       
   438         }
       
   439 
       
   440     CleanupStack::PopAndDestroy();
       
   441     }
       
   442 
       
   443 
       
   444 void CRawSurface::DrawComplexL(const TRgb& aColour)
       
   445     {
       
   446     DrawContentL(aColour);
       
   447     }
       
   448 
       
   449 
       
   450 TInt CRawSurface::SubmitContent(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
       
   451     {
       
   452     TRequestStatus displayNotify = KRequestPending;
       
   453     TTimeStamp timeStamp;
       
   454 
       
   455     if(aShouldWaitForDisplay)
       
   456         {
       
   457         Notify(ENotifyWhenDisplayed, displayNotify, 0);
       
   458         }
       
   459 
       
   460     TInt err = iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceId, iDrawBuffer, NULL);
       
   461     if (err != KErrNone)
       
   462         {
       
   463         if (err != KErrNone)
       
   464             {
       
   465             RDebug::Printf("%s:%d: SubmitUpdate gave unexpected error %d", __FILE__, __LINE__, err);
       
   466             }
       
   467         return err;
       
   468         }
       
   469     iDrawBuffer = (iDrawBuffer + 1) % iBuffers;
       
   470 
       
   471     if(aShouldWaitForDisplay)
       
   472         {
       
   473         TUint32 dummy;
       
   474         err = WaitFor(ENotifyWhenDisplayed, displayNotify, 100 * 1000, dummy);
       
   475         if (err != KErrNone && err != KErrNotVisible && err != KErrOverflow)
       
   476             {
       
   477 //            RDebug::Printf("%s:%d: NotifyWhenDisplayed gave unexpected error %d", __FILE__, __LINE__, err);
       
   478             return err;
       
   479             }
       
   480         }
       
   481     return KErrNone;
       
   482     }
       
   483 
       
   484 
       
   485 TSurfaceId CRawSurface::SurfaceId() const
       
   486     {
       
   487     return iSurfaceId;
       
   488     }
       
   489 
       
   490 
       
   491 void CRawSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
       
   492     {
       
   493     aParams.iCommonParams = KSurfaceParams[iParamIndex];
       
   494     aParams.iCommonParams.iBuffers = iBuffers; // May have been changed if it's a single buffered surface...
       
   495     aParams.iSurfaceId = SurfaceId();
       
   496     }
       
   497 
       
   498 const TText *CRawSurface::GetSurfaceTypeStr() const
       
   499     {
       
   500     return _S("CRawSurface");
       
   501     }
       
   502 
       
   503 TInt CRawSurface::Notify(TNotification aWhen, TRequestStatus& aStatus, TUint32 aXTimes)
       
   504     {
       
   505     aStatus = KRequestPending;
       
   506     switch(aWhen)
       
   507         {
       
   508         case ENotifyWhenAvailable:
       
   509             iSurfaceUpdate.NotifyWhenAvailable(aStatus);
       
   510             break;
       
   511         case ENotifyWhenDisplayed:
       
   512             iSurfaceUpdate.NotifyWhenDisplayed(aStatus, iTimeStamp);
       
   513             break;
       
   514         case ENotifyWhenDispXTimes:
       
   515             iSurfaceUpdate.NotifyWhenDisplayedXTimes(aXTimes, aStatus);
       
   516             break;
       
   517         default:
       
   518             RDebug::Printf("%s:%d: Invalid notification: %d. Panicking...", __FILE__, __LINE__, aWhen);
       
   519             User::Panic(_L("CRawSurface::Notify()"), __LINE__);
       
   520             break;
       
   521         }
       
   522     return KErrNone;
       
   523     }
       
   524 
       
   525 
       
   526 TInt CRawSurface::WaitFor(TNotification aWhen, TRequestStatus& aStatus, TInt aTimeoutInMicroSeconds, TUint32& aTimeStamp)
       
   527     {
       
   528     RTimer timer;
       
   529     TInt err = timer.CreateLocal();
       
   530     if (err != KErrNone)
       
   531         {
       
   532         RDebug::Printf("%s:%d: Could not create timer... err= %d", __FILE__, __LINE__, err);
       
   533         return err;
       
   534         }
       
   535     TRequestStatus timerStatus = KRequestPending;
       
   536 #if __WINS__
       
   537     // Windows timer isn't very precise - add some "fuzz" to the timeout to ensure we do not wait "too little".
       
   538     const TInt KTimeOutExtra = 20000;
       
   539 #else
       
   540     // On hardware, we should be able to run with less "fuzz".
       
   541     const TInt KTimeOutExtra = 10000;
       
   542 #endif
       
   543     timer.HighRes(timerStatus, aTimeoutInMicroSeconds + KTimeOutExtra);
       
   544     User::WaitForRequest(timerStatus, aStatus);
       
   545     if (aStatus == KRequestPending)
       
   546         {
       
   547         if (aWhen == ENotifyWhenDisplayed)
       
   548             {
       
   549             aTimeStamp = User::FastCounter();
       
   550             }
       
   551         return KErrTimedOut;
       
   552         }
       
   553     if (aWhen == ENotifyWhenDisplayed)
       
   554         {
       
   555         aTimeStamp = iTimeStamp();
       
   556         }
       
   557     timer.Cancel();
       
   558     timer.Close();
       
   559     TInt result = aStatus.Int();
       
   560     aStatus = KRequestPending;
       
   561     return result;
       
   562     }
       
   563 
       
   564 const TText *CRawSingleBufferSurface::GetSurfaceTypeStr() const
       
   565     {
       
   566     return _S("CRawSingleBufferedSurface");
       
   567     }
       
   568 
       
   569 CRawSingleBufferSurface *CRawSingleBufferSurface::NewL()
       
   570     {
       
   571     CRawSingleBufferSurface* obj = new (ELeave) CRawSingleBufferSurface();
       
   572     CleanupStack::PushL(obj);
       
   573     obj->ConstructL();
       
   574     CleanupStack::Pop(obj);
       
   575     return obj;
       
   576     }
       
   577 
       
   578 
       
   579 void CRawSingleBufferSurface::CreateL(TInt aIndex, const TPoint & /*aPoint */)
       
   580     {
       
   581     RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
       
   582 
       
   583     TInt sizeIndex = 0;
       
   584     if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
       
   585         {
       
   586         sizeIndex = KMaxSurfaceSizes-1;
       
   587         }
       
   588     TInt err = KErrNone;
       
   589     do
       
   590         {
       
   591         GetSurfAttribs(surfaceAttribs, aIndex, sizeIndex);
       
   592         iBuffers = 1;
       
   593         surfaceAttribs().iBuffers = 1;
       
   594         err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
       
   595         iActualSize = surfaceAttribs().iSize;
       
   596         sizeIndex--;
       
   597         }
       
   598     while(err != KErrNone && sizeIndex >= 0);
       
   599     }
       
   600 
       
   601 CRawSingleBufferSurface::~CRawSingleBufferSurface()
       
   602     {
       
   603     }
       
   604 
       
   605 
       
   606 TInt CEglSurfaceBase::Activate()
       
   607     {
       
   608     if (!eglMakeCurrent(iDisplay, iSurface, iSurface, iContext))
       
   609         {
       
   610         EGLint err = eglGetError();
       
   611         RDebug::Printf("%s:%d: eglMakeCurrent gave error 0x%x", __FILE__, __LINE__, err);
       
   612         return KErrBadHandle;
       
   613         }
       
   614     return KErrNone;
       
   615     }
       
   616 
       
   617 void CEglSurfaceBase::ActivateL()
       
   618     {
       
   619     User::LeaveIfError(Activate());
       
   620     }
       
   621 
       
   622 void CEglSurfaceBase::DrawComplexL(const TRgb& aColour)
       
   623     {
       
   624     ActivateL();
       
   625 
       
   626     TSize size;
       
   627     eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth);
       
   628     eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight);
       
   629     
       
   630     //Paint lots of random circles to keep the GPU busy.
       
   631     for(TInt i=0; i < 300; i++)
       
   632         {
       
   633         VGPaint paint = vgCreatePaint();
       
   634         VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_APPEND_TO);
       
   635         
       
   636         TInt minDim = Min(size.iWidth, size.iHeight);
       
   637         VGfloat cx = RandomNumberInRange(0, size.iWidth);
       
   638         VGfloat cy = RandomNumberInRange(0, size.iHeight);
       
   639         VGfloat diameter = RandomNumberInRange(minDim / 20, minDim / 3);
       
   640         TRgb fillColour(RandomNumberInRange(0, 255), RandomNumberInRange(0, 255), RandomNumberInRange(0, 255), RandomNumberInRange(0, 255));
       
   641         
       
   642         vguEllipse(path, cx, cy, diameter, diameter);
       
   643         vgSetPaint(paint, VG_FILL_PATH);
       
   644         vgSetColor(paint, fillColour.Value());
       
   645         vgDrawPath(path, VG_FILL_PATH);
       
   646         
       
   647         vgDestroyPath(path);
       
   648         vgDestroyPaint(paint);
       
   649         }
       
   650     
       
   651     //Paint the top corner with aColour so we can identify the drawing.
       
   652     VGfloat fillColour[4];
       
   653     fillColour[0] = (VGfloat)aColour.Red() / 255.0f;
       
   654     fillColour[1] = (VGfloat)aColour.Green() / 255.0f;
       
   655     fillColour[2] = (VGfloat)aColour.Blue() / 255.0f;
       
   656     fillColour[3] = (VGfloat)aColour.Alpha() / 255.0f;
       
   657     
       
   658     vgSetfv(VG_CLEAR_COLOR, 4, fillColour);
       
   659     vgClear(0, 0, 20, size.iHeight);
       
   660     }
       
   661 
       
   662 void CEglSurfaceBase::DrawContentL(const TRgb& aColour)
       
   663     {
       
   664     ActivateL();
       
   665 
       
   666     TSize size;
       
   667     eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth);
       
   668     eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight);
       
   669 
       
   670     VGfloat fillColour[4];
       
   671     fillColour[0] = (VGfloat)aColour.Red() / 255.0f;
       
   672     fillColour[1] = (VGfloat)aColour.Green() / 255.0f;
       
   673     fillColour[2] = (VGfloat)aColour.Blue() / 255.0f;
       
   674     fillColour[3] = (VGfloat)aColour.Alpha() / 255.0f;
       
   675 
       
   676     vgSetfv(VG_CLEAR_COLOR, 4, fillColour);
       
   677     vgClear(0, 0, size.iWidth, size.iHeight);
       
   678     }
       
   679 
       
   680 void CEglSurfaceBase::CreateL(TInt aIndex, const TPoint &aOffset)
       
   681     {
       
   682     SURF_ASSERT(aIndex < KSurfaceMaxIndex);
       
   683     SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
       
   684 
       
   685     TInt sizeIndex = 0;
       
   686     if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG)
       
   687         {
       
   688         sizeIndex = KMaxSurfaceSizes-1;
       
   689         }
       
   690     TInt err = KErrNone;
       
   691     do
       
   692         {
       
   693         TRAP(err, DoCreateL(aIndex, aOffset, sizeIndex));
       
   694         sizeIndex--;
       
   695         }
       
   696     while(err != KErrNone && sizeIndex >= 0);
       
   697     if (err != KErrNone)
       
   698         {
       
   699 //        RDebug::Printf("%s:%d: err=%d (%d x %d)", __FILE__, __LINE__, err, iActualSize.iWidth, iActualSize.iHeight);
       
   700         User::Leave(err);
       
   701         }
       
   702     }
       
   703 
       
   704 TInt CEglSurfaceBase::SubmitContent(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
       
   705     {
       
   706     TInt err = Activate();
       
   707     if (err != KErrNone)
       
   708         {
       
   709         return err;
       
   710         }
       
   711     if (!eglSwapBuffers(iDisplay, iSurface))
       
   712         {
       
   713         EGLint err = eglGetError();
       
   714         RDebug::Printf("%s:%d: eglSwapBuffers gave error 0x%x", __FILE__, __LINE__, err);
       
   715         return KErrBadHandle;
       
   716         }
       
   717     if (aShouldWaitForDisplay)
       
   718         {
       
   719         // We are cheating: We just wait for a bit to ensure that the swapbuffer is actually finished.
       
   720         // There is no way to determine how long this takes, so we just grab a number that should be
       
   721         // large enough...
       
   722         User::After(100 * 1000);  // Wait 100ms.
       
   723         }
       
   724     return KErrNone;
       
   725     }
       
   726 
       
   727 void CEglSurfaceBase::DrawContentL(TInt aIndex)
       
   728     {
       
   729     ActivateL();
       
   730     CTestVgImage *vgImage = CTestVgImage::NewL(aIndex);
       
   731     CleanupStack::PushL(vgImage);
       
   732     vgDrawImage(vgImage->VGImage());
       
   733     CleanupStack::PopAndDestroy(vgImage);
       
   734     }
       
   735 
       
   736 void CEglSurfaceBase::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
       
   737     {
       
   738     RSurfaceManager surfaceManager;
       
   739     User::LeaveIfError(surfaceManager.Open());
       
   740     RSurfaceManager::TInfoBuf infoBuf;
       
   741     TInt err = surfaceManager.SurfaceInfo(SurfaceId(), infoBuf);
       
   742     User::LeaveIfError(err);
       
   743     surfaceManager.Close();
       
   744     RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   745     aParams.iSurfaceId = SurfaceId();
       
   746     aParams.iCommonParams.iAlignment = -1;  // N/A
       
   747     aParams.iCommonParams.iBuffers = info.iBuffers;
       
   748     aParams.iCommonParams.iOffsetToFirstBuffer = -1;
       
   749     aParams.iCommonParams.iPixelFormat = info.iPixelFormat;
       
   750     aParams.iCommonParams.iStrideInBytes = info.iStride;
       
   751     aParams.iCommonParams.iXSize = info.iSize.iWidth;
       
   752     aParams.iCommonParams.iYSize = info.iSize.iHeight;
       
   753     aParams.iCommonParams.iUseAttribList = KSurfaceParams[iParamIndex].iUseAttribList;
       
   754     for(TInt i = 0; i < KNumAttribs; i++)
       
   755         {
       
   756         aParams.iCommonParams.iAttribs[i] = KSurfaceParams[iParamIndex].iAttribs[i];
       
   757         }
       
   758     }
       
   759 
       
   760 
       
   761 TInt CEglSurfaceBase::Notify(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, TUint32 /*aXTImes*/)
       
   762     {
       
   763     return KErrNotSupported;
       
   764     }
       
   765 
       
   766 TInt CEglSurfaceBase::WaitFor(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/,
       
   767         TInt /*aTimeoutinMicroseconds*/, TUint32 & /*aTimeStamp*/)
       
   768     {
       
   769     return KErrNotSupported;
       
   770     }
       
   771 
       
   772 void CEglSurfaceBase::BaseCreateL(TInt aIndex, EGLint aSurfaceType)
       
   773     {
       
   774     iParamIndex = aIndex;
       
   775     iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
       
   776     
       
   777     EGLint err;
       
   778     if (iDisplay == EGL_NO_DISPLAY)
       
   779         {
       
   780         err = eglGetError();
       
   781         RDebug::Printf("%s:%d: err = 0x%x", __FILE__, __LINE__, err);
       
   782         User::Leave(KErrNotSupported);
       
   783         }
       
   784     
       
   785     EGLint nConfigs = 0;
       
   786     
       
   787     // TODO: Need to use differnet config attribs based on aIndex.
       
   788     EGLint configAttribs[] =
       
   789     {
       
   790         EGL_BUFFER_SIZE,    32,
       
   791         EGL_RED_SIZE,       8,
       
   792         EGL_GREEN_SIZE,     8,
       
   793         EGL_BLUE_SIZE,      8,
       
   794         EGL_ALPHA_SIZE,     8,
       
   795         EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
       
   796         EGL_RENDERABLE_TYPE,EGL_OPENVG_BIT,
       
   797         EGL_NONE
       
   798     };
       
   799     
       
   800     // Update surfacetype type to match 
       
   801     for(TInt i = 0; configAttribs[i] != EGL_NONE; i += 2)
       
   802         {
       
   803         if (configAttribs[i] == EGL_SURFACE_TYPE)
       
   804             {
       
   805             configAttribs[i+1] = aSurfaceType;
       
   806             }
       
   807         }
       
   808     // Need some way to configure the attribs ...
       
   809     eglChooseConfig(iDisplay, configAttribs, &iConfig, 1, &nConfigs);
       
   810     if (!nConfigs)
       
   811         {
       
   812         err = eglGetError();
       
   813         RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   814         User::Leave(KErrNotSupported);
       
   815         }
       
   816     
       
   817     if (!eglBindAPI(EGL_OPENVG_API))
       
   818         {
       
   819         err = eglGetError();
       
   820         RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   821         User::Leave(KErrNotSupported);
       
   822         }
       
   823     iContext = eglCreateContext(iDisplay, iConfig, 0, NULL);
       
   824     if (iContext == EGL_NO_CONTEXT)
       
   825         {
       
   826         err = eglGetError();
       
   827         //RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   828         User::Leave(KErrNotSupported);
       
   829         }
       
   830     }
       
   831 
       
   832 void CEglSurfaceBase::Destroy()
       
   833     {
       
   834     eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
       
   835     if (iSurface != EGL_NO_SURFACE)
       
   836         {
       
   837         eglDestroySurface(iDisplay, iSurface);
       
   838         iSurface = EGL_NO_SURFACE;
       
   839         }
       
   840 
       
   841     if (iDisplay != EGL_NO_DISPLAY)
       
   842         {
       
   843         eglDestroyContext(iDisplay, iContext);
       
   844         }
       
   845     }
       
   846 
       
   847 
       
   848 class CWindow: public CBase
       
   849     {
       
   850 public:
       
   851     static CWindow *NewL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex);
       
   852     RWindow& Window();
       
   853     ~CWindow();
       
   854 private:
       
   855     void ConstructL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex);
       
   856     CWindow();
       
   857 
       
   858 private:
       
   859     RWindow iWindow;
       
   860     RWindowGroup iWindowGroup;
       
   861     RWsSession iWsSession;
       
   862     };
       
   863 
       
   864 
       
   865 CWindow* CWindow::NewL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex)
       
   866     {
       
   867     CWindow *self = new (ELeave) CWindow;
       
   868     CleanupStack::PushL(self);
       
   869     self->ConstructL(aIndex, aOffset, aSizeIndex);
       
   870     CleanupStack::Pop(self);
       
   871     return self;
       
   872     }
       
   873 
       
   874 
       
   875 void CWindow::ConstructL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex)
       
   876     {
       
   877     RFbsSession::Connect();
       
   878     if (aIndex >= KSurfaceMaxIndex)
       
   879         {
       
   880         User::Leave(KErrOverflow);
       
   881         }
       
   882     User::LeaveIfError(iWsSession.Connect());
       
   883     iWindowGroup = RWindowGroup(iWsSession);
       
   884     User::LeaveIfError(iWindowGroup.Construct((TUint32)this));
       
   885     iWindow = RWindow(iWsSession);
       
   886     User::LeaveIfError(iWindow.Construct(iWindowGroup, -1U));
       
   887     TSurfaceParamsCommon winAttrib = KSurfaceParams[aIndex];
       
   888     TSize winSize;
       
   889     if (winAttrib.iXSize & LARGEST_POSSIBLE_FLAG)
       
   890         {
       
   891         winSize = TSize(KSurfaceSizes[aSizeIndex].iWidth, KSurfaceSizes[aSizeIndex].iHeight);
       
   892         }
       
   893     else
       
   894         {
       
   895         winSize = TSize(winAttrib.iXSize, winAttrib.iYSize);
       
   896         }
       
   897     iWindow.SetExtent(TPoint(winAttrib.iXPos + aOffset.iX, winAttrib.iYPos + aOffset.iY), winSize);
       
   898     iWindow.SetRequiredDisplayMode(winAttrib.iDisplayMode);
       
   899     iWindow.Activate();
       
   900     }
       
   901 
       
   902 
       
   903 CWindow::~CWindow()
       
   904     {
       
   905     iWindow.Close();
       
   906     iWindowGroup.Close();
       
   907     iWsSession.Close();
       
   908     RFbsSession::Disconnect();
       
   909     }
       
   910 
       
   911 
       
   912 CWindow::CWindow()
       
   913     {
       
   914     }
       
   915 
       
   916 
       
   917 RWindow& CWindow::Window()
       
   918     {
       
   919     return iWindow;
       
   920     }
       
   921 
       
   922 
       
   923 CEglWindowSurface* CEglWindowSurface::NewL()
       
   924     {
       
   925     CEglWindowSurface* self = new (ELeave) CEglWindowSurface;
       
   926     CleanupStack::PushL(self);
       
   927     self->ConstructL();
       
   928     CleanupStack::Pop(self);
       
   929     return self;
       
   930     }
       
   931 
       
   932 
       
   933 void CEglWindowSurface::ConstructL()
       
   934     {
       
   935     }
       
   936 
       
   937 
       
   938 CEglWindowSurface::CEglWindowSurface()
       
   939     {
       
   940     }
       
   941 
       
   942 
       
   943 void CEglWindowSurface::DoCreateL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex)
       
   944     {
       
   945     iParamIndex = aIndex;
       
   946     iWindow = CWindow::NewL(aIndex, aOffset, aSizeIndex);
       
   947     iActualSize = iWindow->Window().Size();
       
   948     
       
   949     CEglSurfaceBase::BaseCreateL(aIndex, EGL_WINDOW_BIT);
       
   950     
       
   951     iSurface = eglCreateWindowSurface(iDisplay, iConfig, &iWindow->Window(), NULL);
       
   952     if (iSurface == EGL_NO_SURFACE)
       
   953         {
       
   954         EGLint err = eglGetError();
       
   955         RDebug::Printf("%s:%d: err = %x (%d x %d)", __FILE__, __LINE__, err, iActualSize.iWidth, iActualSize.iHeight);
       
   956         User::Leave(KErrNotSupported);
       
   957         }
       
   958     }
       
   959 
       
   960 
       
   961 CEglWindowSurface::~CEglWindowSurface()
       
   962     {
       
   963     Destroy();
       
   964 	eglReleaseThread();
       
   965     delete iWindow;
       
   966     }
       
   967 
       
   968 
       
   969 TSurfaceId CEglWindowSurface::SurfaceId() const
       
   970     {
       
   971     // Default constructor for id sets it to a NULL-value, so if no window is created, we get
       
   972     // a defined surface id value that is invalid.
       
   973     TSurfaceId id;
       
   974     if (iWindow)
       
   975         {
       
   976         TSurfaceConfiguration surfConfig;
       
   977         iWindow->Window().GetBackgroundSurface(surfConfig);
       
   978         surfConfig.GetSurfaceId(id);
       
   979         }
       
   980     return id;
       
   981     }
       
   982 
       
   983 
       
   984 const TText *CEglWindowSurface::GetSurfaceTypeStr() const
       
   985     {
       
   986     return _S("CEglWindowSurface");
       
   987     }
       
   988 
       
   989 
       
   990 CEglPBufferSurface::CEglPBufferSurface()
       
   991     {
       
   992     }
       
   993 
       
   994 
       
   995 CEglPBufferSurface::~CEglPBufferSurface()
       
   996     {
       
   997     Destroy();
       
   998 	eglReleaseThread();
       
   999     }
       
  1000     
       
  1001 
       
  1002 CEglPBufferSurface* CEglPBufferSurface::NewL()
       
  1003     {
       
  1004     CEglPBufferSurface* self = new (ELeave) CEglPBufferSurface;
       
  1005     CleanupStack::PushL(self);
       
  1006     self->ConstructL();
       
  1007     CleanupStack::Pop(self);
       
  1008     return self;
       
  1009     }
       
  1010 
       
  1011 
       
  1012 void CEglPBufferSurface::ConstructL()
       
  1013     {
       
  1014     }
       
  1015     
       
  1016 
       
  1017 const TText *CEglPBufferSurface::GetSurfaceTypeStr() const
       
  1018     {
       
  1019     return _S("CEglPBufferSurface");
       
  1020     }
       
  1021 
       
  1022 
       
  1023 void CEglPBufferSurface::DoCreateL(TInt aIndex, const TPoint &/*aOffset*/, TInt aSizeIndex)
       
  1024     {
       
  1025     CEglSurfaceBase::BaseCreateL(aIndex, EGL_PBUFFER_BIT);
       
  1026 
       
  1027     EGLint attribs[] = 
       
  1028             {
       
  1029                 EGL_WIDTH, 0,
       
  1030                 EGL_HEIGHT, 0,
       
  1031                 EGL_NONE,
       
  1032             };
       
  1033     if (KSurfaceParams[aIndex].iXSize & ELargestPossibleSurface)
       
  1034         {
       
  1035         iActualSize.iWidth = KSurfaceSizes[aSizeIndex].iWidth;
       
  1036         iActualSize.iHeight = KSurfaceSizes[aSizeIndex].iHeight;
       
  1037         }
       
  1038     else
       
  1039         {
       
  1040         iActualSize.iWidth = KSurfaceParams[aIndex].iXSize;
       
  1041         iActualSize.iHeight = KSurfaceParams[aIndex].iYSize;
       
  1042         }
       
  1043     for(TInt i = 0; attribs[i] != EGL_NONE; i += 2)
       
  1044         {
       
  1045         switch(attribs[i])
       
  1046             {
       
  1047             case EGL_HEIGHT:
       
  1048                 attribs[i+1] = iActualSize.iHeight;
       
  1049                 break;
       
  1050             case EGL_WIDTH:
       
  1051                 attribs[i+1] = iActualSize.iWidth;
       
  1052                 break;
       
  1053             }
       
  1054         }
       
  1055     
       
  1056     iSurface = eglCreatePbufferSurface(iDisplay, iConfig, attribs);
       
  1057     if (iSurface == EGL_NO_SURFACE)
       
  1058         {
       
  1059         EGLint err = eglGetError();
       
  1060         User::Leave(KErrNotSupported);
       
  1061         }
       
  1062     }
       
  1063 
       
  1064 
       
  1065 TSurfaceId CEglPBufferSurface::SurfaceId() const
       
  1066     {
       
  1067     SURF_ASSERT(0);  // We shouldn't call this!
       
  1068     return TSurfaceId::CreateNullId();
       
  1069     }
       
  1070 
       
  1071 TInt CEglPBufferSurface::SizeInBytes() const
       
  1072     {
       
  1073     // size of a pixel in bits. 
       
  1074     EGLint size;
       
  1075     if (!eglGetConfigAttrib(iDisplay, iConfig, EGL_BUFFER_SIZE, &size))
       
  1076         {
       
  1077         RDebug::Printf("Unable to get EGL_BUFFER_SIZE from config %d, err = %04x", iConfig, eglGetError());
       
  1078         return 0;
       
  1079         }
       
  1080     
       
  1081     return (KSurfaceParams[iParamIndex].iXSize * KSurfaceParams[iParamIndex].iYSize * size) / 8;
       
  1082     }
       
  1083 
       
  1084 
       
  1085 // Factory function.
       
  1086 CSurface *CSurface::SurfaceFactoryL(TSurfaceType aSurfaceType)
       
  1087     {
       
  1088     switch(aSurfaceType)
       
  1089         {
       
  1090         case ESurfTypeRaw:
       
  1091             return CRawSurface::NewL();
       
  1092             
       
  1093         case ESurfTypeEglWindow:
       
  1094             return CEglWindowSurface::NewL();
       
  1095             
       
  1096         case ESurfTypeRawSingleBuffered:
       
  1097             return CRawSingleBufferSurface::NewL();
       
  1098             
       
  1099         case ESurfTypePBuffer:
       
  1100             return CEglPBufferSurface::NewL();
       
  1101             
       
  1102         default:
       
  1103             SURF_ASSERT(0);
       
  1104             return NULL;
       
  1105         }
       
  1106     }