diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/directgdi/test/tinterleaving.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/directgdi/test/tinterleaving.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,485 @@ +// 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: +// + +#include "tinterleaving.h" +#include "tdirectgdieglcontent_client.h" +#include "tdirectgdieglcontent_clientserver.h" +#include +#include +#include +#include + +/** +A utility class used by the templated function CleanupResetAndDestroyPushL() to create +a TCleanupItem item that will perform a ResetAndDestroy() operation on the class T type object. +Used for cleanup RPointerArray objects. +*/ +template class CleanupResetAndDestroy + { +public: + static void PushL(T &aRef) + { + CleanupStack::PushL(TCleanupItem(&ResetAndDestroy, &aRef)); + }; + +private: + static void ResetAndDestroy(TAny *aPtr) + { + (STATIC_CAST(T *, aPtr))->ResetAndDestroy(); + }; + }; + +/** +Helper function for pushing CleanupResetAndDestroy object onto CleanupStack. +*/ +template void CleanupResetAndDestroyPushL(T &aRef) + { + CleanupResetAndDestroy::PushL(aRef); + }; + +CTInterleaving::CTInterleaving() + { + SetTestStepName(KTDirectGdiInterleavingStep); + } + +CTInterleaving::~CTInterleaving() + { + } + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-INTERLEAVING-0001 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9188 + REQ9189 + REQ9196 + REQ9213 + REQ9227 + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test synchronized drawing with egl content + +@SYMTestPriority + High + +@SYMTestStatus + Implemented + +@SYMTestActions Establish connection to EglContentServer. + Render frame synchronized with EGL content in following way: + - Draw multicolor checkboard to gdi target + - Get EGL content sgimage id from EglContentServer in synchronous mode. + - Using obtained id create DirectGdi image source and draw it on target with DrawResource() method. + - Draw semi-transparent vertical bars to gdi target. + Repeat above steps a few times. + +@SYMTestExpectedResults + Valid set of bitmaps should be created. + These bitmaps should be the same as a reference bitmaps. +*/ +void CTInterleaving::TestSyncL() + { + _LIT(KTestName, "Interleaving-Sync"); //test case name + // start EGL content server + REglContentSession eglContentSession; + TESTNOERRORL(eglContentSession.Connect()); + CleanupClosePushL(eglContentSession); + + // render few frames synchronized with egl content + for(TInt frame=0; frame<10; frame++) + { + ResetGc(); + + DrawDirectGdiCheckboardToTarget(); + TESTNOERRORL(iGc->GetError()); + + // get egl content sgimage id + TSgDrawableId imageId; + TESTNOERRORL(eglContentSession.GetSyncImage(imageId)); + + DrawImageToTargetL(imageId); + TESTNOERRORL(iGc->GetError()); + + DrawDirectGdiBarsToTarget(); + TESTNOERRORL(iGc->GetError()); + + // save target + TBuf<30> testName; + testName.Append(KTestName); + testName.AppendNum(frame); + TESTNOERRORL(CTDirectGdiStepBase::WriteTargetOutput(iTestParams, testName)); + } + + CleanupStack::PopAndDestroy(&eglContentSession); + } + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-INTERLEAVING-0002 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9188 + REQ9189 + REQ9196 + REQ9213 + REQ9227 + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test asynchronous drawing of egl content + +@SYMTestPriority + High + +@SYMTestStatus + Implemented + +@SYMTestActions Establish connection to EglContentServer. + Render frame in following way: + - Draw multicolor checkboard to gdi target + - Get EGL content sgimage id and frame number from EglContentServer in asynchronous mode. + - Using obtained id create DirectGdi image source and draw it on target with DrawResource() method. + - Draw semi-transparent vertical bars to gdi target. + - Find currently created target bitmap in stored bitmaps array. + Use frame number obtained from EglContentServer as an array index. + If it not exists in this array, store it. Otherwise compare it with stored one pixel by pixel. + Test fails when this comparison fails. + EglContentServer produce ten different frames, + so for proper testing repeat above steps at least fifty times. + +@SYMTestExpectedResults Valid set of bitmaps should be created. + These bitmaps should be the same as a reference bitmaps. +*/ +void CTInterleaving::TestAsyncL(TBool aDebug) + { + _LIT(KTestName, "Interleaving-Async"); //test case name + + // start EGL content server + REglContentSession eglContentSession; + TESTNOERRORL(eglContentSession.Connect()); + CleanupClosePushL(eglContentSession); + + // prepare array to store frames + RPointerArray storedBitmaps(KEglContentAsyncMaxFrames); + CleanupResetAndDestroyPushL(storedBitmaps); + for(TInt i=0; iSizeInPixels().iWidth*4; // buffer is 32-bit BGRA + HBufC8* lineBuf1 = HBufC8::NewLC(bufSize); + HBufC8* lineBuf2 = HBufC8::NewLC(bufSize); + + // With the EGL context continuously being generated, we cannot guarantee that + // all the frames will be retrieved. + // However, in theory, the probability of picking each frame can be + // approximated to a uniform discrete distribution. + // So we can work out how many times we need to pick a frame to get all + // the unique frames 99% of the time. + // This works out to be approximately 65 times for 10 unique frames. + const TInt KNumTriesToGetAllFrames = 65; + + if(!aDebug) + { + WARN_PRINTF1(_L("Note: Due to the nature of the test, it may be possible that not all the frames are captured")); + } + TInt64 seed = (TInt64)User::FastCounter(); + + // render few frames asynchronous from egl content + for(TInt frame=0; frameGetError()); + + // get egl content sgimage id + TSgDrawableId imageId; + TInt fnum; + if(!aDebug) + { + TESTNOERRORL(eglContentSession.GetAsyncImage(imageId, fnum)); + // Due to the nature of the asynchronous test, where the frames are + // continuously being rendered and we can only dip in and pick the last + // rendered frame, it cannot be guaranteed that all the unique frames will + // be retrieved. This could be due to this loop and the EGL content + // generation running in harmony. To try to overcome this, introduce + // a random delay between 0 and 3 frames (0 seconds to 100 milliseconds - + // EGL content generated at 30fps). + TInt delay = Math::Rand(seed)%100000; + User::After(delay); + } + else + { + TESTNOERRORL(eglContentSession.GetAsyncImageDebug(imageId, fnum)); + } + + DrawImageToTargetL(imageId); + TESTNOERRORL(iGc->GetError()); + + DrawDirectGdiBarsToTarget(); + TESTNOERRORL(iGc->GetError()); + + iGdiTarget->Finish(); + CFbsBitmap* targetBitmap = iGdiTarget->GetTargetFbsBitmapL(); + + if(storedBitmaps[fnum] != NULL) + { + // compare with previously stored bitmap + TUint32 cmpMask; // BGRA mask + if((iTestParams.iTargetPixelFormat == EUidPixelFormatXRGB_8888) || + (iTestParams.iTargetPixelFormat == EUidPixelFormatXRGB_4444)) + { + cmpMask = 0xffffff00; // exclude unused pixel part from comparision + } + else + { + cmpMask = 0xffffffff; + } + + TInt width = targetBitmap->SizeInPixels().iWidth; + TInt height = targetBitmap->SizeInPixels().iHeight; + + TPtr8 linePtr1(lineBuf1->Des()); + TPtr8 linePtr2(lineBuf2->Des()); + + TBool pass = ETrue; + + // compare pixel by pixel + for(TInt line=0; lineGetScanLine(linePtr1, TPoint(0, line), width, EColor16MA); + storedBitmaps[fnum]->GetScanLine(linePtr2, TPoint(0, line), width, EColor16MA); + + const TUint32* pPtr1 = (const TUint32*)linePtr1.Ptr(); + const TUint32* pPtr2 = (const TUint32*)linePtr2.Ptr(); + for(TInt x=0; xCreate(targetBitmap->SizeInPixels(), targetBitmap->DisplayMode()) == KErrNone); + Mem::Copy((TUint8*)storedBitmaps[fnum]->DataAddress(), + (TUint8*)targetBitmap->DataAddress(), + storedBitmaps[fnum]->DataStride()*storedBitmaps[fnum]->SizeInPixels().iHeight); + + // save target + TBuf<40> testName; + testName.Append(KTestName); + if(aDebug) + { + _LIT(KDebug, "Debug"); + testName.Append(KDebug); + } + testName.AppendNum(fnum); + TESTNOERRORL(CTDirectGdiStepBase::WriteTargetOutput(iTestParams, testName)); + } + } + + CleanupStack::PopAndDestroy(4, &eglContentSession); + } + +/** +Draw multicolor checkboard to gdi target. +*/ +void CTInterleaving::DrawDirectGdiCheckboardToTarget() + { + const TInt width = iGdiTarget->SizeInPixels().iWidth; + const TInt height = iGdiTarget->SizeInPixels().iHeight; + const TInt rwidth = 13; + const TInt rheight = 13; + + iGc->SetPenStyle(DirectGdi::ENullPen); + iGc->SetBrushStyle(DirectGdi::ESolidBrush); + + TInt color = 0; + for(TInt y=0; ySetBrushColor(KColor16Table[color%16]); + color++; + iGc->DrawRect(TRect(TPoint(x, y), TSize(rwidth, rheight))); + } + } + } + +/** +Draw semi-transparent vertical bars to gdi target. +*/ +void CTInterleaving::DrawDirectGdiBarsToTarget() + { + TPoint pos(40, 40); + TSize size(iGdiTarget->SizeInPixels()); + size -= TSize(80, 80); + TSize barSize(size.iWidth/10, size.iHeight); + + iGc->SetPenStyle(DirectGdi::ENullPen); + iGc->SetBrushStyle(DirectGdi::ESolidBrush); + + for(TInt i=0; iSetBrushColor(color); + iGc->DrawRect(TRect(pos+TPoint(i, 0), barSize)); + } + } + +/** +Draw four rotated EGL images to gdi target. +*/ +void CTInterleaving::DrawImageToTargetL(TSgDrawableId aImageId) + { + // prepare sgimage from id + RSgImage image; + TESTNOERRORL(image.Open(aImageId)); + CleanupClosePushL(image); + + TESTNOERRORL(CDirectGdiDriver::Open()); + + CDirectGdiDriver* dgdiDriver = CDirectGdiDriver::Static(); + TESTL(dgdiDriver != NULL); + CleanupClosePushL(*dgdiDriver); + + // prepare DirectGdi image source + RDirectGdiDrawableSource source(*dgdiDriver); + TESTNOERRORL(source.Create(image)); + CleanupClosePushL(source); + + // draw sgimage resorce on gdi target + TDrawableSourceAndEquivRotatedBmps imageSource; + imageSource.iDrawableSrc = &source; + TPoint pos(20, 20); + TSize size(iGdiTarget->SizeInPixels()); + size -= TSize(40, 40); + size.iWidth /= 2; + size.iHeight /= 2; + TSize size2(size); + size2 -= TSize(10, 10); + + iGc->DrawResource(TRect(pos, size2), imageSource); + TESTNOERRORL(iGc->GetError()); + iGc->DrawResource(TRect(pos+TPoint(size.iWidth, 0), size2), imageSource, DirectGdi::EGraphicsRotation90); + TESTNOERRORL(iGc->GetError()); + iGc->DrawResource(TRect(pos+TPoint(0, size.iHeight), size2), imageSource, DirectGdi::EGraphicsRotation180); + TESTNOERRORL(iGc->GetError()); + iGc->DrawResource(TRect(pos+size.AsPoint(), size2), imageSource, DirectGdi::EGraphicsRotation270); + TESTNOERRORL(iGc->GetError()); + + CleanupStack::PopAndDestroy(3, &image); + } + +/** +Override of base class virtual +@leave Gets system wide error code +@return - TVerdict code +*/ +TVerdict CTInterleaving::doTestStepPreambleL() + { + CTDirectGdiStepBase::doTestStepPreambleL(); + return TestStepResult(); + } + +/** +Override of base class pure virtual +Our implementation only gets called if the base class doTestStepPreambleL() did +not leave. That being the case, the current test result value will be EPass. +@leave Gets system wide error code +@return TVerdict code +*/ +TVerdict CTInterleaving::doTestStepL() + { + // Test for each target pixel format + for(TInt targetPixelFormatIndex = iTargetPixelFormatArray.Count() - 1; targetPixelFormatIndex >= 0 ; targetPixelFormatIndex--) + { + iTestParams.iTargetPixelFormat = iTargetPixelFormatArray[targetPixelFormatIndex]; + + SetTargetL(iTestParams.iTargetPixelFormat, EOneContextOneTarget, TSize(400, 400)); + RunTestsL(); + } + CloseTMSGraphicsStep(); + return TestStepResult(); + } + +/** +Override of base class virtual +@leave Gets system wide error code +@return - TVerdict code +*/ +TVerdict CTInterleaving::doTestStepPostambleL() + { + CTDirectGdiStepBase::doTestStepPostambleL(); + return TestStepResult(); + } + +/** +Override of base class pure virtual +Lists the tests to be run +*/ +void CTInterleaving::RunTestsL() + { + if(iUseDirectGdi) + { + SetTestStepID(_L("GRAPHICS-DIRECTGDI-INTERLEAVING-0001")); + TestSyncL(); + RecordTestResultL(); + SetTestStepID(_L("GRAPHICS-DIRECTGDI-INTERLEAVING-0002")); + TestAsyncL(); + RecordTestResultL(); + SetTestStepID(_L("GRAPHICS-DIRECTGDI-INTERLEAVING-0002")); + TestAsyncL(ETrue); + RecordTestResultL(); + } + }