|
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 // The fix solves the problem of bitmap drawing command being added to the window server |
|
15 // command buffer without the bitmap handle(s) being added to the command buffer bitmap array. |
|
16 // |
|
17 // |
|
18 |
|
19 /** |
|
20 @file |
|
21 @test |
|
22 @internalComponent - Internal Symbian test code |
|
23 */ |
|
24 |
|
25 #include "tw32cmdbuf.h" |
|
26 |
|
27 const TInt KMaxTestIterations = 300; |
|
28 const TInt KMinTestIterations = 100; |
|
29 |
|
30 CTW32CmdBuf::CTW32CmdBuf(CTestStep* aStep): |
|
31 CTGraphicsBase(aStep) |
|
32 { |
|
33 } |
|
34 |
|
35 CTW32CmdBuf::~CTW32CmdBuf() |
|
36 { |
|
37 } |
|
38 |
|
39 void CTW32CmdBuf::ConstructL() |
|
40 { |
|
41 } |
|
42 |
|
43 void CTW32CmdBuf::RunTestCaseL(TInt aCurTestCase) |
|
44 { |
|
45 ((CTW32CmdBufStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); |
|
46 switch(aCurTestCase) |
|
47 { |
|
48 case 1: |
|
49 ((CTW32CmdBufStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0452")); |
|
50 INFO_PRINTF1(_L("Test all the drawing commands involving a CFbsBitmap\n")); |
|
51 DoCmdBufTestsL(); |
|
52 break; |
|
53 default: |
|
54 ((CTW32CmdBufStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); |
|
55 ((CTW32CmdBufStep*)iStep)->CloseTMSGraphicsStep(); |
|
56 INFO_PRINTF1(_L("Test complete\n")); |
|
57 TestComplete(); |
|
58 } |
|
59 ((CTW32CmdBufStep*)iStep)->RecordTestResultL(); |
|
60 } |
|
61 |
|
62 /** |
|
63 * TTestFunctionPtr pointer-to-function type definition |
|
64 */ |
|
65 typedef void (*TTestFunctionPtr)(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask); |
|
66 |
|
67 |
|
68 /** |
|
69 * Calls CWindowGc::DrawBitmap(const TPoint &aTopLeft, const CFbsBitmap *aDevice) |
|
70 */ |
|
71 void CallDrawBitmap1(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) |
|
72 { |
|
73 aGc->DrawBitmap(TPoint(0, 0), aBitmap); |
|
74 } |
|
75 |
|
76 /** |
|
77 * Calls CWindowGc::DrawBitmap(const TRect &aDestRect, const CFbsBitmap *aDevice) |
|
78 */ |
|
79 void CallDrawBitmap2(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) |
|
80 { |
|
81 aGc->DrawBitmap(TRect(0, 0, 100, 100), aBitmap); |
|
82 } |
|
83 |
|
84 /** |
|
85 * Calls CWindowGc::DrawBitmap(const TRect &aDestRect, const CFbsBitmap *aDevice, const TRect &aSourceRect) |
|
86 */ |
|
87 void CallDrawBitmap3(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) |
|
88 { |
|
89 aGc->DrawBitmap(TRect(0, 0, 100, 100), aBitmap, TRect(0, 0, 100, 100)); |
|
90 } |
|
91 |
|
92 /** |
|
93 * Calls CWindowGc::DrawBitmapMasked(const TRect& aDestRect, const CFbsBitmap* aBitmap, const TRect& aSourceRect, const CFbsBitmap* aMaskBitmap, TBool aInvertMask) |
|
94 */ |
|
95 void CallDrawBitmapMasked(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask) |
|
96 { |
|
97 aGc->DrawBitmapMasked(TRect(0, 0, 100, 100), aBitmap, TRect(0, 0, 100, 100), aMask, EFalse); |
|
98 } |
|
99 |
|
100 /** |
|
101 * Calls CWindowGc::UseBrushPattern(const CFbsBitmap *aDevice) |
|
102 */ |
|
103 void CallUseBrushPattern(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) |
|
104 { |
|
105 aGc->UseBrushPattern(aBitmap); |
|
106 } |
|
107 |
|
108 /** |
|
109 * Calls CWindowGc::BitBlt(const TPoint &aPos, const CFbsBitmap *aBitmap) |
|
110 */ |
|
111 void CallBitBlt1(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) |
|
112 { |
|
113 aGc->BitBlt(TPoint(0, 0), aBitmap); |
|
114 } |
|
115 |
|
116 /** |
|
117 * Calls CWindowGc::BitBlt(const TPoint &aDestination, const CFbsBitmap *aBitmap, const TRect &aSource) |
|
118 */ |
|
119 void CallBitBlt2(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* /*aMask*/) |
|
120 { |
|
121 aGc->BitBlt(TPoint(0, 0), aBitmap, TRect(0, 0, 100, 100)); |
|
122 } |
|
123 |
|
124 /** |
|
125 * Calls CWindowGc::BitBltMasked(const TPoint& aPoint,const CFbsBitmap* aBitmap,const TRect& aSourceRect,const CFbsBitmap* aMaskBitmap,TBool aInvertMask) |
|
126 */ |
|
127 void CallBitBltMasked(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask) |
|
128 { |
|
129 aGc->BitBltMasked(TPoint(0, 0), aBitmap, TRect(0, 0, 100, 100), aMask, EFalse); |
|
130 } |
|
131 |
|
132 /** |
|
133 * Calls CWindowGc::AlphaBlendBitmaps(const TPoint& aDestPt, const CFbsBitmap* aSrcBmp, const TRect& aSrcRect, const CFbsBitmap* aAlphaBmp, const TPoint& aAlphaPt) |
|
134 */ |
|
135 void CallAlphaBlendBitmaps(CWindowGc* aGc, CFbsBitmap* aBitmap, CFbsBitmap* aMask) |
|
136 { |
|
137 aGc->AlphaBlendBitmaps(TPoint(0, 0), aBitmap, TRect(0, 0, 100, 100), aMask, TPoint(0, 0)); |
|
138 } |
|
139 |
|
140 /** |
|
141 * Drawing command function array. |
|
142 */ |
|
143 const TTestFunctionPtr KTestFunctions[] = |
|
144 { |
|
145 CallDrawBitmap1, |
|
146 CallDrawBitmap2, |
|
147 CallDrawBitmap3, |
|
148 CallDrawBitmapMasked, |
|
149 CallUseBrushPattern, |
|
150 CallBitBlt1, |
|
151 CallBitBlt2, |
|
152 CallBitBltMasked, |
|
153 CallAlphaBlendBitmaps, |
|
154 }; |
|
155 |
|
156 /** |
|
157 * @SYMTestCaseID GRAPHICS-WSERV-0452 |
|
158 * @SYMTestCaseDesc Tests drawing commands with bitmap handles. |
|
159 * @SYMDEF INC111655 |
|
160 * @SYMFssID CWindowGc::DrawBitmap() \n |
|
161 * CWindowGc::DrawBitmapMasked()\n |
|
162 * CWindowGc::UseBrushPattern()\n |
|
163 * CWindowGc::BitBlt()\n |
|
164 * CWindowGc::AlphaBlendBitmaps() |
|
165 * @SYMTestPriority Critical |
|
166 * @SYMTestType Unit Test |
|
167 * @SYMTestPurpose To ensure drawing commands with bitmap handles are added to the |
|
168 command buffer successfully when the buffer is full. |
|
169 * @SYMTestActions Fill the command buffer with CWindowGc::Clear() commands in a loop until |
|
170 the buffer is full, create bitmap(s), then call the draw command and then |
|
171 delete the bitmap handle(s). All tests are done in a second thread. |
|
172 * @SYMTestExpectedResults The function should not panic. Without the fix the functions will panic |
|
173 with WSERV 7. |
|
174 * @SYMTestStatus Implemented |
|
175 */ |
|
176 void CTW32CmdBuf::DoCmdBufTestsL() |
|
177 { |
|
178 CreateSecondThreadAndDoTestL(ECallDrawBitmap1); |
|
179 CreateSecondThreadAndDoTestL(ECallDrawBitmap2); |
|
180 CreateSecondThreadAndDoTestL(ECallDrawBitmap3); |
|
181 CreateSecondThreadAndDoTestL(ECallDrawBitmapMasked); |
|
182 CreateSecondThreadAndDoTestL(ECallUseBrushPattern); |
|
183 CreateSecondThreadAndDoTestL(ECallBitBlt1); |
|
184 CreateSecondThreadAndDoTestL(ECallBitBlt2); |
|
185 CreateSecondThreadAndDoTestL(ECallBitBltMasked); |
|
186 CreateSecondThreadAndDoTestL(ECallAlphaBlendBitmaps); |
|
187 } |
|
188 |
|
189 /** |
|
190 * Creates a second thread to run the test. |
|
191 * |
|
192 * @param aFunctionIndex The drawing function command to be executed. All commands are defined in TestFunctionIndex. |
|
193 */ |
|
194 void CTW32CmdBuf::CreateSecondThreadAndDoTestL(TTestFunctionIndex aFunctionIndex) |
|
195 { |
|
196 RThread thread; |
|
197 TBuf<30> threadName(KTW32CmdBufSecondThread); |
|
198 static TInt threadSerialNumber = 0; |
|
199 threadName.AppendNum(++threadSerialNumber); |
|
200 User::LeaveIfError(thread.Create(threadName, TestCmdBufFunction, KDefaultStackSize, KMinHeapSize, 0x4000, &aFunctionIndex)); |
|
201 TRequestStatus status; |
|
202 thread.Logon(status); |
|
203 thread.Resume(); |
|
204 User::WaitForRequest(status); |
|
205 TEST(thread.ExitType()==EExitKill); |
|
206 TEST(thread.ExitReason() == KErrNone); |
|
207 thread.Close(); |
|
208 } |
|
209 |
|
210 /** |
|
211 * Runs the test in a second thread. |
|
212 * |
|
213 * @param aFunctionIndex The drawing function command to be executed. All commands are defined in TestFunctionIndex. |
|
214 */ |
|
215 TInt CTW32CmdBuf::DoTestCmdBufFunctionL(TTestFunctionIndex aFunctionIndex) |
|
216 { |
|
217 RWsSession session; |
|
218 User::LeaveIfError(session.Connect()); |
|
219 CleanupClosePushL(session); |
|
220 CWsScreenDevice *device = new(ELeave) CWsScreenDevice(session); |
|
221 CleanupStack::PushL(device); |
|
222 User::LeaveIfError(device->Construct(CTestBase::iScreenNo)); |
|
223 CWindowGc* gc; |
|
224 User::LeaveIfError(device->CreateContext(gc)); |
|
225 CleanupStack::PushL(gc); |
|
226 RWindowGroup group(session); |
|
227 User::LeaveIfError(group.Construct(1, EFalse)); |
|
228 CleanupClosePushL(group); |
|
229 RWindow window(session); |
|
230 User::LeaveIfError(window.Construct(group, 2)); |
|
231 CleanupClosePushL(window); |
|
232 window.SetExtent(TPoint(0,0), TSize(200, 200)); |
|
233 User::LeaveIfError(window.SetRequiredDisplayMode(EColor64K)); |
|
234 window.Activate(); |
|
235 gc->Activate(window); |
|
236 session.SetAutoFlush(EFalse); |
|
237 window.Invalidate(); |
|
238 window.BeginRedraw(); |
|
239 for(TInt i=KMinTestIterations; i<KMaxTestIterations; ++i) |
|
240 { |
|
241 for(TInt j=0; j<i; ++j) |
|
242 { |
|
243 gc->Clear(); |
|
244 } |
|
245 |
|
246 CFbsBitmap* bitmap = new(ELeave) CFbsBitmap; |
|
247 CleanupStack::PushL(bitmap); |
|
248 User::LeaveIfError(bitmap->Create(TSize(100, 100), EColor64K)); |
|
249 CFbsBitmap* mask = new(ELeave) CFbsBitmap; |
|
250 CleanupStack::PushL(mask); |
|
251 User::LeaveIfError(mask->Create(TSize(100, 100), EColor64K)); |
|
252 KTestFunctions[aFunctionIndex](gc, bitmap, mask); |
|
253 CleanupStack::PopAndDestroy(2); |
|
254 session.Flush(); |
|
255 } |
|
256 window.EndRedraw(); |
|
257 gc->Deactivate(); |
|
258 CleanupStack::PopAndDestroy(5); |
|
259 return KErrNone; |
|
260 } |
|
261 |
|
262 /** |
|
263 * Second thread entry function. |
|
264 * |
|
265 * @param aInfo The parameter(s) passed to the second thread in this case the function index. |
|
266 */ |
|
267 TInt CTW32CmdBuf::TestCmdBufFunction(TAny* aInfo) |
|
268 { |
|
269 if(!aInfo) |
|
270 { |
|
271 return KErrArgument; |
|
272 } |
|
273 TTestFunctionIndex functionIndex = *(TTestFunctionIndex*)aInfo; |
|
274 CTrapCleanup *trap = CTrapCleanup::New(); |
|
275 __ASSERT_ALWAYS(trap, User::Invariant()); |
|
276 |
|
277 TRAPD(err, DoTestCmdBufFunctionL(functionIndex)); |
|
278 |
|
279 delete trap; |
|
280 return err; |
|
281 } |
|
282 |
|
283 __CONSTRUCT_STEP__(W32CmdBuf) |