egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp
changeset 98 bf7481649c98
child 136 62bb7c97884c
equal deleted inserted replaced
85:cdf2f6e5c390 98:bf7481649c98
       
     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 
       
    27 #define SURF_ASSERT(x) { if (!(x)) { RDebug::Printf("ASSERT(%s) failed at %s:%d", #x, __FILE__, __LINE__); User::Panic(_L("ASSERT SURF"), __LINE__); }}
       
    28 
       
    29 // Macros for indicating what is what.
       
    30 #define SIZE(x, y) x, y
       
    31 #define Buffers(x) x
       
    32 #define DefaultAlignment 32  // Pick some value that is valid.
       
    33 #define Alignment(x) x
       
    34 #define Stride(x) x
       
    35 #define DefaultStride 0
       
    36 // Note: Offset to first buffer.
       
    37 #define Offset(x) x
       
    38 #define WindowPos(x, y)  x, y
       
    39 #define WindowMode(m) m
       
    40 
       
    41 static const TSurfaceParamsCommon KSurfaceParams[] =
       
    42 {
       
    43     {
       
    44         EStandardSurface,
       
    45         SIZE(100, 100),
       
    46         Buffers(2),
       
    47         DefaultAlignment,
       
    48         DefaultStride,
       
    49         Offset(0),
       
    50         EUidPixelFormatARGB_8888_PRE,
       
    51         EFalse,
       
    52         { 0 },
       
    53         WindowPos(0, 0),
       
    54         WindowMode(EColor16MAP)
       
    55     },
       
    56     {
       
    57         EBadAttribSurface,
       
    58         SIZE(100, 100),
       
    59         Buffers(2),
       
    60         DefaultAlignment,
       
    61         DefaultStride,
       
    62         Offset(0),
       
    63         EUidPixelFormatARGB_8888_PRE,
       
    64         ETrue,
       
    65         { 1, 1, EGL_NONE },
       
    66         WindowPos(0, 0),
       
    67         WindowMode(EColor16MAP)
       
    68     },
       
    69     {
       
    70         EEmptyAttribSurface,
       
    71         SIZE(100, 100),
       
    72         Buffers(2),
       
    73         DefaultAlignment,
       
    74         DefaultStride,
       
    75         Offset(0),
       
    76         EUidPixelFormatARGB_8888_PRE,
       
    77         ETrue,
       
    78         { EGL_NONE },
       
    79         WindowPos(0, 0),
       
    80         WindowMode(EColor16MAP)
       
    81     },
       
    82     {
       
    83         EStandard128sqSurface,
       
    84         SIZE(128, 128),
       
    85         Buffers(3),
       
    86         DefaultAlignment,
       
    87         DefaultStride,
       
    88         Offset(0),
       
    89         EUidPixelFormatARGB_8888_PRE,
       
    90         EFalse,
       
    91         { 0 },
       
    92         WindowPos(20, 20),
       
    93         WindowMode(EColor16MAP)
       
    94     },
       
    95     {
       
    96         EUnusualStrideSurface,
       
    97         SIZE(167,263),
       
    98         Buffers(2),
       
    99         Alignment(8),
       
   100         Stride(167*4+64),
       
   101         Offset(200),
       
   102         EUidPixelFormatARGB_8888_PRE,
       
   103         EFalse,
       
   104         { 0 },
       
   105         WindowPos(0, 0),
       
   106         WindowMode(EColor16MAP)
       
   107     },
       
   108     {
       
   109         EUnalignedPixelSizeSurface,
       
   110         SIZE(103, 107),
       
   111         Buffers(2),
       
   112         Alignment(8),
       
   113         Stride(103*4),
       
   114         Offset(0),
       
   115         EUidPixelFormatARGB_8888_PRE,
       
   116         EFalse,
       
   117         { 0 },
       
   118         WindowPos(0, 0),
       
   119         WindowMode(EColor16MAP)
       
   120     },
       
   121     {
       
   122         ELargeSurface,
       
   123         SIZE(800, 600),
       
   124         Buffers(2),
       
   125         DefaultAlignment,
       
   126         DefaultStride,
       
   127         Offset(0),
       
   128         EUidPixelFormatARGB_8888_PRE,
       
   129         EFalse,
       
   130         { 0 },
       
   131         WindowPos(0, 0),
       
   132         WindowMode(EColor16MAP)
       
   133     },
       
   134 };
       
   135 
       
   136 
       
   137 TInt KSurfaceMaxIndex = sizeof(KSurfaceParams) / sizeof(KSurfaceParams[0]);
       
   138 
       
   139 CRawSurface* CRawSurface::NewL()
       
   140     {
       
   141     CRawSurface* obj = new (ELeave) CRawSurface();
       
   142     CleanupStack::PushL(obj);
       
   143     obj->ConstructL();
       
   144     CleanupStack::Pop(obj);
       
   145     return obj;
       
   146     }
       
   147 
       
   148 
       
   149 CRawSurface::CRawSurface() : iDrawBuffer(0), iBuffers(0)
       
   150     {
       
   151     }
       
   152 
       
   153 
       
   154 void CRawSurface::ConstructL()
       
   155     {
       
   156     iSurfaceId = TSurfaceId::CreateNullId();
       
   157     User::LeaveIfError(iSurfaceManager.Open());
       
   158     User::LeaveIfError(iSurfaceUpdate.Connect(5));
       
   159     }
       
   160 
       
   161 
       
   162 CRawSurface::~CRawSurface()
       
   163     {
       
   164     iSurfaceUpdate.Close();
       
   165     if(!iSurfaceId.IsNull())
       
   166         {
       
   167         iSurfaceManager.CloseSurface(iSurfaceId);
       
   168         }
       
   169     iSurfaceManager.Close();
       
   170     }
       
   171 
       
   172 
       
   173 TInt CRawSurface::PixelSize(TUidPixelFormat aPixelFormat)
       
   174     {
       
   175     switch(aPixelFormat)
       
   176         {
       
   177         case EUidPixelFormatARGB_8888_PRE:
       
   178         case EUidPixelFormatARGB_8888:
       
   179         case EUidPixelFormatABGR_8888:
       
   180         case EUidPixelFormatABGR_8888_PRE:
       
   181             return 4;
       
   182 
       
   183         case EUidPixelFormatARGB_4444:
       
   184         case EUidPixelFormatRGB_565:
       
   185             return 2;
       
   186 
       
   187         default:
       
   188             SURF_ASSERT(0);
       
   189             break;
       
   190         }
       
   191     return 0; // Make sure no compiler moans about "not all paths return a value".
       
   192     }
       
   193 
       
   194 
       
   195 void CRawSurface::GetSurfAttribs(RSurfaceManager::TSurfaceCreationAttributesBuf &aSurfaceAttribs, TInt aIndex)
       
   196     {
       
   197     SURF_ASSERT(aIndex < KSurfaceMaxIndex);
       
   198     SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
       
   199     iParamIndex = aIndex;
       
   200     aSurfaceAttribs().iSize = TSize(KSurfaceParams[aIndex].iXSize, KSurfaceParams[aIndex].iYSize);
       
   201     iBuffers = KSurfaceParams[aIndex].iBuffers;
       
   202     aSurfaceAttribs().iBuffers = iBuffers;
       
   203     aSurfaceAttribs().iPixelFormat = KSurfaceParams[aIndex].iPixelFormat;
       
   204     TInt stride = KSurfaceParams[aIndex].iStrideInBytes;
       
   205     if (stride == 0)
       
   206         {
       
   207         stride = KSurfaceParams[aIndex].iXSize * PixelSize(KSurfaceParams[aIndex].iPixelFormat);
       
   208         }
       
   209     aSurfaceAttribs().iStride = stride;
       
   210     aSurfaceAttribs().iOffsetToFirstBuffer = KSurfaceParams[aIndex].iOffsetToFirstBuffer;
       
   211     aSurfaceAttribs().iAlignment = KSurfaceParams[aIndex].iAlignment;
       
   212     aSurfaceAttribs().iContiguous = EFalse;
       
   213     aSurfaceAttribs().iCacheAttrib = RSurfaceManager::ECached;
       
   214     aSurfaceAttribs().iOffsetBetweenBuffers = 0;
       
   215     aSurfaceAttribs().iSurfaceHints = NULL;
       
   216     aSurfaceAttribs().iHintCount = 0;
       
   217     aSurfaceAttribs().iMappable = ETrue;
       
   218     }
       
   219 
       
   220 
       
   221 //From CSurface.
       
   222 void CRawSurface::CreateL(TInt aIndex)
       
   223     {
       
   224     RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
       
   225 
       
   226     GetSurfAttribs(surfaceAttribs, aIndex);
       
   227     TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
       
   228     User::LeaveIfError(err);
       
   229     }
       
   230 
       
   231 
       
   232 TUint8* CRawSurface::MapSurfaceAndGetInfoLC(RSurfaceManager::TSurfaceInfoV01& aInfo)
       
   233     {
       
   234     SURF_ASSERT(!iSurfaceId.IsNull());
       
   235     User::LeaveIfError(iSurfaceManager.MapSurface(iSurfaceId, iSurfaceChunk));
       
   236     CleanupClosePushL(iSurfaceChunk);
       
   237     RSurfaceManager::TInfoBuf infoBuf;
       
   238     User::LeaveIfError(iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf));
       
   239     aInfo = infoBuf();
       
   240     TInt offset = -1000;  // So we hopefully detect when it goes horribly wrong.
       
   241     User::LeaveIfError(iSurfaceManager.GetBufferOffset(iSurfaceId, iDrawBuffer, offset));
       
   242     return iSurfaceChunk.Base() + offset;
       
   243     }
       
   244 
       
   245 
       
   246 void CRawSurface::DrawContentL(TInt aImageIndex)
       
   247     {
       
   248     CTestCFbsImage *image = CTestCFbsImage::NewL(aImageIndex);
       
   249     CleanupStack::PushL(image);
       
   250 
       
   251     RSurfaceManager::TSurfaceInfoV01 info;
       
   252     TUint8 *dataAddress = MapSurfaceAndGetInfoLC(info);
       
   253     TInt stride = info.iStride;
       
   254 
       
   255     CFbsBitmap *bitmap = image->Bitmap();
       
   256     TDisplayMode displaymode = bitmap->DisplayMode();
       
   257     TInt pixelStride = stride / CFbsBitmap::ScanLineLength(1, displaymode);
       
   258     for(TInt y = 0; y < image->Size().iHeight; y++)
       
   259         {
       
   260         TPtr8 buf(dataAddress + y * stride, stride);
       
   261 
       
   262         // TODO: We need to check that the bitsperpixel matches between the surface and bitmap.
       
   263         bitmap->GetScanLine(buf, TPoint(0, y), pixelStride, displaymode);
       
   264         }
       
   265 
       
   266     CleanupStack::PopAndDestroy(2, image);
       
   267     }
       
   268 
       
   269 
       
   270 void CRawSurface::DrawContentL(const TRgb& aColour)
       
   271     {
       
   272     //Map the surface and get its info.
       
   273     RSurfaceManager::TSurfaceInfoV01 surfaceInfo;
       
   274     TUint32* buffer = (TUint32*)MapSurfaceAndGetInfoLC(surfaceInfo);
       
   275 
       
   276     //Currently this function only supports drawing into ARGB_8888_PRE surfaces.
       
   277     //This is because the only test that uses this function uses this type of surface.
       
   278     //If this functionallity needs expanding, you must correctly convert the TRgb colour
       
   279     //and pack it into the surface buffer correctly.
       
   280     SURF_ASSERT(surfaceInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE);
       
   281 
       
   282     TUint32 fillColour = aColour._Color16MAP();
       
   283 
       
   284     //Loop over each pixel in the surface and colour it.
       
   285     //This is deliberately slow since it is only used for the tearing test
       
   286     //and we want to spend most of our time drawing so that the chances of the other thread
       
   287     //picking up a buffer in the middle of drawing is increased.
       
   288     for(TInt y=0; y < surfaceInfo.iSize.iHeight; ++y)
       
   289         {
       
   290         for(TInt x=0; x < surfaceInfo.iSize.iWidth; ++x)
       
   291             {
       
   292             buffer[x] = fillColour;
       
   293             }
       
   294         buffer += surfaceInfo.iStride >> 2;
       
   295         }
       
   296 
       
   297     CleanupStack::PopAndDestroy();
       
   298     }
       
   299 
       
   300 
       
   301 void CRawSurface::SubmitContentL(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
       
   302     {
       
   303     TRequestStatus displayNotify = KRequestPending;
       
   304     TTimeStamp timeStamp;
       
   305 
       
   306     if(aShouldWaitForDisplay)
       
   307         {
       
   308         Notify(ENotifyWhenDisplayed, displayNotify, 0);
       
   309         }
       
   310 
       
   311     TInt err = iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceId, iDrawBuffer, NULL);
       
   312     User::LeaveIfError(err);
       
   313     iDrawBuffer = (iDrawBuffer + 1) % iBuffers;
       
   314 
       
   315     if(aShouldWaitForDisplay)
       
   316         {
       
   317         TUint32 dummy;
       
   318         TInt err = WaitFor(ENotifyWhenDisplayed, displayNotify, 100 * 1000, dummy);
       
   319         if (err != KErrNone && err != KErrNotVisible && err != KErrOverflow)
       
   320             {
       
   321             RDebug::Printf("%s:%d: NotifyWhenDisplayed gave unexpected error %d", __FILE__, __LINE__, err);
       
   322             User::Leave(err);
       
   323             }
       
   324         }
       
   325     }
       
   326 
       
   327 
       
   328 TSurfaceId CRawSurface::SurfaceId() const
       
   329     {
       
   330     return iSurfaceId;
       
   331     }
       
   332 
       
   333 
       
   334 void CRawSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
       
   335     {
       
   336     aParams.iCommonParams = KSurfaceParams[iParamIndex];
       
   337     aParams.iCommonParams.iBuffers = iBuffers; // May have been changed if it's a single buffered surface...
       
   338     aParams.iSurfaceId = SurfaceId();
       
   339     }
       
   340 
       
   341 const TText *CRawSurface::GetSurfaceTypeStr() const
       
   342     {
       
   343     return _S("CRawSurface");
       
   344     }
       
   345 
       
   346 TInt CRawSurface::Notify(TNotification aWhen, TRequestStatus& aStatus, TUint32 aXTimes)
       
   347     {
       
   348     aStatus = KRequestPending;
       
   349     switch(aWhen)
       
   350         {
       
   351         case ENotifyWhenAvailable:
       
   352             iSurfaceUpdate.NotifyWhenAvailable(aStatus);
       
   353             break;
       
   354         case ENotifyWhenDisplayed:
       
   355             iSurfaceUpdate.NotifyWhenDisplayed(aStatus, iTimeStamp);
       
   356             break;
       
   357         case ENotifyWhenDispXTimes:
       
   358             iSurfaceUpdate.NotifyWhenDisplayedXTimes(aXTimes, aStatus);
       
   359             break;
       
   360         default:
       
   361             RDebug::Printf("%s:%d: Invalid notification: %d. Panicking...", __FILE__, __LINE__, aWhen);
       
   362             User::Panic(_L("CRawSurface::Notify()"), __LINE__);
       
   363             break;
       
   364         }
       
   365     return KErrNone;
       
   366     }
       
   367 
       
   368 
       
   369 TInt CRawSurface::WaitFor(TNotification aWhen, TRequestStatus& aStatus, TInt aTimeoutInMicroSeconds, TUint32& aTimeStamp)
       
   370     {
       
   371     RTimer timer;
       
   372     TInt err = timer.CreateLocal();
       
   373     if (err != KErrNone)
       
   374         {
       
   375         return err;
       
   376         }
       
   377     TRequestStatus timerStatus = KRequestPending;
       
   378 #if __WINS__
       
   379     // Windows timer isn't very precise - add some "fuzz" to the timeout to ensure we do not wait "too little".
       
   380     const TInt KTimeOutExtra = 20000;
       
   381 #else
       
   382     // On hardware, we should be able to run with less "fuzz".
       
   383     const TInt KTimeOutExtra = 10000;
       
   384 #endif
       
   385     timer.HighRes(timerStatus, aTimeoutInMicroSeconds + KTimeOutExtra);
       
   386     User::WaitForRequest(timerStatus, aStatus);
       
   387     if (aStatus == KRequestPending)
       
   388         {
       
   389         if (aWhen == ENotifyWhenDisplayed)
       
   390             {
       
   391             aTimeStamp = User::FastCounter();
       
   392             }
       
   393         return KErrTimedOut;
       
   394         }
       
   395     if (aWhen == ENotifyWhenDisplayed)
       
   396         {
       
   397         aTimeStamp = iTimeStamp();
       
   398         }
       
   399     timer.Cancel();
       
   400     timer.Close();
       
   401     TInt result = aStatus.Int();
       
   402     aStatus = KRequestPending;
       
   403     return result;
       
   404     }
       
   405 
       
   406 
       
   407 
       
   408 const TText *CRawSingleBufferSurface::GetSurfaceTypeStr() const
       
   409     {
       
   410     return _S("CRawSingleBufferedSurface");
       
   411     }
       
   412 
       
   413 CRawSingleBufferSurface *CRawSingleBufferSurface::NewL()
       
   414     {
       
   415     CRawSingleBufferSurface* obj = new (ELeave) CRawSingleBufferSurface();
       
   416     CleanupStack::PushL(obj);
       
   417     obj->ConstructL();
       
   418     CleanupStack::Pop(obj);
       
   419     return obj;
       
   420     }
       
   421 
       
   422 
       
   423 void CRawSingleBufferSurface::CreateL(TInt aIndex)
       
   424     {
       
   425     RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
       
   426 
       
   427     GetSurfAttribs(surfaceAttribs, aIndex);
       
   428 
       
   429     iBuffers = 1;
       
   430     surfaceAttribs().iBuffers = 1;
       
   431 
       
   432     TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
       
   433     User::LeaveIfError(err);
       
   434     }
       
   435 
       
   436 CRawSingleBufferSurface::~CRawSingleBufferSurface()
       
   437     {
       
   438     }
       
   439 
       
   440 class CWindow: public CBase
       
   441     {
       
   442 public:
       
   443     static CWindow *NewL(TInt aIndex);
       
   444     RWindow& Window();
       
   445     ~CWindow();
       
   446 private:
       
   447     void ConstructL(TInt aIndex);
       
   448     CWindow();
       
   449 
       
   450 private:
       
   451     RWindow iWindow;
       
   452     RWindowGroup iWindowGroup;
       
   453     RWsSession iWsSession;
       
   454     };
       
   455 
       
   456 
       
   457 CWindow* CWindow::NewL(TInt aIndex)
       
   458     {
       
   459     CWindow *self = new (ELeave) CWindow;
       
   460     CleanupStack::PushL(self);
       
   461     self->ConstructL(aIndex);
       
   462     CleanupStack::Pop(self);
       
   463     return self;
       
   464     }
       
   465 
       
   466 
       
   467 void CWindow::ConstructL(TInt aIndex)
       
   468     {
       
   469     RFbsSession::Connect();
       
   470     if (aIndex >= KSurfaceMaxIndex)
       
   471         {
       
   472         User::Leave(KErrOverflow);
       
   473         }
       
   474     User::LeaveIfError(iWsSession.Connect());
       
   475     iWindowGroup = RWindowGroup(iWsSession);
       
   476     User::LeaveIfError(iWindowGroup.Construct((TUint32)this));
       
   477     iWindow = RWindow(iWsSession);
       
   478     User::LeaveIfError(iWindow.Construct(iWindowGroup, -1U));
       
   479     const TSurfaceParamsCommon& winAttrib = KSurfaceParams[aIndex];
       
   480     iWindow.SetExtent(TPoint(winAttrib.iXPos, winAttrib.iYPos), TSize(winAttrib.iXSize, winAttrib.iYSize));
       
   481     iWindow.SetRequiredDisplayMode(winAttrib.iDisplayMode);
       
   482     iWindow.Activate();
       
   483     }
       
   484 
       
   485 
       
   486 CWindow::~CWindow()
       
   487     {
       
   488     iWindow.Close();
       
   489     iWindowGroup.Close();
       
   490     iWsSession.Close();
       
   491     RFbsSession::Disconnect();
       
   492     }
       
   493 
       
   494 
       
   495 CWindow::CWindow()
       
   496     {
       
   497     }
       
   498 
       
   499 
       
   500 RWindow& CWindow::Window()
       
   501     {
       
   502     return iWindow;
       
   503     }
       
   504 
       
   505 
       
   506 CEglWindowSurface* CEglWindowSurface::NewL()
       
   507     {
       
   508     CEglWindowSurface* self = new (ELeave) CEglWindowSurface;
       
   509     CleanupStack::PushL(self);
       
   510     self->ConstructL();
       
   511     CleanupStack::Pop(self);
       
   512     return self;
       
   513     }
       
   514 
       
   515 
       
   516 void CEglWindowSurface::ConstructL()
       
   517     {
       
   518     }
       
   519 
       
   520 
       
   521 CEglWindowSurface::CEglWindowSurface()
       
   522     {
       
   523     }
       
   524 
       
   525 
       
   526 void CEglWindowSurface::CreateL(TInt aIndex)
       
   527     {
       
   528     SURF_ASSERT(aIndex < KSurfaceMaxIndex);
       
   529     SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
       
   530     iParamIndex = aIndex;
       
   531     iWindow = CWindow::NewL(aIndex);
       
   532     iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
       
   533     EGLint err;
       
   534     if (iDisplay == EGL_NO_DISPLAY)
       
   535         {
       
   536         err = eglGetError();
       
   537         RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   538         User::Leave(KErrNotSupported);
       
   539         }
       
   540 
       
   541     EGLConfig config;
       
   542     EGLint nConfigs = 0;
       
   543 
       
   544     // TODO: Need to use differnet config attribs based on aIndex.
       
   545     static const EGLint KConfigAttribs[] =
       
   546     {
       
   547         EGL_BUFFER_SIZE,    32,
       
   548         EGL_RED_SIZE,       8,
       
   549         EGL_GREEN_SIZE,     8,
       
   550         EGL_BLUE_SIZE,      8,
       
   551         EGL_ALPHA_SIZE,     8,
       
   552         EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
       
   553         EGL_RENDERABLE_TYPE,EGL_OPENVG_BIT,
       
   554         EGL_NONE
       
   555     };
       
   556 
       
   557     // Need some way to configure the attribs ...
       
   558     eglChooseConfig(iDisplay, KConfigAttribs, &config, 1, &nConfigs);
       
   559     if (!nConfigs)
       
   560         {
       
   561         err = eglGetError();
       
   562         RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   563         User::Leave(KErrNotSupported);
       
   564         }
       
   565 
       
   566     if (!eglBindAPI(EGL_OPENVG_API))
       
   567         {
       
   568         err = eglGetError();
       
   569         RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   570         User::Leave(KErrNotSupported);
       
   571         }
       
   572     iContext = eglCreateContext(iDisplay, config, 0, NULL);
       
   573     if (iContext == EGL_NO_CONTEXT)
       
   574         {
       
   575         err = eglGetError();
       
   576         RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   577         User::Leave(KErrNotSupported);
       
   578         }
       
   579 
       
   580     iSurface = eglCreateWindowSurface(iDisplay, config, &iWindow->Window(), NULL);
       
   581     if (iSurface == EGL_NO_SURFACE)
       
   582         {
       
   583         err = eglGetError();
       
   584         RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
       
   585         User::Leave(KErrNotSupported);
       
   586         }
       
   587     }
       
   588 
       
   589 void CEglWindowSurface::SubmitContentL(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
       
   590     {
       
   591     ActivateL();
       
   592     if (!eglSwapBuffers(iDisplay, iSurface))
       
   593         {
       
   594         User::Leave(KErrBadHandle);
       
   595         }
       
   596     if (aShouldWaitForDisplay)
       
   597         {
       
   598         // We are cheating: We just wait for a bit to ensure that the swapbuffer is actually finished.
       
   599         // There is no way to determine how long this takes, so we just grab a number that should be
       
   600         // large enough...
       
   601         User::After(100 * 1000);  // Wait 100ms.
       
   602         }
       
   603     }
       
   604 
       
   605 void CEglWindowSurface::ActivateL()
       
   606     {
       
   607     if (!eglMakeCurrent(iDisplay, iSurface, iSurface, iContext))
       
   608         {
       
   609         User::Leave(KErrBadHandle);
       
   610         }
       
   611     }
       
   612 
       
   613 CEglWindowSurface::~CEglWindowSurface()
       
   614     {
       
   615     eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
       
   616     if (iSurface != EGL_NO_SURFACE)
       
   617         {
       
   618         eglDestroySurface(iDisplay, iSurface);
       
   619         iSurface = EGL_NO_SURFACE;
       
   620         }
       
   621 
       
   622     if (iDisplay != EGL_NO_DISPLAY)
       
   623         {
       
   624         eglDestroyContext(iDisplay, iContext);
       
   625         }
       
   626 
       
   627     delete iWindow;
       
   628     }
       
   629 
       
   630 TSurfaceId CEglWindowSurface::SurfaceId() const
       
   631     {
       
   632     // Default constructor for id sets it to a NULL-value, so if no window is created, we get
       
   633     // a defined surface id value that is invalid.
       
   634     TSurfaceId id;
       
   635     if (iWindow)
       
   636         {
       
   637         TSurfaceConfiguration surfConfig;
       
   638         iWindow->Window().GetBackgroundSurface(surfConfig);
       
   639         surfConfig.GetSurfaceId(id);
       
   640         }
       
   641     return id;
       
   642     }
       
   643 
       
   644 
       
   645 void CEglWindowSurface::DrawContentL(const TRgb& aColour)
       
   646     {
       
   647     ActivateL();
       
   648 
       
   649     TSize size;
       
   650     eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth);
       
   651     eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight);
       
   652 
       
   653     VGfloat fillColour[4];
       
   654     fillColour[0] = (VGfloat)aColour.Red() / 255.0f;
       
   655     fillColour[1] = (VGfloat)aColour.Green() / 255.0f;
       
   656     fillColour[2] = (VGfloat)aColour.Blue() / 255.0f;
       
   657     fillColour[3] = (VGfloat)aColour.Alpha() / 255.0f;
       
   658 
       
   659     vgSetfv(VG_CLEAR_COLOR, 4, fillColour);
       
   660     vgClear(0, 0, size.iWidth, size.iHeight);
       
   661     }
       
   662 
       
   663 
       
   664 void CEglWindowSurface::DrawContentL(TInt aIndex)
       
   665     {
       
   666     ActivateL();
       
   667     CTestVgImage *vgImage = CTestVgImage::NewL(aIndex);
       
   668     CleanupStack::PushL(vgImage);
       
   669     vgDrawImage(vgImage->VGImage());
       
   670     CleanupStack::PopAndDestroy(vgImage);
       
   671     }
       
   672 
       
   673 void CEglWindowSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
       
   674     {
       
   675     RSurfaceManager surfaceManager;
       
   676     User::LeaveIfError(surfaceManager.Open());
       
   677     RSurfaceManager::TInfoBuf infoBuf;
       
   678     TInt err = surfaceManager.SurfaceInfo(SurfaceId(), infoBuf);
       
   679     User::LeaveIfError(err);
       
   680     surfaceManager.Close();
       
   681     RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   682     aParams.iSurfaceId = SurfaceId();
       
   683     aParams.iCommonParams.iAlignment = -1;  // N/A
       
   684     aParams.iCommonParams.iBuffers = info.iBuffers;
       
   685     aParams.iCommonParams.iOffsetToFirstBuffer = -1;
       
   686     aParams.iCommonParams.iPixelFormat = info.iPixelFormat;
       
   687     aParams.iCommonParams.iStrideInBytes = info.iStride;
       
   688     aParams.iCommonParams.iXSize = info.iSize.iWidth;
       
   689     aParams.iCommonParams.iYSize = info.iSize.iHeight;
       
   690     aParams.iCommonParams.iUseAttribList = KSurfaceParams[iParamIndex].iUseAttribList;
       
   691     for(TInt i = 0; i < KNumAttribs; i++)
       
   692         {
       
   693         aParams.iCommonParams.iAttribs[i] = KSurfaceParams[iParamIndex].iAttribs[i];
       
   694         }
       
   695     }
       
   696 
       
   697 const TText *CEglWindowSurface::GetSurfaceTypeStr() const
       
   698     {
       
   699     return _S("CEglWindowSurface");
       
   700     }
       
   701 
       
   702 TInt CEglWindowSurface::Notify(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, TUint32 /*aXTImes*/)
       
   703     {
       
   704     return KErrNotSupported;
       
   705     }
       
   706 
       
   707 TInt CEglWindowSurface::WaitFor(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/,
       
   708         TInt /*aTimeoutinMicroseconds*/, TUint32 & /*aTimeStamp*/)
       
   709     {
       
   710     return KErrNotSupported;
       
   711     }
       
   712 
       
   713 
       
   714 // Factory function.
       
   715 CSurface *CSurface::SurfaceFactoryL(TSurfaceType aSurfaceType)
       
   716     {
       
   717     switch(aSurfaceType)
       
   718         {
       
   719         case ESurfTypeRaw:
       
   720             return CRawSurface::NewL();
       
   721         case ESurfTypeEglWindow:
       
   722             return CEglWindowSurface::NewL();
       
   723         case ESurfTypeRawSingleBuffered:
       
   724             return CRawSingleBufferSurface::NewL();
       
   725         default:
       
   726             SURF_ASSERT(0);
       
   727             return NULL;
       
   728         }
       
   729     }
       
   730