egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp
changeset 98 bf7481649c98
child 136 62bb7c97884c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp	Fri Jun 11 14:58:47 2010 +0300
@@ -0,0 +1,730 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+
+#include "egltest_surface.h"
+#include "egltest_endpoint_images.h"
+#include <graphics/surfaceconfiguration.h>
+
+#define SURF_ASSERT(x) { if (!(x)) { RDebug::Printf("ASSERT(%s) failed at %s:%d", #x, __FILE__, __LINE__); User::Panic(_L("ASSERT SURF"), __LINE__); }}
+
+// Macros for indicating what is what.
+#define SIZE(x, y) x, y
+#define Buffers(x) x
+#define DefaultAlignment 32  // Pick some value that is valid.
+#define Alignment(x) x
+#define Stride(x) x
+#define DefaultStride 0
+// Note: Offset to first buffer.
+#define Offset(x) x
+#define WindowPos(x, y)  x, y
+#define WindowMode(m) m
+
+static const TSurfaceParamsCommon KSurfaceParams[] =
+{
+    {
+        EStandardSurface,
+        SIZE(100, 100),
+        Buffers(2),
+        DefaultAlignment,
+        DefaultStride,
+        Offset(0),
+        EUidPixelFormatARGB_8888_PRE,
+        EFalse,
+        { 0 },
+        WindowPos(0, 0),
+        WindowMode(EColor16MAP)
+    },
+    {
+        EBadAttribSurface,
+        SIZE(100, 100),
+        Buffers(2),
+        DefaultAlignment,
+        DefaultStride,
+        Offset(0),
+        EUidPixelFormatARGB_8888_PRE,
+        ETrue,
+        { 1, 1, EGL_NONE },
+        WindowPos(0, 0),
+        WindowMode(EColor16MAP)
+    },
+    {
+        EEmptyAttribSurface,
+        SIZE(100, 100),
+        Buffers(2),
+        DefaultAlignment,
+        DefaultStride,
+        Offset(0),
+        EUidPixelFormatARGB_8888_PRE,
+        ETrue,
+        { EGL_NONE },
+        WindowPos(0, 0),
+        WindowMode(EColor16MAP)
+    },
+    {
+        EStandard128sqSurface,
+        SIZE(128, 128),
+        Buffers(3),
+        DefaultAlignment,
+        DefaultStride,
+        Offset(0),
+        EUidPixelFormatARGB_8888_PRE,
+        EFalse,
+        { 0 },
+        WindowPos(20, 20),
+        WindowMode(EColor16MAP)
+    },
+    {
+        EUnusualStrideSurface,
+        SIZE(167,263),
+        Buffers(2),
+        Alignment(8),
+        Stride(167*4+64),
+        Offset(200),
+        EUidPixelFormatARGB_8888_PRE,
+        EFalse,
+        { 0 },
+        WindowPos(0, 0),
+        WindowMode(EColor16MAP)
+    },
+    {
+        EUnalignedPixelSizeSurface,
+        SIZE(103, 107),
+        Buffers(2),
+        Alignment(8),
+        Stride(103*4),
+        Offset(0),
+        EUidPixelFormatARGB_8888_PRE,
+        EFalse,
+        { 0 },
+        WindowPos(0, 0),
+        WindowMode(EColor16MAP)
+    },
+    {
+        ELargeSurface,
+        SIZE(800, 600),
+        Buffers(2),
+        DefaultAlignment,
+        DefaultStride,
+        Offset(0),
+        EUidPixelFormatARGB_8888_PRE,
+        EFalse,
+        { 0 },
+        WindowPos(0, 0),
+        WindowMode(EColor16MAP)
+    },
+};
+
+
+TInt KSurfaceMaxIndex = sizeof(KSurfaceParams) / sizeof(KSurfaceParams[0]);
+
+CRawSurface* CRawSurface::NewL()
+    {
+    CRawSurface* obj = new (ELeave) CRawSurface();
+    CleanupStack::PushL(obj);
+    obj->ConstructL();
+    CleanupStack::Pop(obj);
+    return obj;
+    }
+
+
+CRawSurface::CRawSurface() : iDrawBuffer(0), iBuffers(0)
+    {
+    }
+
+
+void CRawSurface::ConstructL()
+    {
+    iSurfaceId = TSurfaceId::CreateNullId();
+    User::LeaveIfError(iSurfaceManager.Open());
+    User::LeaveIfError(iSurfaceUpdate.Connect(5));
+    }
+
+
+CRawSurface::~CRawSurface()
+    {
+    iSurfaceUpdate.Close();
+    if(!iSurfaceId.IsNull())
+        {
+        iSurfaceManager.CloseSurface(iSurfaceId);
+        }
+    iSurfaceManager.Close();
+    }
+
+
+TInt CRawSurface::PixelSize(TUidPixelFormat aPixelFormat)
+    {
+    switch(aPixelFormat)
+        {
+        case EUidPixelFormatARGB_8888_PRE:
+        case EUidPixelFormatARGB_8888:
+        case EUidPixelFormatABGR_8888:
+        case EUidPixelFormatABGR_8888_PRE:
+            return 4;
+
+        case EUidPixelFormatARGB_4444:
+        case EUidPixelFormatRGB_565:
+            return 2;
+
+        default:
+            SURF_ASSERT(0);
+            break;
+        }
+    return 0; // Make sure no compiler moans about "not all paths return a value".
+    }
+
+
+void CRawSurface::GetSurfAttribs(RSurfaceManager::TSurfaceCreationAttributesBuf &aSurfaceAttribs, TInt aIndex)
+    {
+    SURF_ASSERT(aIndex < KSurfaceMaxIndex);
+    SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
+    iParamIndex = aIndex;
+    aSurfaceAttribs().iSize = TSize(KSurfaceParams[aIndex].iXSize, KSurfaceParams[aIndex].iYSize);
+    iBuffers = KSurfaceParams[aIndex].iBuffers;
+    aSurfaceAttribs().iBuffers = iBuffers;
+    aSurfaceAttribs().iPixelFormat = KSurfaceParams[aIndex].iPixelFormat;
+    TInt stride = KSurfaceParams[aIndex].iStrideInBytes;
+    if (stride == 0)
+        {
+        stride = KSurfaceParams[aIndex].iXSize * PixelSize(KSurfaceParams[aIndex].iPixelFormat);
+        }
+    aSurfaceAttribs().iStride = stride;
+    aSurfaceAttribs().iOffsetToFirstBuffer = KSurfaceParams[aIndex].iOffsetToFirstBuffer;
+    aSurfaceAttribs().iAlignment = KSurfaceParams[aIndex].iAlignment;
+    aSurfaceAttribs().iContiguous = EFalse;
+    aSurfaceAttribs().iCacheAttrib = RSurfaceManager::ECached;
+    aSurfaceAttribs().iOffsetBetweenBuffers = 0;
+    aSurfaceAttribs().iSurfaceHints = NULL;
+    aSurfaceAttribs().iHintCount = 0;
+    aSurfaceAttribs().iMappable = ETrue;
+    }
+
+
+//From CSurface.
+void CRawSurface::CreateL(TInt aIndex)
+    {
+    RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
+
+    GetSurfAttribs(surfaceAttribs, aIndex);
+    TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
+    User::LeaveIfError(err);
+    }
+
+
+TUint8* CRawSurface::MapSurfaceAndGetInfoLC(RSurfaceManager::TSurfaceInfoV01& aInfo)
+    {
+    SURF_ASSERT(!iSurfaceId.IsNull());
+    User::LeaveIfError(iSurfaceManager.MapSurface(iSurfaceId, iSurfaceChunk));
+    CleanupClosePushL(iSurfaceChunk);
+    RSurfaceManager::TInfoBuf infoBuf;
+    User::LeaveIfError(iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf));
+    aInfo = infoBuf();
+    TInt offset = -1000;  // So we hopefully detect when it goes horribly wrong.
+    User::LeaveIfError(iSurfaceManager.GetBufferOffset(iSurfaceId, iDrawBuffer, offset));
+    return iSurfaceChunk.Base() + offset;
+    }
+
+
+void CRawSurface::DrawContentL(TInt aImageIndex)
+    {
+    CTestCFbsImage *image = CTestCFbsImage::NewL(aImageIndex);
+    CleanupStack::PushL(image);
+
+    RSurfaceManager::TSurfaceInfoV01 info;
+    TUint8 *dataAddress = MapSurfaceAndGetInfoLC(info);
+    TInt stride = info.iStride;
+
+    CFbsBitmap *bitmap = image->Bitmap();
+    TDisplayMode displaymode = bitmap->DisplayMode();
+    TInt pixelStride = stride / CFbsBitmap::ScanLineLength(1, displaymode);
+    for(TInt y = 0; y < image->Size().iHeight; y++)
+        {
+        TPtr8 buf(dataAddress + y * stride, stride);
+
+        // TODO: We need to check that the bitsperpixel matches between the surface and bitmap.
+        bitmap->GetScanLine(buf, TPoint(0, y), pixelStride, displaymode);
+        }
+
+    CleanupStack::PopAndDestroy(2, image);
+    }
+
+
+void CRawSurface::DrawContentL(const TRgb& aColour)
+    {
+    //Map the surface and get its info.
+    RSurfaceManager::TSurfaceInfoV01 surfaceInfo;
+    TUint32* buffer = (TUint32*)MapSurfaceAndGetInfoLC(surfaceInfo);
+
+    //Currently this function only supports drawing into ARGB_8888_PRE surfaces.
+    //This is because the only test that uses this function uses this type of surface.
+    //If this functionallity needs expanding, you must correctly convert the TRgb colour
+    //and pack it into the surface buffer correctly.
+    SURF_ASSERT(surfaceInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE);
+
+    TUint32 fillColour = aColour._Color16MAP();
+
+    //Loop over each pixel in the surface and colour it.
+    //This is deliberately slow since it is only used for the tearing test
+    //and we want to spend most of our time drawing so that the chances of the other thread
+    //picking up a buffer in the middle of drawing is increased.
+    for(TInt y=0; y < surfaceInfo.iSize.iHeight; ++y)
+        {
+        for(TInt x=0; x < surfaceInfo.iSize.iWidth; ++x)
+            {
+            buffer[x] = fillColour;
+            }
+        buffer += surfaceInfo.iStride >> 2;
+        }
+
+    CleanupStack::PopAndDestroy();
+    }
+
+
+void CRawSurface::SubmitContentL(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
+    {
+    TRequestStatus displayNotify = KRequestPending;
+    TTimeStamp timeStamp;
+
+    if(aShouldWaitForDisplay)
+        {
+        Notify(ENotifyWhenDisplayed, displayNotify, 0);
+        }
+
+    TInt err = iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceId, iDrawBuffer, NULL);
+    User::LeaveIfError(err);
+    iDrawBuffer = (iDrawBuffer + 1) % iBuffers;
+
+    if(aShouldWaitForDisplay)
+        {
+        TUint32 dummy;
+        TInt err = WaitFor(ENotifyWhenDisplayed, displayNotify, 100 * 1000, dummy);
+        if (err != KErrNone && err != KErrNotVisible && err != KErrOverflow)
+            {
+            RDebug::Printf("%s:%d: NotifyWhenDisplayed gave unexpected error %d", __FILE__, __LINE__, err);
+            User::Leave(err);
+            }
+        }
+    }
+
+
+TSurfaceId CRawSurface::SurfaceId() const
+    {
+    return iSurfaceId;
+    }
+
+
+void CRawSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
+    {
+    aParams.iCommonParams = KSurfaceParams[iParamIndex];
+    aParams.iCommonParams.iBuffers = iBuffers; // May have been changed if it's a single buffered surface...
+    aParams.iSurfaceId = SurfaceId();
+    }
+
+const TText *CRawSurface::GetSurfaceTypeStr() const
+    {
+    return _S("CRawSurface");
+    }
+
+TInt CRawSurface::Notify(TNotification aWhen, TRequestStatus& aStatus, TUint32 aXTimes)
+    {
+    aStatus = KRequestPending;
+    switch(aWhen)
+        {
+        case ENotifyWhenAvailable:
+            iSurfaceUpdate.NotifyWhenAvailable(aStatus);
+            break;
+        case ENotifyWhenDisplayed:
+            iSurfaceUpdate.NotifyWhenDisplayed(aStatus, iTimeStamp);
+            break;
+        case ENotifyWhenDispXTimes:
+            iSurfaceUpdate.NotifyWhenDisplayedXTimes(aXTimes, aStatus);
+            break;
+        default:
+            RDebug::Printf("%s:%d: Invalid notification: %d. Panicking...", __FILE__, __LINE__, aWhen);
+            User::Panic(_L("CRawSurface::Notify()"), __LINE__);
+            break;
+        }
+    return KErrNone;
+    }
+
+
+TInt CRawSurface::WaitFor(TNotification aWhen, TRequestStatus& aStatus, TInt aTimeoutInMicroSeconds, TUint32& aTimeStamp)
+    {
+    RTimer timer;
+    TInt err = timer.CreateLocal();
+    if (err != KErrNone)
+        {
+        return err;
+        }
+    TRequestStatus timerStatus = KRequestPending;
+#if __WINS__
+    // Windows timer isn't very precise - add some "fuzz" to the timeout to ensure we do not wait "too little".
+    const TInt KTimeOutExtra = 20000;
+#else
+    // On hardware, we should be able to run with less "fuzz".
+    const TInt KTimeOutExtra = 10000;
+#endif
+    timer.HighRes(timerStatus, aTimeoutInMicroSeconds + KTimeOutExtra);
+    User::WaitForRequest(timerStatus, aStatus);
+    if (aStatus == KRequestPending)
+        {
+        if (aWhen == ENotifyWhenDisplayed)
+            {
+            aTimeStamp = User::FastCounter();
+            }
+        return KErrTimedOut;
+        }
+    if (aWhen == ENotifyWhenDisplayed)
+        {
+        aTimeStamp = iTimeStamp();
+        }
+    timer.Cancel();
+    timer.Close();
+    TInt result = aStatus.Int();
+    aStatus = KRequestPending;
+    return result;
+    }
+
+
+
+const TText *CRawSingleBufferSurface::GetSurfaceTypeStr() const
+    {
+    return _S("CRawSingleBufferedSurface");
+    }
+
+CRawSingleBufferSurface *CRawSingleBufferSurface::NewL()
+    {
+    CRawSingleBufferSurface* obj = new (ELeave) CRawSingleBufferSurface();
+    CleanupStack::PushL(obj);
+    obj->ConstructL();
+    CleanupStack::Pop(obj);
+    return obj;
+    }
+
+
+void CRawSingleBufferSurface::CreateL(TInt aIndex)
+    {
+    RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs;
+
+    GetSurfAttribs(surfaceAttribs, aIndex);
+
+    iBuffers = 1;
+    surfaceAttribs().iBuffers = 1;
+
+    TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId);
+    User::LeaveIfError(err);
+    }
+
+CRawSingleBufferSurface::~CRawSingleBufferSurface()
+    {
+    }
+
+class CWindow: public CBase
+    {
+public:
+    static CWindow *NewL(TInt aIndex);
+    RWindow& Window();
+    ~CWindow();
+private:
+    void ConstructL(TInt aIndex);
+    CWindow();
+
+private:
+    RWindow iWindow;
+    RWindowGroup iWindowGroup;
+    RWsSession iWsSession;
+    };
+
+
+CWindow* CWindow::NewL(TInt aIndex)
+    {
+    CWindow *self = new (ELeave) CWindow;
+    CleanupStack::PushL(self);
+    self->ConstructL(aIndex);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+
+void CWindow::ConstructL(TInt aIndex)
+    {
+    RFbsSession::Connect();
+    if (aIndex >= KSurfaceMaxIndex)
+        {
+        User::Leave(KErrOverflow);
+        }
+    User::LeaveIfError(iWsSession.Connect());
+    iWindowGroup = RWindowGroup(iWsSession);
+    User::LeaveIfError(iWindowGroup.Construct((TUint32)this));
+    iWindow = RWindow(iWsSession);
+    User::LeaveIfError(iWindow.Construct(iWindowGroup, -1U));
+    const TSurfaceParamsCommon& winAttrib = KSurfaceParams[aIndex];
+    iWindow.SetExtent(TPoint(winAttrib.iXPos, winAttrib.iYPos), TSize(winAttrib.iXSize, winAttrib.iYSize));
+    iWindow.SetRequiredDisplayMode(winAttrib.iDisplayMode);
+    iWindow.Activate();
+    }
+
+
+CWindow::~CWindow()
+    {
+    iWindow.Close();
+    iWindowGroup.Close();
+    iWsSession.Close();
+    RFbsSession::Disconnect();
+    }
+
+
+CWindow::CWindow()
+    {
+    }
+
+
+RWindow& CWindow::Window()
+    {
+    return iWindow;
+    }
+
+
+CEglWindowSurface* CEglWindowSurface::NewL()
+    {
+    CEglWindowSurface* self = new (ELeave) CEglWindowSurface;
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+
+void CEglWindowSurface::ConstructL()
+    {
+    }
+
+
+CEglWindowSurface::CEglWindowSurface()
+    {
+    }
+
+
+void CEglWindowSurface::CreateL(TInt aIndex)
+    {
+    SURF_ASSERT(aIndex < KSurfaceMaxIndex);
+    SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex);
+    iParamIndex = aIndex;
+    iWindow = CWindow::NewL(aIndex);
+    iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    EGLint err;
+    if (iDisplay == EGL_NO_DISPLAY)
+        {
+        err = eglGetError();
+        RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
+        User::Leave(KErrNotSupported);
+        }
+
+    EGLConfig config;
+    EGLint nConfigs = 0;
+
+    // TODO: Need to use differnet config attribs based on aIndex.
+    static const EGLint KConfigAttribs[] =
+    {
+        EGL_BUFFER_SIZE,    32,
+        EGL_RED_SIZE,       8,
+        EGL_GREEN_SIZE,     8,
+        EGL_BLUE_SIZE,      8,
+        EGL_ALPHA_SIZE,     8,
+        EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE,EGL_OPENVG_BIT,
+        EGL_NONE
+    };
+
+    // Need some way to configure the attribs ...
+    eglChooseConfig(iDisplay, KConfigAttribs, &config, 1, &nConfigs);
+    if (!nConfigs)
+        {
+        err = eglGetError();
+        RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
+        User::Leave(KErrNotSupported);
+        }
+
+    if (!eglBindAPI(EGL_OPENVG_API))
+        {
+        err = eglGetError();
+        RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
+        User::Leave(KErrNotSupported);
+        }
+    iContext = eglCreateContext(iDisplay, config, 0, NULL);
+    if (iContext == EGL_NO_CONTEXT)
+        {
+        err = eglGetError();
+        RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
+        User::Leave(KErrNotSupported);
+        }
+
+    iSurface = eglCreateWindowSurface(iDisplay, config, &iWindow->Window(), NULL);
+    if (iSurface == EGL_NO_SURFACE)
+        {
+        err = eglGetError();
+        RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err);
+        User::Leave(KErrNotSupported);
+        }
+    }
+
+void CEglWindowSurface::SubmitContentL(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */)
+    {
+    ActivateL();
+    if (!eglSwapBuffers(iDisplay, iSurface))
+        {
+        User::Leave(KErrBadHandle);
+        }
+    if (aShouldWaitForDisplay)
+        {
+        // We are cheating: We just wait for a bit to ensure that the swapbuffer is actually finished.
+        // There is no way to determine how long this takes, so we just grab a number that should be
+        // large enough...
+        User::After(100 * 1000);  // Wait 100ms.
+        }
+    }
+
+void CEglWindowSurface::ActivateL()
+    {
+    if (!eglMakeCurrent(iDisplay, iSurface, iSurface, iContext))
+        {
+        User::Leave(KErrBadHandle);
+        }
+    }
+
+CEglWindowSurface::~CEglWindowSurface()
+    {
+    eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    if (iSurface != EGL_NO_SURFACE)
+        {
+        eglDestroySurface(iDisplay, iSurface);
+        iSurface = EGL_NO_SURFACE;
+        }
+
+    if (iDisplay != EGL_NO_DISPLAY)
+        {
+        eglDestroyContext(iDisplay, iContext);
+        }
+
+    delete iWindow;
+    }
+
+TSurfaceId CEglWindowSurface::SurfaceId() const
+    {
+    // Default constructor for id sets it to a NULL-value, so if no window is created, we get
+    // a defined surface id value that is invalid.
+    TSurfaceId id;
+    if (iWindow)
+        {
+        TSurfaceConfiguration surfConfig;
+        iWindow->Window().GetBackgroundSurface(surfConfig);
+        surfConfig.GetSurfaceId(id);
+        }
+    return id;
+    }
+
+
+void CEglWindowSurface::DrawContentL(const TRgb& aColour)
+    {
+    ActivateL();
+
+    TSize size;
+    eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth);
+    eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight);
+
+    VGfloat fillColour[4];
+    fillColour[0] = (VGfloat)aColour.Red() / 255.0f;
+    fillColour[1] = (VGfloat)aColour.Green() / 255.0f;
+    fillColour[2] = (VGfloat)aColour.Blue() / 255.0f;
+    fillColour[3] = (VGfloat)aColour.Alpha() / 255.0f;
+
+    vgSetfv(VG_CLEAR_COLOR, 4, fillColour);
+    vgClear(0, 0, size.iWidth, size.iHeight);
+    }
+
+
+void CEglWindowSurface::DrawContentL(TInt aIndex)
+    {
+    ActivateL();
+    CTestVgImage *vgImage = CTestVgImage::NewL(aIndex);
+    CleanupStack::PushL(vgImage);
+    vgDrawImage(vgImage->VGImage());
+    CleanupStack::PopAndDestroy(vgImage);
+    }
+
+void CEglWindowSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams)
+    {
+    RSurfaceManager surfaceManager;
+    User::LeaveIfError(surfaceManager.Open());
+    RSurfaceManager::TInfoBuf infoBuf;
+    TInt err = surfaceManager.SurfaceInfo(SurfaceId(), infoBuf);
+    User::LeaveIfError(err);
+    surfaceManager.Close();
+    RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
+    aParams.iSurfaceId = SurfaceId();
+    aParams.iCommonParams.iAlignment = -1;  // N/A
+    aParams.iCommonParams.iBuffers = info.iBuffers;
+    aParams.iCommonParams.iOffsetToFirstBuffer = -1;
+    aParams.iCommonParams.iPixelFormat = info.iPixelFormat;
+    aParams.iCommonParams.iStrideInBytes = info.iStride;
+    aParams.iCommonParams.iXSize = info.iSize.iWidth;
+    aParams.iCommonParams.iYSize = info.iSize.iHeight;
+    aParams.iCommonParams.iUseAttribList = KSurfaceParams[iParamIndex].iUseAttribList;
+    for(TInt i = 0; i < KNumAttribs; i++)
+        {
+        aParams.iCommonParams.iAttribs[i] = KSurfaceParams[iParamIndex].iAttribs[i];
+        }
+    }
+
+const TText *CEglWindowSurface::GetSurfaceTypeStr() const
+    {
+    return _S("CEglWindowSurface");
+    }
+
+TInt CEglWindowSurface::Notify(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, TUint32 /*aXTImes*/)
+    {
+    return KErrNotSupported;
+    }
+
+TInt CEglWindowSurface::WaitFor(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/,
+        TInt /*aTimeoutinMicroseconds*/, TUint32 & /*aTimeStamp*/)
+    {
+    return KErrNotSupported;
+    }
+
+
+// Factory function.
+CSurface *CSurface::SurfaceFactoryL(TSurfaceType aSurfaceType)
+    {
+    switch(aSurfaceType)
+        {
+        case ESurfTypeRaw:
+            return CRawSurface::NewL();
+        case ESurfTypeEglWindow:
+            return CEglWindowSurface::NewL();
+        case ESurfTypeRawSingleBuffered:
+            return CRawSingleBufferSurface::NewL();
+        default:
+            SURF_ASSERT(0);
+            return NULL;
+        }
+    }
+