sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // The fix solves the problem of bitmap drawing command being added to the window server sl@0: // command buffer without the bitmap handle(s) being added to the command buffer bitmap array. sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @test sl@0: @internalComponent - Internal Symbian test code sl@0: */ sl@0: sl@0: #include "tw32cmdbuf.h" sl@0: sl@0: const TInt KMaxTestIterations = 300; sl@0: const TInt KMinTestIterations = 100; sl@0: sl@0: CTW32CmdBuf::CTW32CmdBuf(CTestStep* aStep): sl@0: CTGraphicsBase(aStep) sl@0: { sl@0: } sl@0: sl@0: CTW32CmdBuf::~CTW32CmdBuf() sl@0: { sl@0: } sl@0: sl@0: void CTW32CmdBuf::ConstructL() sl@0: { sl@0: } sl@0: sl@0: void CTW32CmdBuf::RunTestCaseL(TInt aCurTestCase) sl@0: { sl@0: ((CTW32CmdBufStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); sl@0: switch(aCurTestCase) sl@0: { sl@0: case 1: sl@0: ((CTW32CmdBufStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0452")); sl@0: INFO_PRINTF1(_L("Test all the drawing commands involving a CFbsBitmap\n")); sl@0: DoCmdBufTestsL(); sl@0: break; sl@0: default: sl@0: ((CTW32CmdBufStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); sl@0: ((CTW32CmdBufStep*)iStep)->CloseTMSGraphicsStep(); sl@0: INFO_PRINTF1(_L("Test complete\n")); sl@0: TestComplete(); sl@0: } sl@0: ((CTW32CmdBufStep*)iStep)->RecordTestResultL(); sl@0: } sl@0: sl@0: /** sl@0: * TTestFunctionPtr pointer-to-function type definition sl@0: */ sl@0: typedef void (*TTestFunctionPtr)(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask); sl@0: sl@0: sl@0: /** sl@0: * Calls CWindowGc::DrawBitmap(const TPoint &aTopLeft, const CFbsBitmap *aDevice) sl@0: */ sl@0: void CallDrawBitmap1(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) sl@0: { sl@0: aGc->DrawBitmap(TPoint(0, 0), aBitmap); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::DrawBitmap(const TRect &aDestRect, const CFbsBitmap *aDevice) sl@0: */ sl@0: void CallDrawBitmap2(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) sl@0: { sl@0: aGc->DrawBitmap(TRect(0, 0, 100, 100), aBitmap); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::DrawBitmap(const TRect &aDestRect, const CFbsBitmap *aDevice, const TRect &aSourceRect) sl@0: */ sl@0: void CallDrawBitmap3(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) sl@0: { sl@0: aGc->DrawBitmap(TRect(0, 0, 100, 100), aBitmap, TRect(0, 0, 100, 100)); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::DrawBitmapMasked(const TRect& aDestRect, const CFbsBitmap* aBitmap, const TRect& aSourceRect, const CFbsBitmap* aMaskBitmap, TBool aInvertMask) sl@0: */ sl@0: void CallDrawBitmapMasked(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask) sl@0: { sl@0: aGc->DrawBitmapMasked(TRect(0, 0, 100, 100), aBitmap, TRect(0, 0, 100, 100), aMask, EFalse); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::UseBrushPattern(const CFbsBitmap *aDevice) sl@0: */ sl@0: void CallUseBrushPattern(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) sl@0: { sl@0: aGc->UseBrushPattern(aBitmap); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::BitBlt(const TPoint &aPos, const CFbsBitmap *aBitmap) sl@0: */ sl@0: void CallBitBlt1(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) sl@0: { sl@0: aGc->BitBlt(TPoint(0, 0), aBitmap); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::BitBlt(const TPoint &aDestination, const CFbsBitmap *aBitmap, const TRect &aSource) sl@0: */ sl@0: void CallBitBlt2(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) sl@0: { sl@0: aGc->BitBlt(TPoint(0, 0), aBitmap, TRect(0, 0, 100, 100)); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::BitBltMasked(const TPoint& aPoint,const CFbsBitmap* aBitmap,const TRect& aSourceRect,const CFbsBitmap* aMaskBitmap,TBool aInvertMask) sl@0: */ sl@0: void CallBitBltMasked(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask) sl@0: { sl@0: aGc->BitBltMasked(TPoint(0, 0), aBitmap, TRect(0, 0, 100, 100), aMask, EFalse); sl@0: } sl@0: sl@0: /** sl@0: * Calls CWindowGc::AlphaBlendBitmaps(const TPoint& aDestPt, const CFbsBitmap* aSrcBmp, const TRect& aSrcRect, const CFbsBitmap* aAlphaBmp, const TPoint& aAlphaPt) sl@0: */ sl@0: void CallAlphaBlendBitmaps(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask) sl@0: { sl@0: aGc->AlphaBlendBitmaps(TPoint(0, 0), aBitmap, TRect(0, 0, 100, 100), aMask, TPoint(0, 0)); sl@0: } sl@0: sl@0: /** sl@0: * Drawing command function array. sl@0: */ sl@0: const TTestFunctionPtr KTestFunctions[] = sl@0: { sl@0: CallDrawBitmap1, sl@0: CallDrawBitmap2, sl@0: CallDrawBitmap3, sl@0: CallDrawBitmapMasked, sl@0: CallUseBrushPattern, sl@0: CallBitBlt1, sl@0: CallBitBlt2, sl@0: CallBitBltMasked, sl@0: CallAlphaBlendBitmaps, sl@0: }; sl@0: sl@0: /** sl@0: * @SYMTestCaseID GRAPHICS-WSERV-0452 sl@0: * @SYMTestCaseDesc Tests drawing commands with bitmap handles. sl@0: * @SYMDEF INC111655 sl@0: * @SYMFssID CWindowGc::DrawBitmap() \n sl@0: * CWindowGc::DrawBitmapMasked()\n sl@0: * CWindowGc::UseBrushPattern()\n sl@0: * CWindowGc::BitBlt()\n sl@0: * CWindowGc::AlphaBlendBitmaps() sl@0: * @SYMTestPriority Critical sl@0: * @SYMTestType Unit Test sl@0: * @SYMTestPurpose To ensure drawing commands with bitmap handles are added to the sl@0: command buffer successfully when the buffer is full. sl@0: * @SYMTestActions Fill the command buffer with CWindowGc::Clear() commands in a loop until sl@0: the buffer is full, create bitmap(s), then call the draw command and then sl@0: delete the bitmap handle(s). All tests are done in a second thread. sl@0: * @SYMTestExpectedResults The function should not panic. Without the fix the functions will panic sl@0: with WSERV 7. sl@0: * @SYMTestStatus Implemented sl@0: */ sl@0: void CTW32CmdBuf::DoCmdBufTestsL() sl@0: { sl@0: CreateSecondThreadAndDoTestL(ECallDrawBitmap1); sl@0: CreateSecondThreadAndDoTestL(ECallDrawBitmap2); sl@0: CreateSecondThreadAndDoTestL(ECallDrawBitmap3); sl@0: CreateSecondThreadAndDoTestL(ECallDrawBitmapMasked); sl@0: CreateSecondThreadAndDoTestL(ECallUseBrushPattern); sl@0: CreateSecondThreadAndDoTestL(ECallBitBlt1); sl@0: CreateSecondThreadAndDoTestL(ECallBitBlt2); sl@0: CreateSecondThreadAndDoTestL(ECallBitBltMasked); sl@0: CreateSecondThreadAndDoTestL(ECallAlphaBlendBitmaps); sl@0: } sl@0: sl@0: /** sl@0: * Creates a second thread to run the test. sl@0: * sl@0: * @param aFunctionIndex The drawing function command to be executed. All commands are defined in TestFunctionIndex. sl@0: */ sl@0: void CTW32CmdBuf::CreateSecondThreadAndDoTestL(TTestFunctionIndex aFunctionIndex) sl@0: { sl@0: RThread thread; sl@0: TBuf<30> threadName(KTW32CmdBufSecondThread); sl@0: static TInt threadSerialNumber = 0; sl@0: threadName.AppendNum(++threadSerialNumber); sl@0: User::LeaveIfError(thread.Create(threadName, TestCmdBufFunction, KDefaultStackSize, KMinHeapSize, 0x4000, &aFunctionIndex)); sl@0: TRequestStatus status; sl@0: thread.Logon(status); sl@0: thread.Resume(); sl@0: User::WaitForRequest(status); sl@0: TEST(thread.ExitType()==EExitKill); sl@0: TEST(thread.ExitReason() == KErrNone); sl@0: thread.Close(); sl@0: } sl@0: sl@0: /** sl@0: * Runs the test in a second thread. sl@0: * sl@0: * @param aFunctionIndex The drawing function command to be executed. All commands are defined in TestFunctionIndex. sl@0: */ sl@0: TInt CTW32CmdBuf::DoTestCmdBufFunctionL(TTestFunctionIndex aFunctionIndex) sl@0: { sl@0: RWsSession session; sl@0: User::LeaveIfError(session.Connect()); sl@0: CleanupClosePushL(session); sl@0: CWsScreenDevice *device = new(ELeave) CWsScreenDevice(session); sl@0: CleanupStack::PushL(device); sl@0: User::LeaveIfError(device->Construct(CTestBase::iScreenNo)); sl@0: CWindowGc* gc; sl@0: User::LeaveIfError(device->CreateContext(gc)); sl@0: CleanupStack::PushL(gc); sl@0: RWindowGroup group(session); sl@0: User::LeaveIfError(group.Construct(1, EFalse)); sl@0: CleanupClosePushL(group); sl@0: RWindow window(session); sl@0: User::LeaveIfError(window.Construct(group, 2)); sl@0: CleanupClosePushL(window); sl@0: window.SetExtent(TPoint(0,0), TSize(200, 200)); sl@0: User::LeaveIfError(window.SetRequiredDisplayMode(EColor64K)); sl@0: window.Activate(); sl@0: gc->Activate(window); sl@0: session.SetAutoFlush(EFalse); sl@0: window.Invalidate(); sl@0: window.BeginRedraw(); sl@0: for(TInt i=KMinTestIterations; iClear(); sl@0: } sl@0: sl@0: CFbsBitmap* bitmap = new(ELeave) CFbsBitmap; sl@0: CleanupStack::PushL(bitmap); sl@0: User::LeaveIfError(bitmap->Create(TSize(100, 100), EColor64K)); sl@0: CFbsBitmap* mask = new(ELeave) CFbsBitmap; sl@0: CleanupStack::PushL(mask); sl@0: User::LeaveIfError(mask->Create(TSize(100, 100), EColor64K)); sl@0: KTestFunctions[aFunctionIndex](gc, bitmap, mask); sl@0: CleanupStack::PopAndDestroy(2); sl@0: session.Flush(); sl@0: } sl@0: window.EndRedraw(); sl@0: gc->Deactivate(); sl@0: CleanupStack::PopAndDestroy(5); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: * Second thread entry function. sl@0: * sl@0: * @param aInfo The parameter(s) passed to the second thread in this case the function index. sl@0: */ sl@0: TInt CTW32CmdBuf::TestCmdBufFunction(TAny* aInfo) sl@0: { sl@0: if(!aInfo) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: TTestFunctionIndex functionIndex = *(TTestFunctionIndex*)aInfo; sl@0: CTrapCleanup *trap = CTrapCleanup::New(); sl@0: __ASSERT_ALWAYS(trap, User::Invariant()); sl@0: sl@0: TRAPD(err, DoTestCmdBufFunctionL(functionIndex)); sl@0: sl@0: delete trap; sl@0: return err; sl@0: } sl@0: sl@0: __CONSTRUCT_STEP__(W32CmdBuf)