diff -r d72fc2aace31 -r 62bb7c97884c egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp --- a/egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp Tue Jul 20 13:27:44 2010 +0300 +++ b/egl/egltest/endpointtestsuite/automated/tsrc/egltest_surface.cpp Fri Jul 30 11:41:40 2010 +0300 @@ -23,6 +23,10 @@ #include "egltest_surface.h" #include "egltest_endpoint_images.h" #include +#include +#include +#include + #define SURF_ASSERT(x) { if (!(x)) { RDebug::Printf("ASSERT(%s) failed at %s:%d", #x, __FILE__, __LINE__); User::Panic(_L("ASSERT SURF"), __LINE__); }} @@ -38,6 +42,8 @@ #define WindowPos(x, y) x, y #define WindowMode(m) m +#define LARGEST_POSSIBLE_FLAG 0x80000000 + static const TSurfaceParamsCommon KSurfaceParams[] = { { @@ -131,10 +137,123 @@ WindowPos(0, 0), WindowMode(EColor16MAP) }, + { + ELargestPossibleSurface, + SIZE(LARGEST_POSSIBLE_FLAG, LARGEST_POSSIBLE_FLAG), + Buffers(2), + DefaultAlignment, + DefaultStride, + Offset(0), + EUidPixelFormatARGB_8888_PRE, + EFalse, + { 0 }, + WindowPos(0, 0), + WindowMode(EColor16MAP) + }, + { + ESmallSurface, + SIZE(16, 16), + Buffers(1), + DefaultAlignment, + DefaultStride, + Offset(0), + EUidPixelFormatARGB_8888_PRE, + EFalse, + { 0 }, + WindowPos(0, 0), + WindowMode(EColor16MAP) + }, + { + ETinySurface, + SIZE(8, 8), + Buffers(1), + DefaultAlignment, + DefaultStride, + Offset(0), + EUidPixelFormatARGB_8888_PRE, + EFalse, + { 0 }, + WindowPos(0, 0), + WindowMode(EColor16MAP) + }, }; +const TInt KSurfaceMaxIndex = sizeof(KSurfaceParams) / sizeof(KSurfaceParams[0]); -TInt KSurfaceMaxIndex = sizeof(KSurfaceParams) / sizeof(KSurfaceParams[0]); +struct TSurfaceSize + { + TInt iWidth; + TInt iHeight; + }; + +static const TSurfaceSize KSurfaceSizes[] = + { + { 320, 240 }, + { 640, 480 }, + { 720, 480 }, + { 854, 480 }, + { 720, 576 }, + { 854, 576 }, + { 1280, 720 }, + { 1024, 768 }, + { 1280, 1024 }, + { 1920, 1080 }, + { 1600, 1200 }, +#if 0 + { 2048, 1536 }, + { 2560, 1920 }, + { 3648, 2736 }, + { 4216, 2638 }, + { 4000, 3000 }, + { 4616, 2600 }, +#endif + }; + +const TInt KMaxSurfaceSizes = sizeof(KSurfaceSizes) / sizeof(KSurfaceSizes[0]); + +LOCAL_C TUint RandomNumberInRange(TUint aLow, TUint aHigh) + { + TReal32 rand = Math::Random(); + rand /= KMaxTUint; + rand *= aHigh - aLow; + rand += aLow; + return TUint(rand); + } + + +void CSurface::CreateL(TInt aIndex) + { + CreateL(aIndex, TPoint(0, 0)); + } + + +TSize CSurface::Size() + { + return iActualSize; + } + + +TInt CSurface::SizeInBytes() const + { + RSurfaceManager::TInfoBuf infoBuf; + RSurfaceManager surfMgr; + TInt err = surfMgr.Open(); + if (err != KErrNone) + { + RDebug::Printf("Error opening surface manager... Err=%d", err); + return 0; + } + err = surfMgr.SurfaceInfo(SurfaceId(), infoBuf); + if (err != KErrNone) + { + RDebug::Printf("Could not get surface info - err = %d", err); + return 0; + } + TInt size = infoBuf().iBuffers * infoBuf().iSize.iHeight * infoBuf().iStride; + surfMgr.Close(); + return size; + } + CRawSurface* CRawSurface::NewL() { @@ -146,6 +265,7 @@ } + CRawSurface::CRawSurface() : iDrawBuffer(0), iBuffers(0) { } @@ -155,7 +275,7 @@ { iSurfaceId = TSurfaceId::CreateNullId(); User::LeaveIfError(iSurfaceManager.Open()); - User::LeaveIfError(iSurfaceUpdate.Connect(5)); + User::LeaveIfError(iSurfaceUpdate.Connect()); } @@ -192,19 +312,30 @@ } -void CRawSurface::GetSurfAttribs(RSurfaceManager::TSurfaceCreationAttributesBuf &aSurfaceAttribs, TInt aIndex) +void CRawSurface::GetSurfAttribs(RSurfaceManager::TSurfaceCreationAttributesBuf &aSurfaceAttribs, + TInt aIndex, TInt aSizeIndex) { SURF_ASSERT(aIndex < KSurfaceMaxIndex); SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex); iParamIndex = aIndex; - aSurfaceAttribs().iSize = TSize(KSurfaceParams[aIndex].iXSize, KSurfaceParams[aIndex].iYSize); + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG) + { + + aSurfaceAttribs().iSize = + TSize(KSurfaceSizes[aSizeIndex].iWidth, KSurfaceSizes[aSizeIndex].iHeight); + } + else + { + 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); + stride = aSurfaceAttribs().iSize.iWidth * PixelSize(KSurfaceParams[aIndex].iPixelFormat); } aSurfaceAttribs().iStride = stride; aSurfaceAttribs().iOffsetToFirstBuffer = KSurfaceParams[aIndex].iOffsetToFirstBuffer; @@ -218,13 +349,25 @@ } -//From CSurface. -void CRawSurface::CreateL(TInt aIndex) +void CRawSurface::CreateL(TInt aIndex, const TPoint &/* aPoint */) { RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs; - - GetSurfAttribs(surfaceAttribs, aIndex); - TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId); + SURF_ASSERT(aIndex < KSurfaceMaxIndex); + TInt sizeIndex = 0; + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG) + { + sizeIndex = KMaxSurfaceSizes-1; + + } + TInt err = KErrNone; + do + { + GetSurfAttribs(surfaceAttribs, aIndex, sizeIndex); + err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId); + iActualSize = surfaceAttribs().iSize; + sizeIndex--; + } + while(err != KErrNone && sizeIndex >= 0); User::LeaveIfError(err); } @@ -239,6 +382,7 @@ aInfo = infoBuf(); TInt offset = -1000; // So we hopefully detect when it goes horribly wrong. User::LeaveIfError(iSurfaceManager.GetBufferOffset(iSurfaceId, iDrawBuffer, offset)); + SURF_ASSERT(offset >= 0); return iSurfaceChunk.Base() + offset; } @@ -266,7 +410,6 @@ CleanupStack::PopAndDestroy(2, image); } - void CRawSurface::DrawContentL(const TRgb& aColour) { //Map the surface and get its info. @@ -298,7 +441,13 @@ } -void CRawSurface::SubmitContentL(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */) +void CRawSurface::DrawComplexL(const TRgb& aColour) + { + DrawContentL(aColour); + } + + +TInt CRawSurface::SubmitContent(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */) { TRequestStatus displayNotify = KRequestPending; TTimeStamp timeStamp; @@ -309,19 +458,27 @@ } TInt err = iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceId, iDrawBuffer, NULL); - User::LeaveIfError(err); + if (err != KErrNone) + { + if (err != KErrNone) + { + RDebug::Printf("%s:%d: SubmitUpdate gave unexpected error %d", __FILE__, __LINE__, err); + } + return err; + } iDrawBuffer = (iDrawBuffer + 1) % iBuffers; if(aShouldWaitForDisplay) { TUint32 dummy; - TInt err = WaitFor(ENotifyWhenDisplayed, displayNotify, 100 * 1000, dummy); + 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); +// RDebug::Printf("%s:%d: NotifyWhenDisplayed gave unexpected error %d", __FILE__, __LINE__, err); + return err; } } + return KErrNone; } @@ -372,6 +529,7 @@ TInt err = timer.CreateLocal(); if (err != KErrNone) { + RDebug::Printf("%s:%d: Could not create timer... err= %d", __FILE__, __LINE__, err); return err; } TRequestStatus timerStatus = KRequestPending; @@ -403,8 +561,6 @@ return result; } - - const TText *CRawSingleBufferSurface::GetSurfaceTypeStr() const { return _S("CRawSingleBufferedSurface"); @@ -420,31 +576,283 @@ } -void CRawSingleBufferSurface::CreateL(TInt aIndex) +void CRawSingleBufferSurface::CreateL(TInt aIndex, const TPoint & /*aPoint */) { RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs; - GetSurfAttribs(surfaceAttribs, aIndex); - - iBuffers = 1; - surfaceAttribs().iBuffers = 1; - - TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId); - User::LeaveIfError(err); + TInt sizeIndex = 0; + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG) + { + sizeIndex = KMaxSurfaceSizes-1; + } + TInt err = KErrNone; + do + { + GetSurfAttribs(surfaceAttribs, aIndex, sizeIndex); + iBuffers = 1; + surfaceAttribs().iBuffers = 1; + err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId); + iActualSize = surfaceAttribs().iSize; + sizeIndex--; + } + while(err != KErrNone && sizeIndex >= 0); } CRawSingleBufferSurface::~CRawSingleBufferSurface() { } + +TInt CEglSurfaceBase::Activate() + { + if (!eglMakeCurrent(iDisplay, iSurface, iSurface, iContext)) + { + EGLint err = eglGetError(); + RDebug::Printf("%s:%d: eglMakeCurrent gave error 0x%x", __FILE__, __LINE__, err); + return KErrBadHandle; + } + return KErrNone; + } + +void CEglSurfaceBase::ActivateL() + { + User::LeaveIfError(Activate()); + } + +void CEglSurfaceBase::DrawComplexL(const TRgb& aColour) + { + ActivateL(); + + TSize size; + eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth); + eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight); + + //Paint lots of random circles to keep the GPU busy. + for(TInt i=0; i < 300; i++) + { + VGPaint paint = vgCreatePaint(); + VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_APPEND_TO); + + TInt minDim = Min(size.iWidth, size.iHeight); + VGfloat cx = RandomNumberInRange(0, size.iWidth); + VGfloat cy = RandomNumberInRange(0, size.iHeight); + VGfloat diameter = RandomNumberInRange(minDim / 20, minDim / 3); + TRgb fillColour(RandomNumberInRange(0, 255), RandomNumberInRange(0, 255), RandomNumberInRange(0, 255), RandomNumberInRange(0, 255)); + + vguEllipse(path, cx, cy, diameter, diameter); + vgSetPaint(paint, VG_FILL_PATH); + vgSetColor(paint, fillColour.Value()); + vgDrawPath(path, VG_FILL_PATH); + + vgDestroyPath(path); + vgDestroyPaint(paint); + } + + //Paint the top corner with aColour so we can identify the drawing. + 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, 20, size.iHeight); + } + +void CEglSurfaceBase::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 CEglSurfaceBase::CreateL(TInt aIndex, const TPoint &aOffset) + { + SURF_ASSERT(aIndex < KSurfaceMaxIndex); + SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex); + + TInt sizeIndex = 0; + if (KSurfaceParams[aIndex].iXSize & LARGEST_POSSIBLE_FLAG) + { + sizeIndex = KMaxSurfaceSizes-1; + } + TInt err = KErrNone; + do + { + TRAP(err, DoCreateL(aIndex, aOffset, sizeIndex)); + sizeIndex--; + } + while(err != KErrNone && sizeIndex >= 0); + if (err != KErrNone) + { +// RDebug::Printf("%s:%d: err=%d (%d x %d)", __FILE__, __LINE__, err, iActualSize.iWidth, iActualSize.iHeight); + User::Leave(err); + } + } + +TInt CEglSurfaceBase::SubmitContent(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */) + { + TInt err = Activate(); + if (err != KErrNone) + { + return err; + } + if (!eglSwapBuffers(iDisplay, iSurface)) + { + EGLint err = eglGetError(); + RDebug::Printf("%s:%d: eglSwapBuffers gave error 0x%x", __FILE__, __LINE__, err); + return 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. + } + return KErrNone; + } + +void CEglSurfaceBase::DrawContentL(TInt aIndex) + { + ActivateL(); + CTestVgImage *vgImage = CTestVgImage::NewL(aIndex); + CleanupStack::PushL(vgImage); + vgDrawImage(vgImage->VGImage()); + CleanupStack::PopAndDestroy(vgImage); + } + +void CEglSurfaceBase::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]; + } + } + + +TInt CEglSurfaceBase::Notify(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, TUint32 /*aXTImes*/) + { + return KErrNotSupported; + } + +TInt CEglSurfaceBase::WaitFor(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, + TInt /*aTimeoutinMicroseconds*/, TUint32 & /*aTimeStamp*/) + { + return KErrNotSupported; + } + +void CEglSurfaceBase::BaseCreateL(TInt aIndex, EGLint aSurfaceType) + { + iParamIndex = aIndex; + iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + + EGLint err; + if (iDisplay == EGL_NO_DISPLAY) + { + err = eglGetError(); + RDebug::Printf("%s:%d: err = 0x%x", __FILE__, __LINE__, err); + User::Leave(KErrNotSupported); + } + + EGLint nConfigs = 0; + + // TODO: Need to use differnet config attribs based on aIndex. + EGLint configAttribs[] = + { + 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 + }; + + // Update surfacetype type to match + for(TInt i = 0; configAttribs[i] != EGL_NONE; i += 2) + { + if (configAttribs[i] == EGL_SURFACE_TYPE) + { + configAttribs[i+1] = aSurfaceType; + } + } + // Need some way to configure the attribs ... + eglChooseConfig(iDisplay, configAttribs, &iConfig, 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, iConfig, 0, NULL); + if (iContext == EGL_NO_CONTEXT) + { + err = eglGetError(); + //RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err); + User::Leave(KErrNotSupported); + } + } + +void CEglSurfaceBase::Destroy() + { + 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); + } + } + + class CWindow: public CBase { public: - static CWindow *NewL(TInt aIndex); + static CWindow *NewL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex); RWindow& Window(); ~CWindow(); private: - void ConstructL(TInt aIndex); + void ConstructL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex); CWindow(); private: @@ -454,17 +862,17 @@ }; -CWindow* CWindow::NewL(TInt aIndex) +CWindow* CWindow::NewL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex) { CWindow *self = new (ELeave) CWindow; CleanupStack::PushL(self); - self->ConstructL(aIndex); + self->ConstructL(aIndex, aOffset, aSizeIndex); CleanupStack::Pop(self); return self; } -void CWindow::ConstructL(TInt aIndex) +void CWindow::ConstructL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex) { RFbsSession::Connect(); if (aIndex >= KSurfaceMaxIndex) @@ -476,8 +884,17 @@ 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)); + TSurfaceParamsCommon winAttrib = KSurfaceParams[aIndex]; + TSize winSize; + if (winAttrib.iXSize & LARGEST_POSSIBLE_FLAG) + { + winSize = TSize(KSurfaceSizes[aSizeIndex].iWidth, KSurfaceSizes[aSizeIndex].iHeight); + } + else + { + winSize = TSize(winAttrib.iXSize, winAttrib.iYSize); + } + iWindow.SetExtent(TPoint(winAttrib.iXPos + aOffset.iX, winAttrib.iYPos + aOffset.iY), winSize); iWindow.SetRequiredDisplayMode(winAttrib.iDisplayMode); iWindow.Activate(); } @@ -523,110 +940,32 @@ } -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[] = +void CEglWindowSurface::DoCreateL(TInt aIndex, const TPoint &aOffset, TInt aSizeIndex) { - 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); + iParamIndex = aIndex; + iWindow = CWindow::NewL(aIndex, aOffset, aSizeIndex); + iActualSize = iWindow->Window().Size(); + + CEglSurfaceBase::BaseCreateL(aIndex, EGL_WINDOW_BIT); + + iSurface = eglCreateWindowSurface(iDisplay, iConfig, &iWindow->Window(), NULL); if (iSurface == EGL_NO_SURFACE) { - err = eglGetError(); - RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err); + EGLint err = eglGetError(); + RDebug::Printf("%s:%d: err = %x (%d x %d)", __FILE__, __LINE__, err, iActualSize.iWidth, iActualSize.iHeight); 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); - } - + Destroy(); + eglReleaseThread(); delete iWindow; } + TSurfaceId CEglWindowSurface::SurfaceId() const { // Default constructor for id sets it to a NULL-value, so if no window is created, we get @@ -642,72 +981,104 @@ } -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*/) + +CEglPBufferSurface::CEglPBufferSurface() + { + } + + +CEglPBufferSurface::~CEglPBufferSurface() + { + Destroy(); + eglReleaseThread(); + } + + +CEglPBufferSurface* CEglPBufferSurface::NewL() { - return KErrNotSupported; + CEglPBufferSurface* self = new (ELeave) CEglPBufferSurface; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +void CEglPBufferSurface::ConstructL() + { + } + + +const TText *CEglPBufferSurface::GetSurfaceTypeStr() const + { + return _S("CEglPBufferSurface"); } -TInt CEglWindowSurface::WaitFor(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, - TInt /*aTimeoutinMicroseconds*/, TUint32 & /*aTimeStamp*/) + +void CEglPBufferSurface::DoCreateL(TInt aIndex, const TPoint &/*aOffset*/, TInt aSizeIndex) { - return KErrNotSupported; + CEglSurfaceBase::BaseCreateL(aIndex, EGL_PBUFFER_BIT); + + EGLint attribs[] = + { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_NONE, + }; + if (KSurfaceParams[aIndex].iXSize & ELargestPossibleSurface) + { + iActualSize.iWidth = KSurfaceSizes[aSizeIndex].iWidth; + iActualSize.iHeight = KSurfaceSizes[aSizeIndex].iHeight; + } + else + { + iActualSize.iWidth = KSurfaceParams[aIndex].iXSize; + iActualSize.iHeight = KSurfaceParams[aIndex].iYSize; + } + for(TInt i = 0; attribs[i] != EGL_NONE; i += 2) + { + switch(attribs[i]) + { + case EGL_HEIGHT: + attribs[i+1] = iActualSize.iHeight; + break; + case EGL_WIDTH: + attribs[i+1] = iActualSize.iWidth; + break; + } + } + + iSurface = eglCreatePbufferSurface(iDisplay, iConfig, attribs); + if (iSurface == EGL_NO_SURFACE) + { + EGLint err = eglGetError(); + User::Leave(KErrNotSupported); + } + } + + +TSurfaceId CEglPBufferSurface::SurfaceId() const + { + SURF_ASSERT(0); // We shouldn't call this! + return TSurfaceId::CreateNullId(); + } + +TInt CEglPBufferSurface::SizeInBytes() const + { + // size of a pixel in bits. + EGLint size; + if (!eglGetConfigAttrib(iDisplay, iConfig, EGL_BUFFER_SIZE, &size)) + { + RDebug::Printf("Unable to get EGL_BUFFER_SIZE from config %d, err = %04x", iConfig, eglGetError()); + return 0; + } + + return (KSurfaceParams[iParamIndex].iXSize * KSurfaceParams[iParamIndex].iYSize * size) / 8; } @@ -718,13 +1089,18 @@ { case ESurfTypeRaw: return CRawSurface::NewL(); + case ESurfTypeEglWindow: return CEglWindowSurface::NewL(); + case ESurfTypeRawSingleBuffered: return CRawSingleBufferSurface::NewL(); + + case ESurfTypePBuffer: + return CEglPBufferSurface::NewL(); + default: SURF_ASSERT(0); return NULL; } } -