|
1 // Copyright (c) 2003-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 // |
|
15 |
|
16 #include <random.h> |
|
17 #include <s32file.h> |
|
18 #include <e32math.h> |
|
19 #include <hal.h> |
|
20 #include <s32mem.h> |
|
21 #include <graphics/gdi/gdiconsts.h> |
|
22 #include <e32cmn.h> |
|
23 #include "BITPANIC.H" |
|
24 #include "TDefect2.h" |
|
25 #include "fbsmessage.h" |
|
26 |
|
27 //=================================================================== |
|
28 //In order to test multiple screens creation process on the Emulator, |
|
29 //you have to extend your epoc.ini file with the following lines |
|
30 //_NewScreen_ |
|
31 //ScreenWidth 640 |
|
32 //ScreenHeight 480 |
|
33 //=================================================================== |
|
34 |
|
35 // |
|
36 // |
|
37 //Globals |
|
38 LOCAL_D RFs FServSession; |
|
39 |
|
40 // |
|
41 // |
|
42 //Test file names |
|
43 _LIT(KArchiveFileName, "C:\\FbsBitGcArchive.dat"); |
|
44 |
|
45 // |
|
46 // |
|
47 //Create/Destroy test environment global functions |
|
48 |
|
49 //Delete "aFullName" file. |
|
50 LOCAL_C void DeleteDataFile(const TDesC& aFullName) |
|
51 { |
|
52 RFs fsSession; |
|
53 TInt err = fsSession.Connect(); |
|
54 if(err == KErrNone) |
|
55 { |
|
56 TEntry entry; |
|
57 if(fsSession.Entry(aFullName, entry) == KErrNone) |
|
58 { |
|
59 RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); |
|
60 err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); |
|
61 if(err != KErrNone) |
|
62 { |
|
63 RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); |
|
64 } |
|
65 err = fsSession.Delete(aFullName); |
|
66 if(err != KErrNone) |
|
67 { |
|
68 RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); |
|
69 } |
|
70 } |
|
71 fsSession.Close(); |
|
72 } |
|
73 else |
|
74 { |
|
75 RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); |
|
76 } |
|
77 } |
|
78 |
|
79 // |
|
80 CTDefect2::CTDefect2(CTestStep* aStep): |
|
81 CTGraphicsBase(aStep), |
|
82 iScrDev(NULL), |
|
83 iGc(NULL), |
|
84 iSize(0, 0), |
|
85 iCurrentMode(ENone), |
|
86 iBitmap(NULL), |
|
87 iBmpDevice(NULL) |
|
88 { |
|
89 } |
|
90 |
|
91 CTDefect2::~CTDefect2() |
|
92 { |
|
93 DestroyFont(); |
|
94 DeleteBitmap(); |
|
95 DeleteGraphicsContext(); |
|
96 DeleteBitmapDevice(); |
|
97 DeleteScreenDevice(); |
|
98 } |
|
99 |
|
100 void CTDefect2::ConstructL() |
|
101 { |
|
102 User::LeaveIfError(::FServSession.Connect()); |
|
103 } |
|
104 |
|
105 void CTDefect2::RunTestCaseL(TInt aCurTestCase) |
|
106 { |
|
107 ((CTDefect2Step*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); |
|
108 _LIT(KTest1,"SubTest %d: DEF039237"); |
|
109 _LIT(KTest2,"SubTest %d: DEF039331"); |
|
110 _LIT(KTest3,"SubTest %d: DEF039650"); |
|
111 _LIT(KTest4,"SubTest %d: CFbsBitmap::GetPixel() performance"); |
|
112 _LIT(KTest5,"SubTest %d: Rotate/Move text"); |
|
113 _LIT(KTest6,"SubTest %d: SwapWidthAndHeight"); |
|
114 _LIT(KTest7,"SubTest %d: Create multiple screens"); |
|
115 _LIT(KTest8,"SubTest %d: Clear with non-zero origin"); |
|
116 _LIT(KTest9,"SubTest %d: DEF115395: DrawBitmap & DrawBitmapMasked with a sourceRect out of the Bitmap bounds"); |
|
117 _LIT(KTest10,"SubTest %d: INC119063: General test CopyRect rewrite for low color depth (8,4,2, pixels per byte)"); |
|
118 _LIT(KTest11,"SubTest %d: INC120917: Dirty Mask Bitmap not remapped in BitBltMasked"); |
|
119 _LIT(KTest12,"SubTest %d: Zero-sized brush pattern bitmaps"); |
|
120 _LIT(KTest13,"SubTest %d: CopyRect with non-trivial alpha"); |
|
121 _LIT(KTest14,"SubTest %d: INC119063: CopyRect reading past end of bitmap data at unallocated pages"); |
|
122 _LIT(KTest15,"SubTest %d: INC128813 : CFbsBitGc::InternalizeL handle duplicate fail testing"); |
|
123 _LIT(KTest16,"SubTest %d: DEF132331 : CFbsScreenDevice PixelsToTwips conversions faulty with large inputs"); |
|
124 _LIT(KTest17,"SubTest %d: DEF137103: CFbsBitmapDevice::SetBits() should check bitmap size"); |
|
125 switch(aCurTestCase) |
|
126 { |
|
127 case 1: |
|
128 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0066")); |
|
129 INFO_PRINTF2(KTest1,aCurTestCase); |
|
130 DEF039237L(); |
|
131 break; |
|
132 case 2: |
|
133 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0067")); |
|
134 INFO_PRINTF2(KTest2,aCurTestCase); |
|
135 DEF039331L(); |
|
136 break; |
|
137 case 3: |
|
138 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0068")); |
|
139 INFO_PRINTF2(KTest3,aCurTestCase); |
|
140 DEF039650L(); |
|
141 break; |
|
142 case 4: |
|
143 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0069")); |
|
144 INFO_PRINTF2(KTest4,aCurTestCase); |
|
145 GetPixelPerformance1L(); |
|
146 break; |
|
147 case 5: |
|
148 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0070")); |
|
149 INFO_PRINTF2(KTest5,aCurTestCase); |
|
150 RotateMoveTextL(); |
|
151 break; |
|
152 case 6: |
|
153 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0071")); |
|
154 INFO_PRINTF2(KTest6,aCurTestCase); |
|
155 SwapWidthAndHeightL(); |
|
156 break; |
|
157 case 7: |
|
158 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0072")); |
|
159 INFO_PRINTF2(KTest7,aCurTestCase); |
|
160 CreateScreenDeviceL(); |
|
161 break; |
|
162 case 8: |
|
163 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0073")); |
|
164 INFO_PRINTF2(KTest8,aCurTestCase); |
|
165 NonZeroOriginClearL(); |
|
166 break; |
|
167 case 9: |
|
168 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0097")); |
|
169 INFO_PRINTF2(KTest9,aCurTestCase); |
|
170 DEF115395L(); |
|
171 break; |
|
172 case 10: |
|
173 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0099")); |
|
174 INFO_PRINTF2(KTest10,aCurTestCase); |
|
175 ExerciseCopyRect(); |
|
176 break; |
|
177 case 11: |
|
178 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0101")); |
|
179 INFO_PRINTF2(KTest11,aCurTestCase); |
|
180 TestDirtyMaskBitmapL(); |
|
181 break; |
|
182 case 12: |
|
183 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0108")); |
|
184 INFO_PRINTF2(KTest12,aCurTestCase); |
|
185 ZeroSizedPatternBrushL(); |
|
186 break; |
|
187 case 13: |
|
188 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0113")); |
|
189 INFO_PRINTF2(KTest13,aCurTestCase); |
|
190 CopyRectAlphaL(); |
|
191 break; |
|
192 case 14: |
|
193 //Note: This test generates panic windows... you may need to put your test before it. |
|
194 //They will be closed at the end of the test set, but they may get in the way of your next test, sorry. |
|
195 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0098")); |
|
196 INFO_PRINTF2(KTest14,aCurTestCase); |
|
197 CopyRectReadOutsideBitmap(); |
|
198 break; |
|
199 case 15: |
|
200 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0110")); |
|
201 INFO_PRINTF2(KTest15,aCurTestCase); |
|
202 CFbsBitGcInternalizeLFailL(); |
|
203 break; |
|
204 case 16: |
|
205 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0111")); |
|
206 INFO_PRINTF2(KTest16,aCurTestCase); |
|
207 PixelsToTwipsConversionCheck(); |
|
208 break; |
|
209 case 17: |
|
210 ((CTDefect2Step*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0112")); |
|
211 INFO_PRINTF2(KTest17,aCurTestCase); |
|
212 TestSetBitsL(); |
|
213 break; |
|
214 |
|
215 case 18: |
|
216 INFO_PRINTF1(_L("PDEF141192: test CFbsBitGc::DrawBitmapMasked()")); |
|
217 INFO_PRINTF1(_L("Test Red Channel")); |
|
218 TestMaskForSelectedValuesL(0); |
|
219 INFO_PRINTF1(_L("Test Green Channel")); |
|
220 TestMaskForSelectedValuesL(1); |
|
221 INFO_PRINTF1(_L("Test Blue Channel")); |
|
222 TestMaskForSelectedValuesL(2); |
|
223 break; |
|
224 |
|
225 //Insert tests here |
|
226 |
|
227 case 19: |
|
228 ((CTDefect2Step*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); |
|
229 ((CTDefect2Step*)iStep)->CloseTMSGraphicsStep(); |
|
230 TestComplete(); |
|
231 break; |
|
232 } |
|
233 ((CTDefect2Step*)iStep)->RecordTestResultL(); |
|
234 } |
|
235 |
|
236 /** |
|
237 * @SYMTestCaseID GRAPHICS-BITGDI-0101 |
|
238 * |
|
239 * @SYMDEF INC120917 |
|
240 * |
|
241 * @SYMTestCaseDesc If mask bitmap has been dirtied (by resize/compress) |
|
242 * then bitbltmasked should not read old memory contents |
|
243 * |
|
244 * @SYMTestPriority Normal |
|
245 * |
|
246 * @SYMTestStatus Implemented |
|
247 * |
|
248 * @SYMTestActions Create image and mask bitmap with pattern and blit them for reference |
|
249 * create duplicate handle |
|
250 * resize the mask on duplicate |
|
251 * verify that blit produces same result for same area on larger mask |
|
252 * and change pattern |
|
253 * blit using duplicate handle and source |
|
254 * blit using original handle and source |
|
255 * in defect scenario these results are different (original same as reference) |
|
256 * in fix scenario they should be same (different to reference) |
|
257 * revalidate original handle reblit and verify now correct |
|
258 * |
|
259 * repeat above steps: |
|
260 * (this proves duplicate change causes original flag, not just duplication) |
|
261 * resize the mask on duplicate |
|
262 * verify that blit produces same result for same area on larger mask |
|
263 * and change pattern |
|
264 * blit using duplicate handle and source |
|
265 * blit using original handle and source |
|
266 * in defect scenario these results are different (original same as reference) |
|
267 * in fix scenario they should be same (different to reference) |
|
268 * revalidate original handle reblit and verify now correct |
|
269 */ |
|
270 void CTDefect2::TestDirtyMaskBitmapL() |
|
271 { |
|
272 const TInt KWidth=120; |
|
273 const TInt KHeight=50; |
|
274 const TInt KBigger=50; |
|
275 enum |
|
276 { |
|
277 EStepBefore=0, |
|
278 EStepVerifyDupGrow, |
|
279 EStepDupDiffAfterRefill, |
|
280 EStepOriginalDiffAfterRefill, |
|
281 EStepOriginalDiffAfterRefillAndGetAddress, |
|
282 EStepDupDiffAfterRefill2, |
|
283 EStepOriginalDiffAfterRefill2, |
|
284 ENumSteps |
|
285 }; |
|
286 TInt pushcount=0; |
|
287 //set up the target |
|
288 CFbsBitmap* targetBmp=new(ELeave) CFbsBitmap(); |
|
289 CleanupStack::PushL(targetBmp);pushcount++; |
|
290 User::LeaveIfError(targetBmp->Create(TSize(KWidth,KHeight*ENumSteps), EColor16MU)); |
|
291 CFbsBitmapDevice* bmpDevice=CFbsBitmapDevice::NewL(targetBmp); |
|
292 CleanupStack::PushL(bmpDevice);pushcount++; |
|
293 CBitmapContext* bmpContext; |
|
294 User::LeaveIfError(bmpDevice->CreateBitmapContext(bmpContext)); |
|
295 CleanupStack::PushL(bmpContext);pushcount++; |
|
296 bmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
297 bmpContext->SetBrushColor(KRgbRed); |
|
298 bmpContext->Clear(); |
|
299 |
|
300 //set up source and mask |
|
301 CFbsBitmap* sourceBmp=new(ELeave) CFbsBitmap(); |
|
302 CleanupStack::PushL(sourceBmp);pushcount++; |
|
303 User::LeaveIfError(sourceBmp->Create(TSize(KWidth,KHeight), EColor16MU)); |
|
304 TUint32* sourceData=sourceBmp->DataAddress(); |
|
305 TInt sourceLength=(sourceBmp->DataStride()>>2)*KHeight; |
|
306 CFbsBitmap* maskBmp=new(ELeave) CFbsBitmap(); |
|
307 CleanupStack::PushL(maskBmp);pushcount++; |
|
308 User::LeaveIfError(maskBmp->Create(TSize(KWidth,KHeight), EGray2)); |
|
309 TUint32* maskDataStart=maskBmp->DataAddress(); |
|
310 TInt maskLength=(maskBmp->DataStride()>>2)*KHeight; |
|
311 |
|
312 TUint32* targetData=targetBmp->DataAddress(); |
|
313 TInt targetCopySize=((targetBmp->DataStride()+3)>>2)*KHeight; |
|
314 |
|
315 TUint32 blueint=KRgbBlue.Color16MU(); |
|
316 for (TInt fillIndex=0;fillIndex<sourceLength;fillIndex++) |
|
317 { |
|
318 sourceData[fillIndex]=blueint; |
|
319 } |
|
320 TInt maskPattern=0x12345678; |
|
321 for (TInt fillIndex=0;fillIndex<maskLength;fillIndex++) |
|
322 { |
|
323 maskDataStart[fillIndex]=maskPattern; |
|
324 } |
|
325 |
|
326 //Initial result of blit operation |
|
327 bmpContext->BitBltMasked(TPoint(0,KHeight*EStepBefore),sourceBmp,TSize(KWidth,KHeight),maskBmp,EFalse); |
|
328 |
|
329 //duplicate the mask handle |
|
330 CFbsBitmap* maskBmpDup=new(ELeave) CFbsBitmap(); |
|
331 CleanupStack::PushL(maskBmpDup);pushcount++; |
|
332 maskBmpDup->Duplicate(maskBmp->Handle()); |
|
333 TUint32* maskDataDup=maskBmpDup->DataAddress(); |
|
334 TEST(maskDataDup==maskDataStart); //not expected to fail |
|
335 //resize duplicate handle bigger |
|
336 maskBmpDup->Resize(TSize(KWidth+KBigger,KHeight)); |
|
337 maskDataDup=maskBmpDup->DataAddress(); |
|
338 TEST(maskDataDup!=maskDataStart); //not expected to fail |
|
339 |
|
340 //At this point the duplicate handle is referencing a different address to the original handle. |
|
341 //With the defect in place this remains uncorrected, |
|
342 //and is demonstrated by comparing the output contents of blitting using each of the handles. |
|
343 |
|
344 //verify that the resizing of the mask preserved the original mask data, so the resize has no effect on small area blit |
|
345 bmpContext->BitBltMasked(TPoint(0,KHeight*EStepVerifyDupGrow),sourceBmp,TSize(KWidth,KHeight),maskBmpDup,EFalse); |
|
346 |
|
347 //If this cmp fails: blit or resize is not working properly on the duplicate handle - not caused by this defect (very unexpected) |
|
348 TEST(0==Mem::Compare((TUint8*)(targetData),targetCopySize*4,(TUint8*)(targetData+targetCopySize*EStepVerifyDupGrow),targetCopySize*4)); |
|
349 |
|
350 //Change the mask using the address in the duplicate handle |
|
351 //As we want to fill the whole mask with a known pattern we need to recalculate the mask size. |
|
352 TInt newMaskLength=(maskBmpDup->DataStride()>>2)*KHeight; |
|
353 maskPattern=0xAAAAAAAA; |
|
354 for (TInt fillIndex=0;fillIndex<newMaskLength;fillIndex++) |
|
355 { |
|
356 maskDataDup[fillIndex]=maskPattern; |
|
357 } |
|
358 |
|
359 //compare the results of blitting using this new mask using each of the two handles to the same mask |
|
360 bmpContext->BitBltMasked(TPoint(0,KHeight*EStepDupDiffAfterRefill),sourceBmp,TSize(KWidth,KHeight),maskBmpDup,EFalse); |
|
361 //This blit should not crash, even if the defect is present because the previous sized bitmap should not be released until all references have been updated. |
|
362 |
|
363 bmpContext->BitBltMasked(TPoint(0,KHeight*EStepOriginalDiffAfterRefill),sourceBmp,TSize(KWidth,KHeight),maskBmp,EFalse); |
|
364 |
|
365 //If this cmp fails: data change had no effect for duplicate handle (very unexpected) |
|
366 TEST(0!=Mem::Compare((TUint8*)(targetData),targetCopySize*4,(TUint8*)(targetData+targetCopySize*EStepDupDiffAfterRefill),targetCopySize*4)); |
|
367 |
|
368 //Check that the result of both blits is the same. |
|
369 //If this cmp fails: defect is demonstrated. This is the main defect demonstration test. |
|
370 TEST(0==Mem::Compare((TUint8*)(targetData+targetCopySize*EStepDupDiffAfterRefill),targetCopySize*4,(TUint8*)(targetData+targetCopySize*EStepOriginalDiffAfterRefill),targetCopySize*4)); |
|
371 |
|
372 //This revalidates the original handle, hiding the defect |
|
373 TUint32* maskDataRevalid=maskBmp->DataAddress(); |
|
374 TEST(maskDataDup==maskDataRevalid); |
|
375 |
|
376 //This blit should not crash as the original handle has now been revalidated to point to allocated data. |
|
377 bmpContext->BitBltMasked(TPoint(0,KHeight*EStepOriginalDiffAfterRefillAndGetAddress),sourceBmp,TSize(KWidth,KHeight),maskBmp,EFalse); |
|
378 //If this cmp fails: original was not revalidated by DataAddress - content is not same as duplicate |
|
379 TEST(0==Mem::Compare((TUint8*)(targetData+targetCopySize*EStepDupDiffAfterRefill),targetCopySize*4,(TUint8*)(targetData+targetCopySize*EStepOriginalDiffAfterRefillAndGetAddress),targetCopySize*4)); |
|
380 |
|
381 //Extra testing... do we handle situation where the duplicated handle is changed more than once? |
|
382 |
|
383 //Basically repeats the test sequence above. |
|
384 |
|
385 //Repeat the resize even bigger using duplicate handle |
|
386 //resize duplicate handle bigger |
|
387 maskBmpDup->Resize(TSize(KWidth+KBigger,KHeight+KBigger)); |
|
388 maskDataDup=maskBmpDup->DataAddress(); |
|
389 TEST(maskDataDup!=maskDataRevalid); |
|
390 |
|
391 //Change the mask using the address in the duplicate handle |
|
392 //As we want to fill the whole mask with a known pattern we need to recalculate the mask size. |
|
393 newMaskLength=(maskBmpDup->DataStride()>>2)*(KHeight+KBigger); |
|
394 maskPattern=0x55555555; |
|
395 for (TInt fillIndex=0;fillIndex<newMaskLength;fillIndex++) |
|
396 { |
|
397 maskDataDup[fillIndex]=maskPattern; |
|
398 } |
|
399 |
|
400 //compare the results of blitting using this new mask using each of the two handles to the same mask |
|
401 |
|
402 bmpContext->BitBltMasked(TPoint(0,KHeight*EStepDupDiffAfterRefill2),sourceBmp,TSize(KWidth,KHeight),maskBmpDup,EFalse); |
|
403 //This blit should not crash, even if the defect is present because the previous sized bitmap should not be released until all references have been updated. |
|
404 //If it does crash then this demonstrates the defect in that the original address is being used in error and has been freed and paged out |
|
405 bmpContext->BitBltMasked(TPoint(0,KHeight*EStepOriginalDiffAfterRefill2),sourceBmp,TSize(KWidth,KHeight),maskBmp,EFalse); |
|
406 |
|
407 //If this cmp fails: data change had no effect for duplicate handle (very unexpected) |
|
408 TEST(0!=Mem::Compare((TUint8*)(targetData+targetCopySize*EStepDupDiffAfterRefill),targetCopySize*4,(TUint8*)(targetData+targetCopySize*EStepDupDiffAfterRefill2),targetCopySize*4)); |
|
409 |
|
410 //Check that the result of both blits is the same. |
|
411 //If this cmp fails: defect is demonstrated. This is the main defect demonstration test. |
|
412 TEST(0==Mem::Compare((TUint8*)(targetData+targetCopySize*EStepDupDiffAfterRefill2),targetCopySize*4,(TUint8*)(targetData+targetCopySize*EStepOriginalDiffAfterRefill2),targetCopySize*4)); |
|
413 |
|
414 |
|
415 CleanupStack::PopAndDestroy(pushcount,targetBmp); |
|
416 } |
|
417 |
|
418 /** |
|
419 * @SYMTestCaseID GRAPHICS-BITGDI-0097 |
|
420 * |
|
421 * @SYMDEF DEF115395 |
|
422 * |
|
423 * @SYMTestCaseDesc Robustness in the CFbsBitGc::DrawBitmap & CFbsBitGc::DrawBitmapMasked functions: |
|
424 * when a sourceRect is used to capture only a part of the bitmap, |
|
425 * we have to make sure that the sourceRect is not out of border of the image! |
|
426 * (if it's the case, we just draw nothing) |
|
427 * |
|
428 * @SYMTestPriority Normal |
|
429 * |
|
430 * @SYMTestStatus Implemented |
|
431 * |
|
432 * @SYMTestActions We create a 8x8 KRgbRed Bitmap and 8x8 Mask (color TRgb(30, 30, 30)) |
|
433 * We try the 2 functions CFbsBitGc::DrawBitmap and CFbsBitGc::DrawBitmapMasked |
|
434 * with a out of bounds source rectangle on a white output image. |
|
435 * The output should stay all white. |
|
436 * |
|
437 */ |
|
438 void CTDefect2::DEF115395L() |
|
439 { |
|
440 const TSize size=TSize(8, 8); |
|
441 const TPoint origin=TPoint(0, 0); |
|
442 const TPoint vector=TPoint(2, 2); |
|
443 const TRect destRect=TRect(origin, size); |
|
444 const TRect srcRect=TRect(origin-vector, size); |
|
445 const TBool invertMask=EFalse; |
|
446 const TRgb maskColor=TRgb(30, 30, 30); |
|
447 TBool succeed=ETrue; |
|
448 |
|
449 // Bitmap creation |
|
450 CFbsBitmap* myBmp=new(ELeave) CFbsBitmap(); |
|
451 CleanupStack::PushL(myBmp); |
|
452 User::LeaveIfError(myBmp->Create(size, EColor16MU)); |
|
453 CFbsBitmapDevice* bmpDevice=CFbsBitmapDevice::NewL(myBmp); |
|
454 CleanupStack::PushL(bmpDevice); |
|
455 CBitmapContext* bmpContext; |
|
456 User::LeaveIfError(bmpDevice->CreateBitmapContext(bmpContext)); |
|
457 CleanupStack::PushL(bmpContext); |
|
458 bmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
459 bmpContext->SetBrushColor(KRgbRed); |
|
460 bmpContext->Clear(); |
|
461 CleanupStack::PopAndDestroy(2, bmpDevice); // bmpContext, bmpDevice |
|
462 |
|
463 // Mask creation |
|
464 CFbsBitmap* myMaskBmp=new(ELeave) CFbsBitmap(); |
|
465 CleanupStack::PushL(myMaskBmp); |
|
466 User::LeaveIfError(myMaskBmp->Create(size, EGray256)); |
|
467 bmpDevice = CFbsBitmapDevice::NewL(myMaskBmp); |
|
468 CleanupStack::PushL(bmpDevice); |
|
469 User::LeaveIfError(bmpDevice->CreateBitmapContext(bmpContext)); |
|
470 CleanupStack::PushL(bmpContext); |
|
471 bmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
472 bmpContext->SetBrushColor(maskColor); |
|
473 bmpContext->Clear(); |
|
474 CleanupStack::PopAndDestroy(2, bmpDevice); // bmpContext, bmpDevice |
|
475 |
|
476 // Output Image |
|
477 CFbsBitmap* outputImg=new(ELeave) CFbsBitmap(); |
|
478 CleanupStack::PushL(outputImg); |
|
479 User::LeaveIfError(outputImg->Create(size, EColor16MU)); |
|
480 bmpDevice = CFbsBitmapDevice::NewL(outputImg); |
|
481 CleanupStack::PushL(bmpDevice); |
|
482 User::LeaveIfError(bmpDevice->CreateBitmapContext(bmpContext)); |
|
483 CleanupStack::PushL(bmpContext); |
|
484 bmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
485 bmpContext->SetBrushColor(KRgbWhite); |
|
486 bmpContext->Clear(); |
|
487 |
|
488 bmpContext->DrawBitmapMasked(destRect, myBmp, srcRect, myMaskBmp, invertMask); |
|
489 TRgb pixelColor; |
|
490 TInt ii,jj; |
|
491 for (ii=0;ii<=size.iWidth;ii++) |
|
492 { |
|
493 for (jj=0;jj<=size.iHeight;jj++) |
|
494 { |
|
495 outputImg->GetPixel(pixelColor, TPoint(ii,jj)); |
|
496 if (pixelColor!=KRgbWhite) |
|
497 { |
|
498 succeed=EFalse; |
|
499 break; |
|
500 } |
|
501 } |
|
502 if (!succeed) |
|
503 { |
|
504 break; |
|
505 } |
|
506 } |
|
507 |
|
508 bmpContext->Clear(); |
|
509 bmpContext->DrawBitmap(destRect, myBmp, srcRect); |
|
510 for (ii=0;ii<=size.iWidth;ii++) |
|
511 { |
|
512 for (jj=0;jj<=size.iHeight;jj++) |
|
513 { |
|
514 outputImg->GetPixel(pixelColor, TPoint(ii,jj)); |
|
515 if (pixelColor!=KRgbWhite) |
|
516 { |
|
517 succeed=EFalse; |
|
518 break; |
|
519 } |
|
520 } |
|
521 if (!succeed) |
|
522 { |
|
523 break; |
|
524 } |
|
525 } |
|
526 |
|
527 TEST(succeed); |
|
528 CleanupStack::PopAndDestroy(5); |
|
529 } |
|
530 |
|
531 /** |
|
532 @SYMDEF PDEF141192, INC140310 |
|
533 |
|
534 @SYMTestCaseDesc Test that the alpha merge method CFbsBitGc::DrawBitmapMasked() works accurately. |
|
535 |
|
536 @SYMTestPriority normal |
|
537 |
|
538 @SYMTestStatus Implemented |
|
539 |
|
540 @SYMTestActions Create an alpha capable bitmap and throw sample values at the merge function |
|
541 |
|
542 @SYMTestExpectedResults |
|
543 1a) The merge resultant alpha values do not wrap through 256 |
|
544 1b) The merge resultant alpha values closely match an equivalent floating-point calculation |
|
545 2a) The merge resultant colours do not wrap through 256 |
|
546 2b) The merge resultant colours do not exceed the resultant alpha if premultiplied output is expected |
|
547 2c) The merge resultant colours closely match an equivalent floating-point calculation |
|
548 2d) The other resultant colour values are not affected (stay black) |
|
549 |
|
550 @param aChannelControl which channel is controlled (0=red, 1= green, 2=blue) |
|
551 |
|
552 The input tested format is EColor64K, but could easily be changesd to test other formats. |
|
553 The input mask is EGray256. If optimised internally, this could be changed to EGray16. |
|
554 The tested output format is EColor16MAP. This should not be changed. |
|
555 |
|
556 This test is an optimised version of CTDefect2::TestMaskForAllCombinationL(TInt aChannelControl) |
|
557 */ |
|
558 void CTDefect2::TestMaskForSelectedValuesL(TInt aChannelControl) |
|
559 { |
|
560 const TSize size=TSize(1, 1); |
|
561 |
|
562 // Bitmap creation |
|
563 CFbsBitmap* srcBmp=new(ELeave) CFbsBitmap(); |
|
564 CleanupStack::PushL(srcBmp); |
|
565 User::LeaveIfError(srcBmp->Create(size, EColor64K)); |
|
566 CFbsBitmapDevice* sourceBmpDevice=CFbsBitmapDevice::NewL(srcBmp); |
|
567 CleanupStack::PushL(sourceBmpDevice); |
|
568 CBitmapContext* sourceBmpContext; |
|
569 User::LeaveIfError(sourceBmpDevice->CreateBitmapContext(sourceBmpContext)); |
|
570 CleanupStack::PushL(sourceBmpContext); |
|
571 sourceBmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
572 sourceBmpContext->Clear(); |
|
573 CleanupStack::PopAndDestroy(2, sourceBmpDevice); // sourceBmpContext, sourceBmpDevice |
|
574 |
|
575 // Mask creation |
|
576 CFbsBitmap* maskBmp=new(ELeave) CFbsBitmap(); |
|
577 CleanupStack::PushL(maskBmp); |
|
578 User::LeaveIfError(maskBmp->Create(size, EGray256)); |
|
579 CFbsBitmapDevice* maskBmpDevice=CFbsBitmapDevice::NewL(maskBmp); |
|
580 CleanupStack::PushL(maskBmpDevice); |
|
581 CBitmapContext* maskBmpContext; |
|
582 User::LeaveIfError(maskBmpDevice->CreateBitmapContext(maskBmpContext)); |
|
583 CleanupStack::PushL(maskBmpContext); |
|
584 maskBmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
585 maskBmpContext->Clear(); |
|
586 CleanupStack::PopAndDestroy(2, maskBmpDevice); // maskBmpContext, maskBmpDevice |
|
587 |
|
588 // Target Bitmap |
|
589 CFbsBitmap* targetBmp=new(ELeave) CFbsBitmap(); |
|
590 CleanupStack::PushL(targetBmp); |
|
591 User::LeaveIfError(targetBmp->Create(size, EColor16MAP)); |
|
592 CFbsBitmapDevice* targetBmpDevice=CFbsBitmapDevice::NewL(targetBmp); |
|
593 CleanupStack::PushL(targetBmpDevice); |
|
594 CBitmapContext* targetBmpContext; |
|
595 User::LeaveIfError(targetBmpDevice->CreateBitmapContext(targetBmpContext)); |
|
596 CleanupStack::PushL(targetBmpContext); |
|
597 targetBmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
598 targetBmpContext->Clear(); |
|
599 |
|
600 TSize screenSize = targetBmpDevice->SizeInPixels(); |
|
601 |
|
602 TInt channelMask; |
|
603 TInt channelMul; |
|
604 |
|
605 if (aChannelControl<1) |
|
606 { |
|
607 channelMask=0xFF0000; |
|
608 } |
|
609 else |
|
610 { |
|
611 if(aChannelControl==1) |
|
612 { |
|
613 channelMask=0x00FF00; |
|
614 } |
|
615 else |
|
616 { |
|
617 channelMask=0x0000FF; |
|
618 } |
|
619 } |
|
620 channelMul=channelMask&0x01010101; |
|
621 TInt previousTargetMask = -1; |
|
622 const TInt otherMask=0xFFFFFF^channelMask; |
|
623 |
|
624 for (TInt targetMask=0;targetMask<256;targetMask++) |
|
625 { |
|
626 //bkgrdChannel is background channel input value. |
|
627 for (TInt targetChannel=0;targetChannel<=targetMask;targetChannel++) |
|
628 { |
|
629 if(targetChannel>(targetMask-10)) // Optimise the loop to test values specific for this defect |
|
630 { |
|
631 TInt failsPerPass=10; |
|
632 |
|
633 //srcMask is the source mask/alpha |
|
634 for (TInt srcMask=0;srcMask<256;srcMask++) |
|
635 { |
|
636 if((srcMask<=10)||(srcMask>=250)) // Optimise the loop to test values specific for this defect |
|
637 { |
|
638 TReal step; |
|
639 if (aChannelControl == 1) |
|
640 { |
|
641 step = 255.0/63; // Only for blue channel for EColor64K source colour |
|
642 } |
|
643 else |
|
644 { |
|
645 step = 255.0/31; |
|
646 } |
|
647 TReal srcChannelReal = 0.0; |
|
648 for (TInt srcChannel=0;srcChannel<256;srcChannel=(TInt)srcChannelReal) |
|
649 { |
|
650 if (targetMask != previousTargetMask) |
|
651 { |
|
652 //uncomment it to print log for each targetMask loop |
|
653 //INFO_PRINTF2(_L("Processing source colours for targetMask=%i"),targetMask); |
|
654 previousTargetMask = targetMask; |
|
655 } |
|
656 srcChannelReal += step; |
|
657 |
|
658 //test blending of one-pixel bitmap |
|
659 DoMaskTestL(srcChannel, srcMask, targetMask, targetChannel, aChannelControl, srcBmp, maskBmp, targetBmp, targetBmpContext); |
|
660 |
|
661 TBuf8<4> readBuffer; |
|
662 TUint* readPixel = (TUint*)readBuffer.Ptr(); |
|
663 targetBmp->GetScanLine(readBuffer, TPoint(0, 0), 1, EColor16MAP); |
|
664 |
|
665 //channelPixelValue is the channel pixel value as generated from the library code under test |
|
666 TUint channelPixelValue=((*readPixel)&channelMask)/channelMul; |
|
667 //alphaPixelValue is the alpha pixel value as generated from the library code under test |
|
668 TUint alphaPixelValue = (*readPixel)>>24; |
|
669 |
|
670 //check if channelPixelValue and alphaPixelValue match the expected ones |
|
671 CheckValues(alphaPixelValue, channelPixelValue, failsPerPass, targetMask, targetChannel, srcMask, srcChannel, otherMask, readPixel); |
|
672 } |
|
673 } |
|
674 } |
|
675 if (failsPerPass<0) |
|
676 { //note that this count may be out by 1... |
|
677 INFO_PRINTF2(_L("Additional %i errors not reported in this pass."),-failsPerPass); |
|
678 } |
|
679 } |
|
680 } |
|
681 } |
|
682 CleanupStack::PopAndDestroy(5); |
|
683 } |
|
684 |
|
685 void CTDefect2::CheckValues(TUint aAlphaPixelValue, TUint aChannelPixelValue, TInt& aFailsPerPass, TInt aTargetMask, TInt aTargetChannel, TInt aSrcMask, TInt aSrcChannel, TInt aOtherMask, TUint* aReadPixel) |
|
686 { |
|
687 const TReal KGross=1.95; |
|
688 TReal srcMultiplier; |
|
689 TReal alphaOutputValue; |
|
690 //source multiplier factor for alpha that can then be used to optimise non-multiplied input calculations. |
|
691 srcMultiplier=aSrcMask/255.0; |
|
692 //destination/background multiplier factor for alpha that can then be used to optimise non-multiplied input calculations. |
|
693 TReal destMultiplier=(aTargetMask/255.0)*(1.0-srcMultiplier); |
|
694 //alphaOutputValue is a floating-point calculation of the alpha output value using 255.0 as the scaling factor. |
|
695 alphaOutputValue=(srcMultiplier+destMultiplier)*255.0; |
|
696 |
|
697 //alphaDiff is the difference in alpha between pixel and float calcuation, i.e. the error. This can be less than 1 level of brightness, i.e. insignificant. |
|
698 TReal alphaDiff=0.0; |
|
699 alphaDiff=alphaOutputValue-aAlphaPixelValue; |
|
700 if (alphaDiff>KGross || alphaDiff<-KGross) |
|
701 { |
|
702 if (--aFailsPerPass>0) |
|
703 { |
|
704 LogColourEvent(aTargetMask,aTargetChannel,aSrcMask,-1,alphaOutputValue,aAlphaPixelValue,alphaDiff,_L("Big Alpha error: expected %f, got %f"),ETrue); |
|
705 } |
|
706 } |
|
707 //channelOutputValue is a floating-point calculation of the channel output value using 255.0 as the scaling factor. |
|
708 TReal channelOutputValue=aSrcChannel*srcMultiplier; |
|
709 channelOutputValue+=aTargetChannel*(1.0-srcMultiplier); |
|
710 |
|
711 if (aChannelPixelValue>aAlphaPixelValue) |
|
712 { |
|
713 if (--aFailsPerPass>0) |
|
714 { |
|
715 LogColourEvent(aTargetMask,aTargetChannel,aSrcMask,aSrcChannel,aAlphaPixelValue,channelOutputValue,aChannelPixelValue,_L("Output multiplied colour exceeds alpha %f: expected %f got %f"),EFalse); |
|
716 INFO_PRINTF1(_L("channelPixelValue>alphaPixelValue")); |
|
717 } |
|
718 } |
|
719 |
|
720 if((aOtherMask&(*aReadPixel))!=0) |
|
721 { |
|
722 if (--aFailsPerPass>0) |
|
723 { |
|
724 LogColourEvent(aTargetMask,aTargetChannel,aSrcMask,aSrcChannel,aAlphaPixelValue,channelOutputValue,aChannelPixelValue,_L("Other colours damaged - NOT Zero"),EFalse); |
|
725 } |
|
726 } |
|
727 |
|
728 //channelDiff is the difference in channel between pixel and float calcuation, i.e. the error. This can be less than 1 level of brightness, i.e. insignificant. |
|
729 TReal channelDiff=channelOutputValue-aChannelPixelValue; |
|
730 |
|
731 if (channelDiff>KGross || channelDiff<-KGross) |
|
732 { |
|
733 if (--aFailsPerPass>0) |
|
734 { |
|
735 LogColourEvent(aTargetMask,aTargetChannel,aSrcMask,aSrcChannel,channelOutputValue,aChannelPixelValue,channelDiff,_L("Big Colour error: expected %f, got %f"),EFalse); |
|
736 } |
|
737 } |
|
738 } |
|
739 |
|
740 /** |
|
741 Test of Blending function DrawBitmapMasked(). |
|
742 @param aSrcChannel source channel |
|
743 @param aSrcMask source mask |
|
744 @param aTargetMask target mask |
|
745 @param aTargetChannel target channel |
|
746 @param aChannelControl which channel is controlled (0=red, 1= green, 2=blue) |
|
747 @param aSrcBmp source bitmap |
|
748 @param aMaskBmp mask bitmap |
|
749 @param aTargetBmp target bitmap |
|
750 @param aTargetBmpContext gc for target bitmap |
|
751 **/ |
|
752 void CTDefect2::DoMaskTestL(TInt aSrcChannel, TInt aSrcMask, TInt aTargetMask, TInt aTargetChannel, TInt aChannelControl, |
|
753 CFbsBitmap* aSrcBmp, CFbsBitmap* aMaskBmp, CFbsBitmap* aTargetBmp, CBitmapContext* aTargetBmpContext) |
|
754 { |
|
755 const TSize size=TSize(1, 1); |
|
756 const TRect destRect=TRect(size); |
|
757 const TRect srcRect=TRect(size); |
|
758 |
|
759 const TInt scanLineLengthEColor16MAP = CFbsBitmap::ScanLineLength(1, EColor16MAP); |
|
760 HBufC8* targetBuffer = HBufC8::NewL(scanLineLengthEColor16MAP); |
|
761 CleanupStack::PushL(targetBuffer); |
|
762 TPtr8 targetDes = targetBuffer->Des(); |
|
763 targetDes.SetLength(scanLineLengthEColor16MAP); |
|
764 TUint32* targetP = (TUint32*)targetDes.Ptr(); |
|
765 TRgb targetColour(0, 0); |
|
766 if (aChannelControl<1) |
|
767 { |
|
768 targetColour.SetRed(aTargetChannel); |
|
769 } |
|
770 else |
|
771 { |
|
772 if (aChannelControl==1) |
|
773 { |
|
774 targetColour.SetGreen(aTargetChannel); |
|
775 } |
|
776 else |
|
777 { |
|
778 targetColour.SetBlue(aTargetChannel); |
|
779 } |
|
780 } |
|
781 targetColour.SetAlpha(aTargetMask); |
|
782 *targetP = targetColour.Internal(); |
|
783 aTargetBmp->SetScanLine(targetDes, 0); |
|
784 |
|
785 const TInt scanLineLengthEGray256 = CFbsBitmap::ScanLineLength(1, EGray256); |
|
786 HBufC8* maskBuffer = HBufC8::NewL(scanLineLengthEGray256); |
|
787 CleanupStack::PushL(maskBuffer); |
|
788 TPtr8 maskDes = maskBuffer->Des(); |
|
789 maskDes.SetLength(scanLineLengthEGray256); |
|
790 TUint8* maskP = (TUint8*)maskDes.Ptr(); |
|
791 *maskP = aSrcMask; |
|
792 aMaskBmp->SetScanLine(maskDes, 0); |
|
793 |
|
794 const TInt scanLineLengthEColor64K = CFbsBitmap::ScanLineLength(1, EColor64K); |
|
795 HBufC8* srcBuffer = HBufC8::NewL(scanLineLengthEColor64K); |
|
796 CleanupStack::PushL(srcBuffer); |
|
797 TPtr8 srcDes = srcBuffer->Des(); |
|
798 srcDes.SetLength(scanLineLengthEColor64K); |
|
799 TUint16* srcP = (TUint16*)srcDes.Ptr(); |
|
800 TRgb srcColour(0); |
|
801 if (aChannelControl<1) |
|
802 { |
|
803 srcColour.SetRed(aSrcChannel); |
|
804 } |
|
805 else |
|
806 { |
|
807 if (aChannelControl==1) |
|
808 { |
|
809 srcColour.SetGreen(aSrcChannel); |
|
810 } |
|
811 else |
|
812 { |
|
813 srcColour.SetBlue(aSrcChannel); |
|
814 } |
|
815 } |
|
816 |
|
817 *srcP = srcColour.Color64K(); |
|
818 aSrcBmp->SetScanLine(srcDes, 0); |
|
819 aTargetBmpContext->DrawBitmapMasked(destRect, aSrcBmp, srcRect, aMaskBmp, EFalse); |
|
820 |
|
821 CleanupStack::PopAndDestroy(3); |
|
822 } |
|
823 |
|
824 /** |
|
825 @SYMDEF PDEF141192, INC140310 |
|
826 |
|
827 @SYMTestCaseDesc Test that the alpha merge method CFbsBitGc::DrawBitmapMasked() works accurately. |
|
828 |
|
829 @SYMTestPriority normal |
|
830 |
|
831 @SYMTestStatus Implemented |
|
832 |
|
833 @SYMTestActions Create an alpha capable bitmap and throw sample values at the merge function |
|
834 |
|
835 @SYMTestExpectedResults |
|
836 1a) The merge resultant alpha values do not wrap through 256 |
|
837 1b) The merge resultant alpha values closely match an equivalent floating-point calculation |
|
838 2a) The merge resultant colours do not wrap through 256 |
|
839 2b) The merge resultant colours do not exceed the resultant alpha if premultiplied output is expected |
|
840 2c) The merge resultant colours closely match an equivalent floating-point calculation |
|
841 2d) The other resultant colour values are not affected (stay black) |
|
842 @param aChannelControl which channel is controlled (0=red, 1= green, 2=blue) |
|
843 |
|
844 The input tested format is EColor64K, but could easily be changesd to test other formats. |
|
845 The input mask is EGray256. If optimised internally, this could be changed to EGray16. |
|
846 The tested output format is EColor16MAP. This should not be changed. |
|
847 |
|
848 This test takes up to 40 minutes to run per channel control. Therefore, it is only kept for local reference, not scheduled for ONB. |
|
849 An optimised version CTDefect2::TestMaskForSelectedValuesL(TInt aChannelControl) is run instead for selected combinations of channel and mask values. |
|
850 */ |
|
851 void CTDefect2::TestMaskForAllCombinationL(TInt aChannelControl) |
|
852 { |
|
853 const TSize size=TSize(1, 1); |
|
854 |
|
855 // Bitmap creation |
|
856 CFbsBitmap* srcBmp=new(ELeave) CFbsBitmap(); |
|
857 CleanupStack::PushL(srcBmp); |
|
858 User::LeaveIfError(srcBmp->Create(size, EColor64K)); |
|
859 CFbsBitmapDevice* sourceBmpDevice=CFbsBitmapDevice::NewL(srcBmp); |
|
860 CleanupStack::PushL(sourceBmpDevice); |
|
861 CBitmapContext* sourceBmpContext; |
|
862 User::LeaveIfError(sourceBmpDevice->CreateBitmapContext(sourceBmpContext)); |
|
863 CleanupStack::PushL(sourceBmpContext); |
|
864 sourceBmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
865 sourceBmpContext->Clear(); |
|
866 CleanupStack::PopAndDestroy(2, sourceBmpDevice); // sourceBmpContext, sourceBmpDevice |
|
867 |
|
868 // Mask creation |
|
869 CFbsBitmap* maskBmp=new(ELeave) CFbsBitmap(); |
|
870 CleanupStack::PushL(maskBmp); |
|
871 User::LeaveIfError(maskBmp->Create(size, EGray256)); |
|
872 CFbsBitmapDevice* maskBmpDevice=CFbsBitmapDevice::NewL(maskBmp); |
|
873 CleanupStack::PushL(maskBmpDevice); |
|
874 CBitmapContext* maskBmpContext; |
|
875 User::LeaveIfError(maskBmpDevice->CreateBitmapContext(maskBmpContext)); |
|
876 CleanupStack::PushL(maskBmpContext); |
|
877 maskBmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
878 maskBmpContext->Clear(); |
|
879 CleanupStack::PopAndDestroy(2, maskBmpDevice); // maskBmpContext, maskBmpDevice |
|
880 |
|
881 // Target Bitmap |
|
882 CFbsBitmap* targetBmp=new(ELeave) CFbsBitmap(); |
|
883 CleanupStack::PushL(targetBmp); |
|
884 User::LeaveIfError(targetBmp->Create(size, EColor16MAP)); |
|
885 CFbsBitmapDevice* targetBmpDevice=CFbsBitmapDevice::NewL(targetBmp); |
|
886 CleanupStack::PushL(targetBmpDevice); |
|
887 CBitmapContext* targetBmpContext; |
|
888 User::LeaveIfError(targetBmpDevice->CreateBitmapContext(targetBmpContext)); |
|
889 CleanupStack::PushL(targetBmpContext); |
|
890 targetBmpContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
891 targetBmpContext->Clear(); |
|
892 |
|
893 TSize screenSize = targetBmpDevice->SizeInPixels(); |
|
894 |
|
895 TInt channelMask; |
|
896 TInt channelMul; |
|
897 |
|
898 if (aChannelControl<1) |
|
899 { |
|
900 channelMask=0xFF0000; |
|
901 } |
|
902 else |
|
903 { |
|
904 if(aChannelControl==1) |
|
905 { |
|
906 channelMask=0x00FF00; |
|
907 } |
|
908 else |
|
909 { |
|
910 channelMask=0x0000FF; |
|
911 } |
|
912 } |
|
913 channelMul=channelMask&0x01010101; |
|
914 TInt previousTargetMask = -1; |
|
915 const TInt otherMask=0xFFFFFF^channelMask; |
|
916 |
|
917 for (TInt targetMask=0;targetMask<256;targetMask++) |
|
918 { |
|
919 //bkgrdChannel is background channel input value. |
|
920 for (TInt targetChannel=0;targetChannel<=targetMask;targetChannel++) |
|
921 { |
|
922 TInt failsPerPass=10; |
|
923 |
|
924 //srcMask is the source mask/alpha |
|
925 for (TInt srcMask=0;srcMask<256;srcMask++) |
|
926 { |
|
927 TReal step; |
|
928 if (aChannelControl == 1) |
|
929 { |
|
930 step = 255.0/63; // Only for blue channel for EColor64K source colour |
|
931 } |
|
932 else |
|
933 { |
|
934 step = 255.0/31; |
|
935 } |
|
936 TReal srcChannelReal = 0.0; |
|
937 |
|
938 for (TInt srcChannel=0;srcChannel<256;srcChannel=(TInt)srcChannelReal) |
|
939 { |
|
940 if (targetMask != previousTargetMask) |
|
941 { |
|
942 INFO_PRINTF2(_L("Processing source colours for targetMask=%i"),targetMask); |
|
943 previousTargetMask = targetMask; |
|
944 } |
|
945 srcChannelReal += step; |
|
946 |
|
947 //test blending of one-pixel bitmap |
|
948 DoMaskTestL(srcChannel, srcMask, targetMask, targetChannel, aChannelControl, srcBmp, maskBmp, targetBmp, targetBmpContext); |
|
949 |
|
950 TBuf8<4> readBuffer; |
|
951 TUint* readPixel = (TUint*)readBuffer.Ptr(); |
|
952 targetBmp->GetScanLine(readBuffer, TPoint(0, 0), 1, EColor16MAP); |
|
953 |
|
954 //channelPixelValue is the channel pixel value as generated from the library code under test |
|
955 TUint channelPixelValue=((*readPixel)&channelMask)/channelMul; |
|
956 //alphaPixelValue is the alpha pixel value as generated from the library code under test |
|
957 TUint alphaPixelValue = (*readPixel)>>24; |
|
958 |
|
959 //check if channelPixelValue and alphaPixelValue match the expected ones |
|
960 CheckValues(alphaPixelValue, channelPixelValue, failsPerPass, targetMask, targetChannel, srcMask, srcChannel, otherMask, readPixel); |
|
961 |
|
962 if (failsPerPass<0) |
|
963 { //note that this count may be out by 1... |
|
964 INFO_PRINTF2(_L("Additional %i errors not reported in this pass."),-failsPerPass); |
|
965 } |
|
966 } |
|
967 } |
|
968 } |
|
969 } |
|
970 CleanupStack::PopAndDestroy(5); |
|
971 } |
|
972 |
|
973 /** |
|
974 This function is used to write to the log file |
|
975 @param aNonPreMulDestPixColor non pre multiplied destination pixel colour |
|
976 @param aPreMulSrcPixelColor pre multiplied source pixel colour |
|
977 @param aNonPreMulSrcPixelColor non pre multiplied source pixel colour |
|
978 @param aVal1 it contains the value of the first variable of the message to be displayed |
|
979 @param aVal2 it contains the value of the second variable of the message to be displayed |
|
980 @param aVal3 it contains the value of the third variable of the message to be displayed |
|
981 @param aMsg it contains the message to be printed to the log file |
|
982 @param aErr if true then the test case fails, if false test passes. log is printed in both the case. TEST does not abort, just reports test case failure |
|
983 */ |
|
984 void CTDefect2::LogColourEvent(TInt aPreMulDestPixColor,TInt aNonPreMulDestPixColor,TInt aPreMulSrcPixelColor,TInt aNonPreMulSrcPixelColor,TReal aVal1,TReal aVal2,TReal aVal3,TRefByValue<const TDesC> aMsg,TBool aErr) |
|
985 { |
|
986 TEST(aErr==EFalse); // if aErr=True, then the previous test step failed. |
|
987 INFO_PRINTF4(aMsg,aVal1,aVal2,aVal3); |
|
988 if (aNonPreMulSrcPixelColor<0) |
|
989 { |
|
990 INFO_PRINTF4(_L("Processing source colours for MDest=%i, CDest=%i, MSrc=%i"),aPreMulDestPixColor,aNonPreMulDestPixColor,aPreMulSrcPixelColor); |
|
991 } |
|
992 else |
|
993 { |
|
994 INFO_PRINTF5(_L("Processing colour set MDest=%i, CDest=%i, MSrc=%i, CSrc=%i"),aPreMulDestPixColor,aNonPreMulDestPixColor,aPreMulSrcPixelColor,aNonPreMulSrcPixelColor); |
|
995 } |
|
996 } |
|
997 |
|
998 class TFunctionThread |
|
999 { |
|
1000 protected: |
|
1001 TFunctionThread():iExitHow(ENotStarted) |
|
1002 {} |
|
1003 TInt LaunchThreadFunction(const TDesC& aName); |
|
1004 private: |
|
1005 static TInt TheThreadFunction(TAny*); |
|
1006 virtual TInt ThreadFunctionL()=0; |
|
1007 public: |
|
1008 enum { |
|
1009 ENotStarted, |
|
1010 ERunning, //should never see this |
|
1011 EReturn, |
|
1012 ELeave, |
|
1013 EPanic, |
|
1014 ETerminate, |
|
1015 }; |
|
1016 TInt iExitHow; |
|
1017 TInt iExitCode; //Currently don't store the panic category string. |
|
1018 }; |
|
1019 |
|
1020 TInt TFunctionThread::LaunchThreadFunction(const TDesC& aName) |
|
1021 { |
|
1022 RThread thrd; |
|
1023 TRequestStatus stat; |
|
1024 enum { //8kb to 2mb |
|
1025 KMinHeapSize=0x2000, |
|
1026 KMaxHeapSize=0x200000 |
|
1027 }; |
|
1028 TInt created=thrd.Create(aName,TheThreadFunction,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,this); |
|
1029 if (created<KErrNone) |
|
1030 { |
|
1031 iExitCode=created; |
|
1032 return created; |
|
1033 } |
|
1034 thrd.SetPriority(EPriorityMuchMore); |
|
1035 thrd.Logon(stat); |
|
1036 User::SetJustInTime(EFalse); |
|
1037 thrd.Resume(); |
|
1038 User::WaitForRequest(stat); |
|
1039 if ( iExitHow!=ENotStarted || iExitHow==ERunning ) |
|
1040 { |
|
1041 iExitCode=thrd.ExitReason(); |
|
1042 switch (thrd.ExitType()) |
|
1043 { |
|
1044 case EExitKill: iExitHow=EReturn; break; |
|
1045 case EExitPanic: iExitHow=EPanic; break; |
|
1046 case EExitTerminate: iExitHow=ETerminate; break; |
|
1047 default: |
|
1048 ASSERT(EFalse); |
|
1049 } |
|
1050 } |
|
1051 thrd.Close(); |
|
1052 User::SetJustInTime(ETrue); |
|
1053 return KErrNone; |
|
1054 } |
|
1055 |
|
1056 TInt TFunctionThread::TheThreadFunction(TAny* aThis) |
|
1057 { |
|
1058 TFunctionThread* thisThis=(TFunctionThread*)aThis; |
|
1059 if (thisThis==NULL) |
|
1060 { |
|
1061 User::Panic(_L("NoThis"),0x1); |
|
1062 } |
|
1063 TInt leaveErr = RFbsSession::Connect(); |
|
1064 if (leaveErr != KErrNone) |
|
1065 { |
|
1066 thisThis->iExitHow = ELeave; |
|
1067 thisThis->iExitCode = leaveErr; |
|
1068 return leaveErr; |
|
1069 } |
|
1070 thisThis->iExitHow=thisThis->ERunning; |
|
1071 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
1072 TInt returnErr=KErrNone; |
|
1073 TRAP(leaveErr, returnErr = thisThis->ThreadFunctionL()); |
|
1074 if (leaveErr) |
|
1075 { |
|
1076 thisThis->iExitHow=ELeave; |
|
1077 thisThis->iExitCode=leaveErr; |
|
1078 delete cleanup; |
|
1079 RFbsSession::Disconnect(); |
|
1080 return leaveErr; |
|
1081 } |
|
1082 else |
|
1083 { |
|
1084 thisThis->iExitHow=EReturn; |
|
1085 thisThis->iExitCode=returnErr; |
|
1086 delete cleanup; |
|
1087 RFbsSession::Disconnect(); |
|
1088 return returnErr; |
|
1089 } |
|
1090 } |
|
1091 |
|
1092 /** This thread verifies whether a range of memory is accessible |
|
1093 The range is read sequentially until it panics, or the range is completed. |
|
1094 It is useful to input a range of addresses where some are valid and some fail |
|
1095 in order to demonstrate an edge against which an algorithm that performs illegal reads can subsequently be tested. |
|
1096 The FailOffset() returned index indicates the offset from the start at which the memory access caused a panic. |
|
1097 **/ |
|
1098 class TTestMemThread:public TFunctionThread |
|
1099 { |
|
1100 public: |
|
1101 TTestMemThread(TUint32* aStartAddress,TUint32* aEndAddress); |
|
1102 TInt FailOffset(); |
|
1103 private: |
|
1104 virtual TInt ThreadFunctionL(); |
|
1105 private: |
|
1106 TUint32* iStartAddress; |
|
1107 TUint32* iEndAddress; |
|
1108 volatile TUint32* iLastAddressTried; |
|
1109 volatile TUint32 iCopyValueHere; |
|
1110 |
|
1111 }; |
|
1112 |
|
1113 TTestMemThread::TTestMemThread(TUint32* aStartAddress,TUint32* aEndAddress): |
|
1114 iStartAddress(aStartAddress), |
|
1115 iEndAddress(aEndAddress), |
|
1116 iLastAddressTried(NULL) |
|
1117 { |
|
1118 ASSERT(aStartAddress); |
|
1119 ASSERT(aEndAddress); |
|
1120 LaunchThreadFunction(_L("MemTest")); |
|
1121 } |
|
1122 |
|
1123 /** |
|
1124 * Returns the number of successful memory reads before a panic occurred |
|
1125 * Or various error codes if the test didn't run or didn't panic. |
|
1126 * |
|
1127 **/ |
|
1128 TInt TTestMemThread::FailOffset() |
|
1129 { |
|
1130 if (iExitHow==EReturn) |
|
1131 { |
|
1132 return KErrCompletion; |
|
1133 } |
|
1134 else |
|
1135 { |
|
1136 if (iExitHow==EPanic) |
|
1137 { |
|
1138 if (iLastAddressTried) |
|
1139 { |
|
1140 TInt retval=iLastAddressTried-iStartAddress; |
|
1141 if (iEndAddress-iStartAddress<0) |
|
1142 { |
|
1143 retval=-retval; |
|
1144 } |
|
1145 if (retval<0) |
|
1146 { |
|
1147 return KErrCorrupt; |
|
1148 } |
|
1149 else |
|
1150 { |
|
1151 return retval; |
|
1152 } |
|
1153 } |
|
1154 else |
|
1155 { |
|
1156 return KErrNotFound; |
|
1157 } |
|
1158 } |
|
1159 else |
|
1160 { |
|
1161 return -iExitHow*100; |
|
1162 } |
|
1163 } |
|
1164 } |
|
1165 /* |
|
1166 * This thread function allows a test to verify that a particular address range |
|
1167 * is actually inaccessable. |
|
1168 * I.e. that attempting to read from the given address range causes a panic. |
|
1169 */ |
|
1170 TInt TTestMemThread::ThreadFunctionL() |
|
1171 { |
|
1172 if (iStartAddress && iEndAddress) |
|
1173 { |
|
1174 TInt delta=1; |
|
1175 if (iStartAddress>iEndAddress) |
|
1176 { |
|
1177 delta=-1; |
|
1178 } |
|
1179 for (TUint32 volatile* tryAddress=iStartAddress;tryAddress!=iEndAddress;tryAddress+=delta) |
|
1180 { |
|
1181 iLastAddressTried=tryAddress; |
|
1182 iCopyValueHere=*tryAddress; |
|
1183 } |
|
1184 return 0; |
|
1185 } |
|
1186 return KErrArgument; |
|
1187 } |
|
1188 |
|
1189 /** This thread verifies the function of CopyRect |
|
1190 A series of operations are performed on the given bitmap. |
|
1191 If the operation panics the launcher is able to retrieve the parameters that caused the panic and report |
|
1192 The FailOffset() returned index indicates the offset from the start at which the memory access caused a panic. |
|
1193 **/ |
|
1194 class TTestCopyRectThread:public TFunctionThread |
|
1195 { |
|
1196 public: |
|
1197 TTestCopyRectThread(CFbsBitGc* aBitmapContext,TInt aStartX,TInt aStopX,TInt aY1,TInt aY2,TPoint aOffset); |
|
1198 private: |
|
1199 virtual TInt ThreadFunctionL(); |
|
1200 private: |
|
1201 CFbsBitGc* iBitmapContext; |
|
1202 TInt iStartX; |
|
1203 TInt iStopX; |
|
1204 TInt iY1; |
|
1205 TInt iY2; |
|
1206 TPoint iOffset; |
|
1207 public: |
|
1208 volatile TInt iCurrX; |
|
1209 volatile TInt iCurrWidth; |
|
1210 |
|
1211 }; |
|
1212 |
|
1213 TTestCopyRectThread::TTestCopyRectThread(CFbsBitGc* aBitmapContext,TInt aStartX,TInt aStopX,TInt aY1,TInt aY2,TPoint aOffset): |
|
1214 iBitmapContext(aBitmapContext), |
|
1215 iStartX(aStartX), |
|
1216 iStopX(aStopX), |
|
1217 iY1(aY1), |
|
1218 iY2(aY2), |
|
1219 iOffset(aOffset) |
|
1220 { |
|
1221 LaunchThreadFunction(_L("CopyRectTest")); |
|
1222 } |
|
1223 TInt TTestCopyRectThread::ThreadFunctionL() |
|
1224 { |
|
1225 for (iCurrX=iStartX;iCurrX<iStopX;iCurrX++) |
|
1226 { |
|
1227 for (iCurrWidth=iStopX-iCurrX;iCurrWidth>0;iCurrWidth--) |
|
1228 { |
|
1229 iBitmapContext->CopyRect(iOffset,TRect(iCurrX,iY1,iCurrX+iCurrWidth,iY2)); |
|
1230 } |
|
1231 } |
|
1232 return KErrNone; |
|
1233 } |
|
1234 |
|
1235 class CTestExecuteLogger; |
|
1236 |
|
1237 struct WrapCTestExecuteLogger |
|
1238 { |
|
1239 WrapCTestExecuteLogger(): iLogger(NULL) {} |
|
1240 WrapCTestExecuteLogger(CTestExecuteLogger&aLogger): iLogger(&aLogger) {} |
|
1241 WrapCTestExecuteLogger(CTestExecuteLogger*aLogger): iLogger(aLogger) {} |
|
1242 |
|
1243 operator int() {return (iLogger!=NULL);} |
|
1244 CTestExecuteLogger& operator()() { return *iLogger; } |
|
1245 |
|
1246 CTestExecuteLogger* iLogger; |
|
1247 |
|
1248 }; |
|
1249 static const TInt KCopyTestHeight=20; |
|
1250 static const TInt KCopyTestWidth=256; //should be some multiple of 32... |
|
1251 /** Compares the pixels in the source rectangle and its copy. |
|
1252 * The copy is at an offset from the source. |
|
1253 * The compare is not complete as this was found to be too slow. |
|
1254 * Instead only a few pixels on the left and right edges are compared. |
|
1255 * |
|
1256 **/ |
|
1257 TBool CmpBitmapRectL(CFbsBitmap& aTestBitmap,TRect aSource,TPoint aTrgOffset,WrapCTestExecuteLogger Logger=NULL,TBool aExpectedPass=EFalse) |
|
1258 { |
|
1259 //Comparing all the pixels in a large rectangle using GetPixel() is too slow. |
|
1260 //So now, only a few pixels on the edges of the rectangle are compared, |
|
1261 //and the ones in between are skipped. |
|
1262 //Using any faster method to get the pixels is dubious |
|
1263 //as it it may ultimately use GetLine, which is the method under test... |
|
1264 const TInt processSize=6; |
|
1265 TBool returnState=ETrue; |
|
1266 TUint16 printcompareresultbuffers[KCopyTestHeight][2][processSize*2+1]={{{0}}}; |
|
1267 TInt resultRow=KCopyTestHeight-aSource.Height(); |
|
1268 TInt skipMiddleStart=aSource.iTl.iX+processSize; |
|
1269 TInt skipMiddleEnd=aSource.iBr.iX-processSize-1; |
|
1270 if (skipMiddleStart>=skipMiddleEnd) |
|
1271 { |
|
1272 skipMiddleStart+=processSize+processSize; //make skip irrelivent |
|
1273 } |
|
1274 //verify inputs valid |
|
1275 TRect bitmapRect=aTestBitmap.SizeInPixels(); |
|
1276 TRect sourceRectIntersect=aSource; |
|
1277 TRect targetRect=aSource; |
|
1278 targetRect.Move(aTrgOffset); |
|
1279 TRect targetRectIntersect=targetRect; |
|
1280 targetRectIntersect.Intersection(bitmapRect); |
|
1281 sourceRectIntersect.Intersection(bitmapRect); |
|
1282 ASSERT(sourceRectIntersect==aSource); |
|
1283 ASSERT(targetRectIntersect==targetRect); |
|
1284 |
|
1285 for (TInt sy=aSource.iTl.iY;sy<aSource.iBr.iY;sy++) |
|
1286 { |
|
1287 TInt resultCol=0; |
|
1288 for (TInt sx=aSource.iTl.iX;sx<aSource.iBr.iX;sx++) |
|
1289 { |
|
1290 if (sx==skipMiddleStart) |
|
1291 { |
|
1292 sx=skipMiddleEnd; |
|
1293 } |
|
1294 else |
|
1295 { |
|
1296 TRgb sourceColor; |
|
1297 aTestBitmap.GetPixel(sourceColor,TPoint(sx,sy)); |
|
1298 TRgb targetColor; |
|
1299 aTestBitmap.GetPixel(targetColor,TPoint(sx,sy)+aTrgOffset); |
|
1300 if (sourceColor!=targetColor) |
|
1301 { |
|
1302 if (Logger) |
|
1303 { |
|
1304 returnState=EFalse; |
|
1305 } |
|
1306 else |
|
1307 { |
|
1308 return EFalse; |
|
1309 } |
|
1310 } |
|
1311 if (Logger&&resultRow>=0) |
|
1312 { |
|
1313 printcompareresultbuffers[resultRow][0][resultCol]=L'@'+sourceColor.Color16(); |
|
1314 printcompareresultbuffers[resultRow][1][resultCol]=L'@'+targetColor.Color16(); |
|
1315 } |
|
1316 } |
|
1317 |
|
1318 } |
|
1319 resultRow++; |
|
1320 } |
|
1321 if (Logger && returnState!=aExpectedPass) |
|
1322 { |
|
1323 INFO_PRINTF4(_L("Case: srcx=%i targx=%i width=%i result compare has failed! Content dump follows: [src] [trg] "), |
|
1324 aSource.iTl.iX,targetRect.iTl.iX,aSource.Width()); |
|
1325 for (TInt row=(KCopyTestHeight-aSource.Height()>0)?KCopyTestHeight-aSource.Height():0;row<KCopyTestHeight;row++) |
|
1326 { |
|
1327 INFO_PRINTF5(_L("Row: %2i %s %s (%s)"), |
|
1328 row,printcompareresultbuffers[row][0],printcompareresultbuffers[row][1], |
|
1329 Mem::Compare(printcompareresultbuffers[row][0],processSize*2,printcompareresultbuffers[row][1],processSize*2) |
|
1330 ?L"differ":L"same" |
|
1331 ); |
|
1332 |
|
1333 } |
|
1334 } |
|
1335 return returnState; |
|
1336 } |
|
1337 |
|
1338 /** |
|
1339 * @SYMTestCaseID GRAPHICS-BITGDI-0099 |
|
1340 * |
|
1341 * @SYMDEF INC119063, pdef120353 |
|
1342 * |
|
1343 * @SYMTestCaseDesc CopyRect could read bytes past the end of the source bitmap |
|
1344 * This is a general test of the rewrite of CopyRect |
|
1345 * Note that this test says well within the boundaries of the bitmap, |
|
1346 * and does not test the exception condition detected in the defect. |
|
1347 * @SYMTestPriority Normal |
|
1348 * |
|
1349 * @SYMTestStatus Implemented |
|
1350 * |
|
1351 * @SYMTestActions |
|
1352 * Repeat the test for 4 affected bitmap resolutions: Gray2, Gray4, Gray16, Color16 |
|
1353 * Allocate a bitmap big enough to process the test |
|
1354 * Repeat: |
|
1355 * Fill the whole image with random data |
|
1356 * Pixel compare the source rectangle wiith the target rectangle |
|
1357 * - they should NOT be identical - very unlucky! |
|
1358 * Pixel compare the left and right edge pixels outside the copy rect |
|
1359 * - these should not be all identical - very unlucky! |
|
1360 * Copyrect a region from the bottom half to the top half (not to edges) |
|
1361 * Pixel compare the source rectangle wiith the target rectangle |
|
1362 * - they should be identical - copy was successful |
|
1363 * Pixel compare the left and right edge pixels outside the copy rect |
|
1364 * - these should not be all identical - or too much was copied |
|
1365 * Repeat for values of target x 0 to 32 |
|
1366 * Repeat for values of source x 0 to 32 |
|
1367 * Repeat for values of source/target width 1 to 96 |
|
1368 * Guess: 4x32x32x96 tests=400000 iterations |
|
1369 */ |
|
1370 void CTDefect2::ExerciseCopyRect() |
|
1371 { |
|
1372 for (TInt mode=1;mode<EColorLast;mode++) |
|
1373 { |
|
1374 CFbsBitmap testBitmap; |
|
1375 |
|
1376 //The exact dimensions of this bitmap are not important... |
|
1377 //The width should ensure that the range of tests work (max 32+32+96=160 pixels) |
|
1378 //The height should be enough to ensure there is enough variability in the random data |
|
1379 //Note that the smallest data used in a uniqueness test is a 1-pixel-width column half the height of the image. |
|
1380 //The whole height will be used if this is changed. |
|
1381 if (testBitmap.Create(TSize(KCopyTestWidth,KCopyTestHeight*2),TDisplayMode(mode))<KErrNone) |
|
1382 { |
|
1383 continue; //some mode numbers are bad! |
|
1384 } |
|
1385 |
|
1386 |
|
1387 SEpocBitmapHeader header1 = testBitmap.Header(); |
|
1388 //We could run this test for other modes, but the defect and fix only applies to low bit depths |
|
1389 if (header1.iBitsPerPixel>4) |
|
1390 { |
|
1391 continue; |
|
1392 } |
|
1393 INFO_PRINTF3(_L("Bitmap color depth: %i bits. Color flag: %i"),header1.iBitsPerPixel,header1.iColor); |
|
1394 |
|
1395 |
|
1396 TUint32* bitmapData=testBitmap.DataAddress(); |
|
1397 TUint32* pastBitmapData=bitmapData+((header1.iBitmapSize-header1.iStructSize)>>2); |
|
1398 |
|
1399 TInt splitHeight=header1.iSizeInPixels.iHeight/2; |
|
1400 |
|
1401 CFbsBitGc* bitmapContext = NULL; |
|
1402 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(&testBitmap); |
|
1403 CleanupStack::PushL(bitmapDevice); |
|
1404 User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext)); |
|
1405 CleanupStack::PushL(bitmapContext); |
|
1406 TInt skippedCases=0; |
|
1407 TInt totalCases=0; |
|
1408 //These counts have been tweaked based on knowledge of the algorithm. |
|
1409 //The target position is shifted in bits by up to 1 word (32 bits) |
|
1410 //Bigger changes than this just change the target pointer and modulo the shift. |
|
1411 //[I don't think that the target position influences the result, but it might] |
|
1412 //The source position is shifted in bits by up to 1 word (32 bits) |
|
1413 //Bigger changes than this just change the source pointer and modulo the shift. |
|
1414 //The copy width is made up of a copy words element and a remainder bytes element. |
|
1415 //The difference in shift element between source and target is used to shift the |
|
1416 //source to a temporary buffer. |
|
1417 //So the copy width element is also influenced by the source position and target position. |
|
1418 //Testing 96 possible bit widths should exercise it for zero and non-zero word counts adequately. |
|
1419 const TInt |
|
1420 KTargXMin=32, |
|
1421 KTargXMax=32+32/header1.iBitsPerPixel, |
|
1422 KSrcXMin=32, |
|
1423 KSrcXMax=32+32/header1.iBitsPerPixel, |
|
1424 KWidthMin=1, |
|
1425 KWidthMax=96/header1.iBitsPerPixel; |
|
1426 for (TInt targx=KTargXMin;targx<KTargXMax;targx++) |
|
1427 { |
|
1428 for (TInt srcx=KSrcXMin;srcx<KSrcXMax;srcx++) |
|
1429 { |
|
1430 for (TInt width=KWidthMin;width<KWidthMax;width++) |
|
1431 { |
|
1432 totalCases++; |
|
1433 TInt offsetx=targx-srcx; |
|
1434 //fill the buffer with random data |
|
1435 TInt64 randomSeed=MAKE_TINT64(0xdeadbeef,0xbaadf00d); |
|
1436 Math::Rand(randomSeed); |
|
1437 TInt maxRetries=3; |
|
1438 TInt rndCount=0; |
|
1439 while (--maxRetries>=0) |
|
1440 { |
|
1441 for (TUint32* fillData=bitmapData;fillData!=pastBitmapData;fillData++) |
|
1442 { |
|
1443 rndCount++; |
|
1444 //Rand only sets 31 bits of the integer - no negative values - no top bit set! |
|
1445 //This solution wastes some of the seed, but it should still produce valid results. |
|
1446 TInt rnd=Math::Rand(randomSeed)^(Math::Rand(randomSeed)<<8); |
|
1447 *fillData=rnd; |
|
1448 } |
|
1449 TInt colOffSrc=0; |
|
1450 TInt colOffTrg=0; |
|
1451 //verify that the data is different inside the copy area and outside each copy area |
|
1452 if (TInt failCode= CmpBitmapRectL(testBitmap,TRect(srcx,splitHeight,srcx+width,splitHeight*2),TPoint(offsetx,-splitHeight)) |
|
1453 + 2*CmpBitmapRectL(testBitmap,TRect(srcx-1,splitHeight,srcx,splitHeight*2),TPoint(offsetx,-splitHeight)) |
|
1454 + 4*CmpBitmapRectL(testBitmap,TRect(srcx+width,splitHeight,srcx+width+1,splitHeight*2),TPoint(offsetx,-splitHeight)) |
|
1455 ) |
|
1456 { |
|
1457 //OK.. need to find another pair of bits where the source and target columns are non-identical |
|
1458 INFO_PRINTF5(_L("First random data failed... (code %i) Trying alternale columns: srcx=%i targx=%i width=%i"),failCode,srcx,targx,width); |
|
1459 for (TInt tryOffSrc=0;tryOffSrc+srcx<KCopyTestWidth-(KWidthMax+1) && (colOffSrc==0&&colOffTrg==0);tryOffSrc+=32) |
|
1460 for (TInt tryOffTrg=0;tryOffTrg+targx<KCopyTestWidth-(KWidthMax+1) && (colOffSrc==0&&colOffTrg==0);tryOffTrg+=32) |
|
1461 { |
|
1462 TInt offsetx=(tryOffTrg+targx)-(tryOffSrc+srcx); |
|
1463 TInt trysrcx=tryOffSrc+srcx; |
|
1464 if ( CmpBitmapRectL(testBitmap,TRect(trysrcx,splitHeight,trysrcx+width,splitHeight*2),TPoint(offsetx,-splitHeight)) |
|
1465 | CmpBitmapRectL(testBitmap,TRect(trysrcx-1,splitHeight,trysrcx,splitHeight*2),TPoint(offsetx,-splitHeight)) |
|
1466 | CmpBitmapRectL(testBitmap,TRect(trysrcx+width,splitHeight,trysrcx+width+1,splitHeight*2),TPoint(offsetx,-splitHeight)) |
|
1467 ) |
|
1468 { |
|
1469 } |
|
1470 else |
|
1471 { |
|
1472 colOffSrc=tryOffSrc; |
|
1473 colOffTrg=tryOffTrg; |
|
1474 } |
|
1475 } |
|
1476 if (colOffSrc||colOffTrg) |
|
1477 { |
|
1478 offsetx=(colOffTrg+targx)-(colOffSrc+srcx); |
|
1479 INFO_PRINTF4(_L("Found a safe equivalent column: srcx=%i targx=%i width=%i"),colOffSrc+srcx,colOffTrg+targx,width); |
|
1480 } |
|
1481 else |
|
1482 { |
|
1483 INFO_PRINTF4(_L("Didn't find a safe column! Trying next random numbers"),srcx,targx,width); |
|
1484 continue; //Try next random number... |
|
1485 } |
|
1486 } |
|
1487 TInt trysrcx=colOffSrc+srcx; |
|
1488 //Copy the region in question |
|
1489 bitmapContext->CopyRect(TPoint(offsetx,-splitHeight), TRect(trysrcx,splitHeight,trysrcx+width,splitHeight*2)); |
|
1490 //verify the copied region is an exact match |
|
1491 TBool copySame=CmpBitmapRectL(testBitmap,TRect(trysrcx,splitHeight,trysrcx+width,splitHeight*2),TPoint(offsetx,-splitHeight)); |
|
1492 //verify the area outside has not been copied |
|
1493 TBool leftSame=CmpBitmapRectL(testBitmap,TRect(trysrcx-1,splitHeight,trysrcx,splitHeight*2),TPoint(offsetx,-splitHeight)); |
|
1494 TBool rightSame=CmpBitmapRectL(testBitmap,TRect(trysrcx+width,splitHeight,trysrcx+width+1,splitHeight*2),TPoint(offsetx,-splitHeight)); |
|
1495 if (!copySame||leftSame||rightSame) |
|
1496 { |
|
1497 INFO_PRINTF4(_L("Case: srcx=%i targx=%i width=%i result compare has failed!"),srcx,targx,width); |
|
1498 if (!copySame) |
|
1499 { |
|
1500 INFO_PRINTF1(_L("Copied data is not same as source data!")); |
|
1501 } |
|
1502 if (leftSame) |
|
1503 { |
|
1504 INFO_PRINTF1(_L("Data to left of copy is now same as source data!")); |
|
1505 } |
|
1506 if (rightSame) |
|
1507 { |
|
1508 INFO_PRINTF1(_L("Data to right of copy is now same as source data!")); |
|
1509 } |
|
1510 TEST(EFalse); |
|
1511 } |
|
1512 break; //out of "try next random number" loop |
|
1513 } |
|
1514 if (maxRetries<0) |
|
1515 { |
|
1516 INFO_PRINTF4(_L("Case skipped TOO MANY TIMES because random data not unique: srcx=%i targx=%i width=%i."),srcx,targx,width); |
|
1517 skippedCases++; |
|
1518 } |
|
1519 } |
|
1520 } |
|
1521 } |
|
1522 CleanupStack::PopAndDestroy(bitmapContext); |
|
1523 CleanupStack::PopAndDestroy(bitmapDevice); |
|
1524 |
|
1525 testBitmap.Reset(); |
|
1526 if (skippedCases) |
|
1527 { |
|
1528 INFO_PRINTF3(_L("%i / %i cases skipped because random picture data not unique enough! 10%% will cause test fail."),skippedCases,totalCases ); |
|
1529 TEST(skippedCases*10<totalCases); |
|
1530 } |
|
1531 } |
|
1532 } |
|
1533 /** |
|
1534 * @SYMTestCaseID GRAPHICS-BITGDI-0098 |
|
1535 * |
|
1536 * @SYMDEF INC119063, PDEF120353 |
|
1537 * |
|
1538 * @SYMTestCaseDesc CopyRect could previously read bytes past the end of the source bitmap |
|
1539 * This would exception if the page is not mapped. |
|
1540 * This particular image size allocation reproduces this exception. |
|
1541 * Any changes to the allocation mechanism may mean the crash condition is not reproducable. |
|
1542 * It is likely that it is changes to the allocator that have caused this defect to occur |
|
1543 * in the first place. |
|
1544 * |
|
1545 * @SYMTestPriority Normal |
|
1546 * |
|
1547 * @SYMTestStatus Implemented |
|
1548 * |
|
1549 * @SYMTestActions Create 768x1280 1 bit image, (also 384x1280x2bit and 192x1280x4bit ?) |
|
1550 * In a seperate thread try to read past the end of the data. |
|
1551 * If this panics then the test is valid. |
|
1552 * Now, make a number of copyrect calls |
|
1553 * that attempt to read data from near the end of the last scanline |
|
1554 * Expected result: these reads should not exception. |
|
1555 * Enhancement to improve reproducability: |
|
1556 * Occasionally, the "next location" is addressable when the test is run in the overnight script |
|
1557 * To address this, the test will recurse and repeat, forcing the image allocation to a different address if this occurs |
|
1558 */ |
|
1559 TBool CTDefect2::CopyRectReadOutsideBitmap(TInt aSingleMode /*=0*/,TInt aRetriesLeft /*=5*/) |
|
1560 { |
|
1561 TBool testShouldUltimatelyFail=EFalse; |
|
1562 TInt startMode=aSingleMode?aSingleMode:1; |
|
1563 TInt stopMode=aSingleMode?aSingleMode+1:EColorLast; |
|
1564 for (TInt mode=startMode;mode<stopMode;mode++) |
|
1565 { |
|
1566 CFbsBitmap testBitmap; |
|
1567 enum |
|
1568 { |
|
1569 EMonoPixelsWidth=768, |
|
1570 EMonoBytesWidth=96, |
|
1571 EMonoHeight=1280 |
|
1572 }; |
|
1573 TInt guessPixels=EMonoPixelsWidth; |
|
1574 TInt guessBytes=CFbsBitmap::ScanLineLength(guessPixels,TDisplayMode(mode)); |
|
1575 if (guessBytes<=0 || reinterpret_cast<TDisplayMode&>(mode)==ERgb) |
|
1576 { |
|
1577 continue; //mode number not good. |
|
1578 } |
|
1579 //want to generate a length of 768/8=96 bytes per scanline to repro the defect... |
|
1580 while (guessBytes<EMonoBytesWidth) |
|
1581 { |
|
1582 if (guessBytes<=EMonoBytesWidth/2) |
|
1583 { |
|
1584 guessPixels*=2; |
|
1585 } |
|
1586 else |
|
1587 { |
|
1588 guessPixels++; |
|
1589 } |
|
1590 guessBytes=CFbsBitmap::ScanLineLength(guessPixels,TDisplayMode(mode)); |
|
1591 } |
|
1592 while (guessBytes>EMonoBytesWidth) |
|
1593 { |
|
1594 if (guessBytes>=EMonoBytesWidth*2) |
|
1595 { |
|
1596 guessPixels>>=1; |
|
1597 } |
|
1598 else |
|
1599 { |
|
1600 guessPixels--; |
|
1601 } |
|
1602 guessBytes=CFbsBitmap::ScanLineLength(guessPixels,TDisplayMode(mode)); |
|
1603 } |
|
1604 |
|
1605 if (testBitmap.Create(TSize(guessPixels,EMonoHeight),TDisplayMode(mode))<KErrNone) |
|
1606 { |
|
1607 _LIT(KFail,"Failed to create bitmap for color depth: %S"); |
|
1608 INFO_PRINTF2(KFail,&ColorModeName(mode)); |
|
1609 if (aSingleMode) |
|
1610 { |
|
1611 testShouldUltimatelyFail=ETrue; |
|
1612 } |
|
1613 continue; //some mode numbers are bad! |
|
1614 } |
|
1615 |
|
1616 SEpocBitmapHeader header1 = testBitmap.Header(); |
|
1617 |
|
1618 TUint32* bitmapData=testBitmap.DataAddress(); |
|
1619 TUint32* pastBitmapData=bitmapData+((header1.iBitmapSize-header1.iStructSize)>>2); |
|
1620 |
|
1621 //The defect and fix only applies to low bit depths, but it is quick enough to run it for all color depths |
|
1622 if (aSingleMode) |
|
1623 { |
|
1624 User::After(1000000); //Pause is in microseconds! //A small pause to try to get the bad operation completed |
|
1625 INFO_PRINTF3(_L("Retry Bitmap: Address 0x%08x, past 0x%08x"), |
|
1626 bitmapData,pastBitmapData ); |
|
1627 |
|
1628 } |
|
1629 else |
|
1630 { |
|
1631 INFO_PRINTF7(_L("Bitmap: color depth: %i bits. Color mode= %i. Width=%i Height=%i Address 0x%08x, past 0x%08x"), |
|
1632 header1.iBitsPerPixel,header1.iColor, |
|
1633 header1.iSizeInPixels.iWidth,header1.iSizeInPixels.iHeight, |
|
1634 bitmapData,pastBitmapData ); |
|
1635 } |
|
1636 TBool canGenerateDefectScenario=EFalse; |
|
1637 |
|
1638 |
|
1639 //So now we hope that we have created a test bitmap on the bottom of a memory page, |
|
1640 //as per the defect, but at different color depths as well. |
|
1641 //Any number of factors could change the way this block is allocated and disguise the defect. |
|
1642 //Equally, the next block of memory may be already mapped, and again the defect will not occurr. |
|
1643 //There is no way to influence the result, so the next ting to do is to verify that an exception will occur. |
|
1644 //Could assert that the address matches a 4K page, but I need to check if the page is mapped anyway! |
|
1645 TTestMemThread memThread(pastBitmapData-2,pastBitmapData+2); |
|
1646 TInt failAt=memThread.FailOffset(); |
|
1647 if (failAt<0) |
|
1648 { |
|
1649 INFO_PRINTF2(_L(" Scenario invalid - error code generated by test thread! %i"),failAt); |
|
1650 } |
|
1651 else if (failAt<=1) |
|
1652 { |
|
1653 INFO_PRINTF1(_L(" Scenario invalid - didn't manage to read a safe location near the end of the bitmap!")); |
|
1654 } |
|
1655 else if (failAt>2) |
|
1656 { |
|
1657 INFO_PRINTF1(_L(" Scenario invalid - managed to read right past the test location!")); |
|
1658 } |
|
1659 else |
|
1660 { |
|
1661 INFO_PRINTF1(_L(" Verified that end address is bad memory")); |
|
1662 canGenerateDefectScenario=ETrue; |
|
1663 } |
|
1664 if (!canGenerateDefectScenario) |
|
1665 { |
|
1666 if (!aRetriesLeft || !CopyRectReadOutsideBitmap(mode,aRetriesLeft-1)) //repeat attempt with nested bitmap alocation to new address |
|
1667 { |
|
1668 //if this doesn't work out then the memory allocator is not like it was when the defect was raised! |
|
1669 //so the test is no longer any good. |
|
1670 //Can't return "Inconclusive" as other tests in the test set may reset the state. |
|
1671 INFO_PRINTF2(_L("Error!!: Couldn't generate the defect scenario for the end address at 0x%08x."),(TInt)pastBitmapData); |
|
1672 testShouldUltimatelyFail=ETrue; |
|
1673 } |
|
1674 } |
|
1675 else |
|
1676 { |
|
1677 //These writes should succeed if the end of the bitmap is where it should be: |
|
1678 //these colour values will be transferred in the copied data in the subsequent test |
|
1679 //The test does not explicitly look for these patterns, |
|
1680 //but they are useful to identify in the copied data if manually debugging. |
|
1681 pastBitmapData[-2]=0xBAADF00D; |
|
1682 pastBitmapData[-1]=0xdeadbeef; |
|
1683 |
|
1684 CFbsBitGc* bitmapContext = NULL; |
|
1685 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(&testBitmap); |
|
1686 CleanupStack::PushL(bitmapDevice); |
|
1687 User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext)); |
|
1688 CleanupStack::PushL(bitmapContext); |
|
1689 //for the last scanline, try to copy various permutations of the last few pixels |
|
1690 //note that there is no check to see if the "right" contents are copied, only that it doesn't abort. |
|
1691 //In fact most of the bitmap is uninitialised... |
|
1692 TTestCopyRectThread copythread(bitmapContext,guessPixels-64,guessPixels,EMonoHeight-5,EMonoHeight,TPoint(-5,-5)); |
|
1693 if (copythread.iExitHow!=copythread.EReturn) |
|
1694 { |
|
1695 testShouldUltimatelyFail=ETrue; |
|
1696 INFO_PRINTF7(_L("Error: (probably panic) when using CopyRect(TPoint(%i,%i),TRect(%i,%i,%i,%i)"), |
|
1697 -5,-5, |
|
1698 copythread.iCurrX,EMonoHeight-5, copythread.iCurrX+copythread.iCurrWidth,EMonoHeight); |
|
1699 _LIT(KLog,"Thread Exit Reason %d, expected %d"); |
|
1700 INFO_PRINTF3(KLog,copythread.iExitHow,copythread.EReturn); |
|
1701 } |
|
1702 |
|
1703 CleanupStack::PopAndDestroy(bitmapContext); |
|
1704 CleanupStack::PopAndDestroy(bitmapDevice); |
|
1705 |
|
1706 //For the purposes of verification, check that the memory location is still considered a valid scenario. |
|
1707 //Again , the test is repeated nested if the scenario has become invalid |
|
1708 TTestMemThread memThread2(pastBitmapData-2,pastBitmapData+2); |
|
1709 TInt failAt=memThread2.FailOffset(); |
|
1710 canGenerateDefectScenario=EFalse; |
|
1711 if (failAt<0) |
|
1712 { |
|
1713 INFO_PRINTF2(_L(" After Test: Scenario invalid - error code generated by test thread! %i"),failAt); |
|
1714 INFO_PRINTF1(_L("Warning: This may mean that bad copys may not have been detected??")); |
|
1715 } |
|
1716 else if (failAt<=1) |
|
1717 { |
|
1718 INFO_PRINTF1(_L(" After Test: Scenario invalid - didn't manage to read a safe location near the end of the bitmap!")); |
|
1719 INFO_PRINTF1(_L("Warning: This may mean that bad copys may not have been detected??")); |
|
1720 } |
|
1721 else if (failAt>2) |
|
1722 { |
|
1723 INFO_PRINTF1(_L(" After Test: Scenario invalid - managed to read right past the test location!")); |
|
1724 INFO_PRINTF1(_L("Warning: This may mean that bad copys may not have been detected??")); |
|
1725 } |
|
1726 else |
|
1727 { |
|
1728 INFO_PRINTF1(_L(" After Test: Verified that end address is still bad memory")); |
|
1729 canGenerateDefectScenario=ETrue; |
|
1730 } |
|
1731 if (!canGenerateDefectScenario) |
|
1732 { |
|
1733 if (!aRetriesLeft || !CopyRectReadOutsideBitmap(mode,aRetriesLeft-1)) //repeat attempt with nested bitmap alocation to new address |
|
1734 { |
|
1735 //if this doesn't work out then the memory allocator is not like it was when the defect was raised! |
|
1736 //so the test is no longer any good. |
|
1737 //Can't return "Inconclusive" as other tests in the test set may reset the state. |
|
1738 INFO_PRINTF2(_L("Warning!!: Couldn't maintain the defect scenario for the end address at 0x%08x after retries."),(TInt)pastBitmapData); |
|
1739 INFO_PRINTF1(_L("Test may have read from end of bitmap after it was made accessible.")); |
|
1740 //Ultimately, this refuses to stabilise on ONB scenario, so I won't have this retry of the test fail. |
|
1741 } |
|
1742 } |
|
1743 |
|
1744 } |
|
1745 testBitmap.Reset(); |
|
1746 } |
|
1747 if (!aSingleMode) |
|
1748 { |
|
1749 TEST(!testShouldUltimatelyFail); |
|
1750 } |
|
1751 return (!testShouldUltimatelyFail); |
|
1752 } |
|
1753 |
|
1754 /** |
|
1755 @SYMTestCaseID GRAPHICS-BITGDI-0066 |
|
1756 |
|
1757 @SYMDEF DEF039237 |
|
1758 |
|
1759 @SYMTestCaseDesc Memory leak in CFbsScreenDevice (occurs on Lubbock, but not WINS) |
|
1760 |
|
1761 @SYMTestPriority normal |
|
1762 |
|
1763 @SYMTestStatus Implemented |
|
1764 |
|
1765 @SYMTestActions Creates a screen device in each colour mode |
|
1766 |
|
1767 @SYMTestExpectedResults Test should perform graphics operations succesfully. |
|
1768 */ |
|
1769 void CTDefect2::DEF039237L() |
|
1770 { |
|
1771 __UHEAP_MARK; |
|
1772 const TInt KNumDisplayModes = 11; |
|
1773 const TDisplayMode KDisplayMode[KNumDisplayModes] = |
|
1774 { EGray2, EGray4, EGray16, EGray256, EColor16, EColor256, |
|
1775 EColor4K, EColor64K, EColor16M, EColor16MA, EColor16MAP }; |
|
1776 |
|
1777 CFbsScreenDevice* device = NULL; |
|
1778 TInt err = KErrNotSupported; |
|
1779 TInt index; |
|
1780 |
|
1781 for (index=0; index<KNumDisplayModes && err==KErrNotSupported; ++index) |
|
1782 { |
|
1783 ASSERT(device==NULL); |
|
1784 TRAP(err,device = CFbsScreenDevice::NewL(KNullDesC,KDisplayMode[index])); |
|
1785 } |
|
1786 --index; |
|
1787 if (device) |
|
1788 { |
|
1789 _LIT(KLog,"Created device with color depth %S"); |
|
1790 INFO_PRINTF2(KLog,&ColorModeName(KDisplayMode[index])); |
|
1791 } |
|
1792 else |
|
1793 { |
|
1794 _LIT(KLog,"Failed to create screen device, last color depth tried %S gave return value %d"); |
|
1795 INFO_PRINTF3(KLog,&ColorModeName(KDisplayMode[index]),err); |
|
1796 } |
|
1797 |
|
1798 User::LeaveIfError(err); |
|
1799 ASSERT(device); |
|
1800 |
|
1801 delete device; |
|
1802 __UHEAP_MARKEND; |
|
1803 } |
|
1804 |
|
1805 /** |
|
1806 @SYMTestCaseID GRAPHICS-BITGDI-0067 |
|
1807 |
|
1808 @SYMDEF DEF039331 |
|
1809 |
|
1810 @SYMTestCaseDesc bitgdi fails to deal correctly with screen orientation changes |
|
1811 |
|
1812 @SYMTestPriority normal |
|
1813 |
|
1814 @SYMTestStatus Implemented |
|
1815 |
|
1816 @SYMTestActions |
|
1817 DEF039604 - CFbsBitGc::InternalizeL/ExternalizeL - comments, version number |
|
1818 Default region externalization/internalization related code was removed, so |
|
1819 I want to check that everything is OK calling |
|
1820 CFbsBitGc::ExternalizeL()/CFbsBitGc::InternalizeL(). |
|
1821 The test may also fail in the future if somebody changes CFbsBitGc data members |
|
1822 and fail to update ExternalizeL/InternalizeL methods. |
|
1823 |
|
1824 @SYMTestExpectedResults Test should perform graphics operations succesfully. |
|
1825 */ |
|
1826 void CTDefect2::DEF039331L() |
|
1827 { |
|
1828 CreateScrDevAndContextL(); |
|
1829 |
|
1830 //Make sure that the archive file does not exist. |
|
1831 FServSession.Delete(KArchiveFileName); |
|
1832 |
|
1833 RFileWriteStream wrStream; |
|
1834 ::CleanupClosePushL(wrStream); |
|
1835 User::LeaveIfError(wrStream.Create(FServSession, KArchiveFileName, EFileWrite | EFileRead)); |
|
1836 |
|
1837 iGc->ExternalizeL(wrStream); |
|
1838 wrStream.CommitL(); |
|
1839 CleanupStack::PopAndDestroy();//wrStream |
|
1840 |
|
1841 RFileReadStream rdStream; |
|
1842 ::CleanupClosePushL(rdStream); |
|
1843 User::LeaveIfError(rdStream.Open(FServSession, KArchiveFileName, EFileRead)); |
|
1844 iGc->InternalizeL(rdStream); |
|
1845 CleanupStack::PopAndDestroy();//rdStream |
|
1846 } |
|
1847 |
|
1848 /** |
|
1849 @SYMTestCaseID GRAPHICS-BITGDI-0068 |
|
1850 |
|
1851 @SYMDEF DEF039650 |
|
1852 |
|
1853 @SYMTestCaseDesc CFbsDevice::RectCompare says don't match when they do |
|
1854 |
|
1855 @SYMTestPriority normal |
|
1856 |
|
1857 @SYMTestStatus Implemented |
|
1858 |
|
1859 @SYMTestActions Creates a bitmap, calls scanlinedata then checks that the scanline returns the correct amount of data |
|
1860 |
|
1861 @SYMTestExpectedResults Test should return correct number of bytes |
|
1862 */ |
|
1863 //DEF039650 - . |
|
1864 void CTDefect2::DEF039650L() |
|
1865 { |
|
1866 enum {KHeight = 1};//Bitmaps height - in pixels |
|
1867 TDisplayMode testMode[] = {EGray2, EGray4, EGray16, EColor16, EColor4K, EColor64K, EColor16M, EColor16MU, EColor256};//tested display modes |
|
1868 const TInt pixelPerByte[] ={8, 4, 2, 2, 0, 0, 0, 0, 1}; |
|
1869 const TInt bytePerPixel[] ={0, 0, 0, 0, 2, 2, 3, 4, 0}; |
|
1870 const TInt bitmapWidth[] = {22, 7, 11, 11, 3, 3, 1, 1, 10};//bitmaps width |
|
1871 const TUint8 KTestVal1 = 0xA3;//test value |
|
1872 const TUint8 KTestVal2 = 0xF7;//test value |
|
1873 TUint8 scanLineData[100];//100 should be enough for all possible modes which are tested |
|
1874 for(TInt ii=0;ii<TInt(sizeof(testMode)/sizeof(testMode[0]));ii++) |
|
1875 { |
|
1876 TSize size(bitmapWidth[ii], KHeight);//bitmap size - in pixels |
|
1877 CreateBitmapL(size, testMode[ii]); |
|
1878 //Initialize the bitmap scanline |
|
1879 TInt scanLineLen = 0; |
|
1880 if(pixelPerByte[ii]) |
|
1881 { |
|
1882 scanLineLen = bitmapWidth[ii] / pixelPerByte[ii] + (bitmapWidth[ii] % pixelPerByte[ii] ? 1 : 0); |
|
1883 } |
|
1884 else |
|
1885 { |
|
1886 scanLineLen = bitmapWidth[ii] * bytePerPixel[ii]; |
|
1887 } |
|
1888 const TInt KAddBytes = 10; |
|
1889 Mem::Fill(scanLineData, scanLineLen, KTestVal1); |
|
1890 TPtr8 p(scanLineData, scanLineLen, scanLineLen + KAddBytes); |
|
1891 iBitmap->SetScanLine(p, 0); |
|
1892 //Create bitmap device (KWidth, KHeight) size |
|
1893 DeleteBitmapDevice(); |
|
1894 iBmpDevice = CFbsBitmapDevice::NewL(iBitmap); |
|
1895 //Fill the scanLineData with control values |
|
1896 Mem::Fill(scanLineData, sizeof(scanLineData), KTestVal2); |
|
1897 //GetScanLine test - check the KAddBytes bytes |
|
1898 iBmpDevice->GetScanLine(p, TPoint(), bitmapWidth[ii], testMode[ii]); |
|
1899 for(TInt jj=0;jj<KAddBytes;jj++) |
|
1900 { |
|
1901 TEST(scanLineData[scanLineLen+jj] == KTestVal2); |
|
1902 } |
|
1903 }//end of - for(TInt ii=0;ii<TInt(sizeof(testMode)/sizeof(testMode[0]));ii++) |
|
1904 } |
|
1905 |
|
1906 /** |
|
1907 @SYMTestCaseID GRAPHICS-BITGDI-0069 |
|
1908 |
|
1909 @SYMDEF |
|
1910 |
|
1911 @SYMTestCaseDesc Tests the performance of getting and setting pixels in different display modes |
|
1912 |
|
1913 @SYMTestPriority normal |
|
1914 |
|
1915 @SYMTestStatus Implemented |
|
1916 |
|
1917 @SYMTestActions draws a number opf pixels to a bitmap then reads them back. Time is recorded |
|
1918 |
|
1919 @SYMTestExpectedResults Test should perform graphics operations succesfully. |
|
1920 */ |
|
1921 void CTDefect2::GetPixelPerformance1L() |
|
1922 { |
|
1923 TDisplayMode mode[] = {EColor16MA, EColor16MAP, EColor256, EColor4K, EColor16M, EColor16MU, EColor64K, |
|
1924 EGray256, EGray16, EGray4, EGray2, EColor16}; |
|
1925 _LIT(KLog,"Mode %S. Uncompressed bitmap. Time=%d"); |
|
1926 for(TInt ii=0;ii<TInt(sizeof(mode)/sizeof(mode[0]));ii++) |
|
1927 { |
|
1928 //Create bitmap |
|
1929 enum {KWidth = 600, KHeight = 400}; |
|
1930 TSize size(KWidth, KHeight); |
|
1931 CreateBitmapL(size, mode[ii]); |
|
1932 TEST(!iBitmap->IsCompressedInRAM()); |
|
1933 //Fill bitmap |
|
1934 TBitmapUtil bmpUtil(iBitmap); |
|
1935 TTime now; |
|
1936 now.UniversalTime(); |
|
1937 TInt64 seed = now.Int64(); |
|
1938 bmpUtil.Begin(TPoint(0, 0)); |
|
1939 for(TInt j1=0;j1<KWidth;j1++) |
|
1940 { |
|
1941 for(TInt j2=0;j2<KHeight;j2++) |
|
1942 { |
|
1943 bmpUtil.SetPos(TPoint(j1, j2)); |
|
1944 bmpUtil.SetPixel(Math::Rand(seed)); |
|
1945 } |
|
1946 } |
|
1947 bmpUtil.End(); |
|
1948 //Performance test |
|
1949 TUint time = User::TickCount(); |
|
1950 TPoint pt; |
|
1951 TRgb color(0); |
|
1952 for(TInt jj=0;jj<size.iWidth;jj++) |
|
1953 { |
|
1954 for(TInt kk=0;kk<size.iHeight;kk++) |
|
1955 { |
|
1956 pt.iX = jj; |
|
1957 pt.iY = kk; |
|
1958 iBitmap->GetPixel(color, pt); |
|
1959 } |
|
1960 } |
|
1961 time = User::TickCount() - time; |
|
1962 INFO_PRINTF3(KLog,&ColorModeName(mode[ii]),time); |
|
1963 //Destroy bitmap |
|
1964 DeleteBitmap(); |
|
1965 }//end of - for(TInt ii=0;ii<TInt(sizeof(mode)/sizeof(mode[0]));ii++) |
|
1966 } |
|
1967 |
|
1968 /** |
|
1969 @SYMTestCaseID GRAPHICS-BITGDI-0070 |
|
1970 |
|
1971 @SYMDEF |
|
1972 |
|
1973 @SYMTestCaseDesc Draws text to the screen device in different orientations |
|
1974 |
|
1975 @SYMTestPriority normal |
|
1976 |
|
1977 @SYMTestStatus Implemented |
|
1978 |
|
1979 @SYMTestActions Creates a screen device and gc, changes the gc orientation then draws some text to it |
|
1980 |
|
1981 @SYMTestExpectedResults Test should perform graphics operations succesfully. |
|
1982 */ |
|
1983 void CTDefect2::RotateMoveTextL() |
|
1984 { |
|
1985 TInt err=CreateScrDevAndContext(EColor64K); |
|
1986 if (err!=KErrNone) |
|
1987 err=CreateScrDevAndContext(EColor256); |
|
1988 if (err!=KErrNone) |
|
1989 err=CreateScrDevAndContext(EColor16MA); |
|
1990 if (err!=KErrNone) |
|
1991 err=CreateScrDevAndContext(EColor16MAP); |
|
1992 TEST(err==KErrNone); |
|
1993 DoRotateMoveTextL(); |
|
1994 } |
|
1995 |
|
1996 void CTDefect2::DoRotateMoveTextL() |
|
1997 { |
|
1998 __ASSERT_ALWAYS(iScrDev, User::Invariant()); |
|
1999 __ASSERT_ALWAYS(iGc, User::Invariant()); |
|
2000 |
|
2001 CreateFontL(); |
|
2002 |
|
2003 const CFbsBitGc::TGraphicsOrientation KOrientation[] = |
|
2004 { |
|
2005 CFbsBitGc::EGraphicsOrientationNormal, |
|
2006 CFbsBitGc::EGraphicsOrientationRotated90, |
|
2007 CFbsBitGc::EGraphicsOrientationRotated180, |
|
2008 CFbsBitGc::EGraphicsOrientationRotated270 |
|
2009 }; |
|
2010 |
|
2011 for(TInt ii=0;ii<TInt(sizeof(KOrientation)/sizeof(KOrientation[0]));++ii) |
|
2012 { |
|
2013 if(!iGc->SetOrientation(KOrientation[ii])) |
|
2014 { |
|
2015 continue; |
|
2016 } |
|
2017 _LIT(KRotation,"===EOrientation%S==="); |
|
2018 INFO_PRINTF2(KRotation,&RotationName(KOrientation[ii])); |
|
2019 |
|
2020 TSize size = iScrDev->SizeInPixels(); |
|
2021 RDebug::Print(_L("Size: %d, %d\r\n"), size.iWidth, size.iHeight); |
|
2022 for(TInt x=-40;x<(size.iWidth+30);x+=27) |
|
2023 { |
|
2024 for(TInt y=-40;y<(size.iHeight+30);y+=23) |
|
2025 { |
|
2026 iGc->Clear(); |
|
2027 iGc->SetPenStyle(CGraphicsContext::ESolidPen); |
|
2028 iGc->SetPenColor(TRgb(0x00, 0x00, 0x00)); |
|
2029 iGc->SetPenSize(TSize(1, 1)); |
|
2030 |
|
2031 iGc->DrawText(_L("Test text"), TPoint(x, y)); |
|
2032 |
|
2033 iScrDev->Update(); |
|
2034 } |
|
2035 } |
|
2036 } |
|
2037 iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal); |
|
2038 } |
|
2039 |
|
2040 /** |
|
2041 @SYMTestCaseID GRAPHICS-BITGDI-0071 |
|
2042 |
|
2043 @SYMDEF |
|
2044 |
|
2045 @SYMTestCaseDesc Swaps width and height of a bitmap |
|
2046 |
|
2047 @SYMTestPriority normal |
|
2048 |
|
2049 @SYMTestStatus Implemented |
|
2050 |
|
2051 @SYMTestActions Test to swap the width and height of a bitmap |
|
2052 |
|
2053 @SYMTestExpectedResults Test should perform graphics operations succesfully. |
|
2054 */ |
|
2055 void CTDefect2::SwapWidthAndHeightL() |
|
2056 { |
|
2057 TDisplayMode testMode[] = {EColor4K, EColor64K, EColor16M, EColor16MU, |
|
2058 EColor256, EColor16MA, EColor16MAP, EColor16, EGray16, EGray4, EGray2};//tested display modes |
|
2059 _LIT(KLog,"Mode %S"); |
|
2060 for(TInt ii=0;ii<TInt(sizeof(testMode)/sizeof(testMode[0]));ii++) |
|
2061 { |
|
2062 INFO_PRINTF2(KLog,&ColorModeName(testMode[ii])); |
|
2063 TSize size(40, 12);//bitmap size - in pixels |
|
2064 CreateBitmapL(size, testMode[ii]);//iBitmap - created |
|
2065 //Create bitmap device |
|
2066 DeleteBitmapDevice(); |
|
2067 iBmpDevice = CFbsBitmapDevice::NewL(iBitmap); |
|
2068 TInt err = iBmpDevice->SwapWidthAndHeight(); |
|
2069 TEST(err == KErrNone); |
|
2070 }//end of - for(TInt ii=0;ii<TInt(sizeof(testMode)/sizeof(testMode[0]));ii++) |
|
2071 } |
|
2072 |
|
2073 /** |
|
2074 @SYMTestCaseID GRAPHICS-BITGDI-0072 |
|
2075 |
|
2076 @SYMDEF |
|
2077 |
|
2078 @SYMTestCaseDesc Multiple screen test |
|
2079 |
|
2080 @SYMTestPriority High |
|
2081 |
|
2082 @SYMTestStatus Implemented |
|
2083 |
|
2084 @SYMTestActions creates some screens in different modes then writes some rotated text to them and test. |
|
2085 |
|
2086 @SYMTestExpectedResults Test should perform graphics operations succesfully. |
|
2087 */ |
|
2088 void CTDefect2::CreateScreenDeviceL() |
|
2089 { |
|
2090 TDisplayMode testMode[] = {EColor4K, EColor64K, EColor16M, EColor16MU, EColor256, EColor16MA, EColor16MAP};//tested display modes |
|
2091 for(TInt ii=0;ii<TInt(sizeof(testMode)/sizeof(testMode[0]));ii++) |
|
2092 { |
|
2093 TInt screenCnt = 0; |
|
2094 TEST(HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCnt) == KErrNone); |
|
2095 for(TInt screenNo=0;screenNo<screenCnt;++screenNo) |
|
2096 { |
|
2097 TInt err = CreateScrDevAndContext(screenNo, testMode[ii]); |
|
2098 if(err == KErrNone) |
|
2099 { |
|
2100 DoRotateMoveTextL(); |
|
2101 } |
|
2102 DeleteGraphicsContext(); |
|
2103 DeleteScreenDevice(); |
|
2104 } |
|
2105 } |
|
2106 } |
|
2107 |
|
2108 void CTDefect2::CreateScrDevAndContextL() |
|
2109 { |
|
2110 DeleteGraphicsContext(); |
|
2111 DeleteScreenDevice(); |
|
2112 TDisplayMode mode[] = {EColor256, EColor4K, EColor16M, EColor16MU, EColor64K, |
|
2113 EGray256, EGray16, EGray4, EGray2, EColor16, EColor16MA, EColor16MAP}; |
|
2114 TInt ii; |
|
2115 TInt err = KErrNotSupported; |
|
2116 for(ii=0;(ii<TInt(sizeof(mode)/sizeof(mode[0]))) && (err == KErrNotSupported);++ii) |
|
2117 { |
|
2118 err = CreateScrDevAndContext(mode[ii]); |
|
2119 } |
|
2120 TEST(err == KErrNone); |
|
2121 } |
|
2122 |
|
2123 TInt CTDefect2::CreateScrDevAndContext(TInt aScreenNo, TDisplayMode aDisplayMode) |
|
2124 { |
|
2125 DeleteGraphicsContext(); |
|
2126 DeleteScreenDevice(); |
|
2127 TRAPD(err, iScrDev = CFbsScreenDevice::NewL(aScreenNo, aDisplayMode)); |
|
2128 if(err == KErrNotSupported) |
|
2129 { |
|
2130 return err; |
|
2131 } |
|
2132 TEST(err == KErrNone); |
|
2133 TEST(iScrDev->ScreenNo() == aScreenNo); |
|
2134 err = iScrDev->CreateContext((CGraphicsContext*&)iGc); |
|
2135 TEST(err == KErrNone); |
|
2136 iGc->SetUserDisplayMode(aDisplayMode); |
|
2137 iScrDev->ChangeScreenDevice(NULL); |
|
2138 iScrDev->SetAutoUpdate(EFalse); |
|
2139 iSize = iScrDev->SizeInPixels(); |
|
2140 iCurrentMode = aDisplayMode; |
|
2141 return err; |
|
2142 } |
|
2143 |
|
2144 TInt CTDefect2::CreateScrDevAndContext(TDisplayMode aDisplayMode) |
|
2145 { |
|
2146 return CreateScrDevAndContext(KDefaultScreenNo,aDisplayMode); |
|
2147 } |
|
2148 |
|
2149 void CTDefect2::DeleteScreenDevice() |
|
2150 { |
|
2151 delete iScrDev; |
|
2152 iScrDev = NULL; |
|
2153 } |
|
2154 |
|
2155 void CTDefect2::DeleteGraphicsContext() |
|
2156 { |
|
2157 delete iGc; |
|
2158 iGc = NULL; |
|
2159 } |
|
2160 |
|
2161 void CTDefect2::CreateBitmapL(const TSize& aSize, TDisplayMode aMode) |
|
2162 { |
|
2163 DeleteBitmap(); |
|
2164 iBitmap = new (ELeave) CFbsBitmap; |
|
2165 User::LeaveIfError(iBitmap->Create(aSize, aMode)); |
|
2166 } |
|
2167 |
|
2168 void CTDefect2::DeleteBitmap() |
|
2169 { |
|
2170 if(iBitmap) |
|
2171 { |
|
2172 iBitmap->Reset(); |
|
2173 } |
|
2174 delete iBitmap; |
|
2175 iBitmap = NULL; |
|
2176 } |
|
2177 |
|
2178 void CTDefect2::DeleteBitmapDevice() |
|
2179 { |
|
2180 delete iBmpDevice; |
|
2181 iBmpDevice = NULL; |
|
2182 } |
|
2183 |
|
2184 void CTDefect2::CreateFontL() |
|
2185 { |
|
2186 CFbsFont* font = NULL; |
|
2187 TFontSpec fs(_L("Swiss"), 12); |
|
2188 User::LeaveIfError(iScrDev->GetNearestFontToDesignHeightInPixels(font, fs)); |
|
2189 iGc->UseFont(font); |
|
2190 } |
|
2191 |
|
2192 void CTDefect2::DestroyFont() |
|
2193 { |
|
2194 if(iGc) |
|
2195 { |
|
2196 iGc->DiscardFont(); |
|
2197 } |
|
2198 } |
|
2199 |
|
2200 /** |
|
2201 @SYMTestCaseID GRAPHICS-BITGDI-0073 |
|
2202 |
|
2203 @SYMDEF |
|
2204 |
|
2205 @SYMTestCaseDesc Clear with non-zero origin |
|
2206 |
|
2207 @SYMTestPriority High |
|
2208 |
|
2209 @SYMTestStatus Implemented |
|
2210 |
|
2211 @SYMTestActions Creates a gc, setes its origin off (0,0) then clears it |
|
2212 |
|
2213 @SYMTestExpectedResults Test should perform graphics operations succesfully. |
|
2214 */ |
|
2215 void CTDefect2::NonZeroOriginClearL() |
|
2216 { |
|
2217 TInt err=CreateScrDevAndContext(EColor64K); |
|
2218 if (err==KErrNotSupported) |
|
2219 err=CreateScrDevAndContext(EColor16MA); |
|
2220 if (err==KErrNotSupported) |
|
2221 err=CreateScrDevAndContext(EColor16MAP); |
|
2222 if (err!=KErrNone) |
|
2223 { |
|
2224 _LIT(KLog,"Failed to create screen device, err=%d"); |
|
2225 INFO_PRINTF2(KLog,err); |
|
2226 } |
|
2227 TRgb setColor(TRgb::Color64K(13897)); |
|
2228 iGc->SetBrushColor(setColor); |
|
2229 iGc->SetOrigin(TPoint(100,100)); |
|
2230 iGc->Clear(); |
|
2231 iScrDev->Update(); |
|
2232 |
|
2233 //Check samples of the screen that it is the right color |
|
2234 TSize size=iScrDev->SizeInPixels(); |
|
2235 TInt x; |
|
2236 TInt y; |
|
2237 |
|
2238 for (x=0;x<size.iWidth;x+=10) |
|
2239 { |
|
2240 for (y=0;y<size.iHeight;y+=10) |
|
2241 { |
|
2242 TRgb gotColor; |
|
2243 iScrDev->GetPixel(gotColor, TPoint(x,y)); |
|
2244 TEST(gotColor==setColor); |
|
2245 } |
|
2246 } |
|
2247 } |
|
2248 |
|
2249 /** |
|
2250 @SYMTestCaseID GRAPHICS-BITGDI-0108 |
|
2251 |
|
2252 @SYMDEF PDEF127874 |
|
2253 |
|
2254 @SYMTestCaseDesc Use pattern brush bitmaps with zero widths or zero height or both |
|
2255 |
|
2256 @SYMTestPriority High |
|
2257 |
|
2258 @SYMTestStatus Implemented |
|
2259 |
|
2260 @SYMTestActions Creates 3 bitmaps: |
|
2261 One with zero width, one with zero height, one width zero width and height. |
|
2262 Each bitmap should automatically be cleared to white. |
|
2263 Clear the screen to black. |
|
2264 Set the GC to use patterned brush. |
|
2265 In turn, set the brush pattern to be one of the bitmap and draw a rectangle. |
|
2266 @SYMTestExpectedResults Each rectangle drawn should remain black as each pattern brush should not be used. |
|
2267 */ |
|
2268 void CTDefect2::ZeroSizedPatternBrushL() |
|
2269 { |
|
2270 // Create a source bitmap with zero width |
|
2271 CFbsBitmap* bmp1 = new (ELeave) CFbsBitmap(); |
|
2272 CleanupStack::PushL(bmp1); |
|
2273 User::LeaveIfError(bmp1->Create(TSize(0,1), EColor16MU)); |
|
2274 |
|
2275 // Create a source bitmap with zero height |
|
2276 CFbsBitmap* bmp2 = new(ELeave) CFbsBitmap(); |
|
2277 CleanupStack::PushL(bmp2); |
|
2278 User::LeaveIfError(bmp2->Create(TSize(1,0), EColor16MU)); |
|
2279 |
|
2280 // Create a source bitmap with zero width and height |
|
2281 CFbsBitmap* bmp3 = new (ELeave) CFbsBitmap(); |
|
2282 CleanupStack::PushL(bmp3); |
|
2283 User::LeaveIfError(bmp3->Create(TSize(0,0), EColor16MU)); |
|
2284 |
|
2285 //Create a screen device & gc |
|
2286 CreateScrDevAndContextL(); |
|
2287 |
|
2288 TRgb clearColor = KRgbBlack; |
|
2289 iGc->SetBrushColor(clearColor); |
|
2290 iGc->Clear(); |
|
2291 iScrDev->Update(); |
|
2292 iGc->SetPenStyle(CGraphicsContext::ENullPen); |
|
2293 iGc->SetBrushStyle(CGraphicsContext::EPatternedBrush); |
|
2294 TSize drawRectSize(10,3); |
|
2295 // Draw a rectangle using each bitmap as a brush pattern |
|
2296 // Each rectangle does not overlap |
|
2297 iGc->UseBrushPattern(bmp1); |
|
2298 iGc->DrawRect(TRect(TPoint(0,0),drawRectSize)); |
|
2299 |
|
2300 iGc->UseBrushPattern(bmp2); |
|
2301 iGc->DrawRect(TRect(TPoint(0,4),drawRectSize)); |
|
2302 |
|
2303 iGc->UseBrushPattern(bmp3); |
|
2304 iGc->DrawRect(TRect(TPoint(0,8),drawRectSize)); |
|
2305 |
|
2306 iScrDev->Update(); |
|
2307 // Bitmaps should be cleared to white when created, so if they are drawn |
|
2308 // will show up different to cleared screen. |
|
2309 for(TInt y=0; y<12; ++y) |
|
2310 { |
|
2311 for(TInt x=0; x<10; ++x) |
|
2312 { |
|
2313 TRgb pixelColor; |
|
2314 iScrDev->GetPixel(pixelColor,TPoint(x,y)); |
|
2315 TEST(pixelColor==clearColor); |
|
2316 } |
|
2317 } |
|
2318 CleanupStack::PopAndDestroy(3, bmp1); |
|
2319 DeleteGraphicsContext(); |
|
2320 DeleteScreenDevice(); |
|
2321 } |
|
2322 |
|
2323 /** |
|
2324 @SYMTestCaseID GRAPHICS-BITGDI-0110 |
|
2325 |
|
2326 @SYMDEF INC128813,PDEF129382 |
|
2327 |
|
2328 @SYMTestCaseDesc Test CFbsBitGc::InternalizeL() when the font duplicate called from |
|
2329 CFbsBitGc::Internalize:() fails. |
|
2330 |
|
2331 @SYMTestPriority Normal |
|
2332 |
|
2333 @SYMTestStatus Implemented (udeb/ debug versions only) |
|
2334 |
|
2335 @SYMTestActions Create and externalize a the CFbsBitGc*. |
|
2336 Then send a message to the font and bitmap server to force |
|
2337 CFbsBitGcFont::Duplicate() calls to fail. |
|
2338 Internalize the CFbsBitGc*() |
|
2339 Then send a message to the font and bitmap server to allow |
|
2340 CFbsBitGcFont::Duplicate() calls to succeed. |
|
2341 If the test runs to completion without any panics, then it has passed. |
|
2342 */ |
|
2343 void CTDefect2::CFbsBitGcInternalizeLFailL() |
|
2344 { |
|
2345 // this code is based on test CTDefect2::DEF039331L(); |
|
2346 #ifndef _DEBUG |
|
2347 INFO_PRINTF1(_L("Cannot run CFbsBitGcInternalizeLFailL test because test needs udeb for fbserv")); |
|
2348 return; |
|
2349 |
|
2350 #else |
|
2351 CreateScrDevAndContextL(); |
|
2352 |
|
2353 //Make sure that the archive file does not exist. |
|
2354 FServSession.Delete(KArchiveFileName); |
|
2355 |
|
2356 CBufFlat* flatBuf = CBufFlat::NewL(256); |
|
2357 CleanupStack::PushL(flatBuf); |
|
2358 RBufWriteStream wrStream(*flatBuf); |
|
2359 ::CleanupClosePushL(wrStream); |
|
2360 |
|
2361 CreateFontL(); |
|
2362 |
|
2363 iGc->ExternalizeL(wrStream); |
|
2364 wrStream.CommitL(); |
|
2365 CleanupStack::PopAndDestroy();//wrStream |
|
2366 |
|
2367 RBufReadStream rdStream(*flatBuf); |
|
2368 ::CleanupClosePushL(rdStream); |
|
2369 |
|
2370 RFbsSession::GetSession()->SendCommand(static_cast<TInt>(EFbsMessSetDuplicateFail),1); |
|
2371 |
|
2372 TInt ret=KErrNone; |
|
2373 TRAP(ret, (void)(iGc->InternalizeL(rdStream))); |
|
2374 INFO_PRINTF2(_L("CFbsBitGcInternalizeLFailL test returned %d: should have an error code"),ret); |
|
2375 |
|
2376 RFbsSession::GetSession()->SendCommand(static_cast<TInt>(EFbsMessSetDuplicateFail),0); |
|
2377 |
|
2378 //Without the fix there is a Kern-Exec3 panic. |
|
2379 TEST (ETrue); |
|
2380 CleanupStack::PopAndDestroy(2,flatBuf); |
|
2381 #endif |
|
2382 } |
|
2383 |
|
2384 /** |
|
2385 @SYMTestCaseID GRAPHICS-BITGDI-0111 |
|
2386 |
|
2387 @SYMDEF DEF132331 |
|
2388 |
|
2389 @SYMTestCaseDesc Compare output from CFbsScreenDevice::HorizontalPixelsToTwips() and |
|
2390 VerticalPixelsToTwips() with the same methods in CWsScreenDevice with |
|
2391 large input numbers. |
|
2392 |
|
2393 @SYMTestPriority Normal |
|
2394 |
|
2395 @SYMTestStatus Implemented |
|
2396 |
|
2397 @SYMTestActions Creates an instance of CWsScreenDevice (instance of CFbsScreenDevice already prepared for |
|
2398 other tests). Call the pixels to twips and twips to pixels conversion methods on each with same |
|
2399 number. Compare the resulting output. |
|
2400 @SYMTestExpectedResults Outputs should be within a small tolerance. |
|
2401 */ |
|
2402 void CTDefect2::PixelsToTwipsConversionCheck() |
|
2403 { |
|
2404 const TInt KHorizontalTestPixels=64000000; |
|
2405 const TInt KVerticalTestPixels=24000000; |
|
2406 const TReal32 KTolerance=0.10; // Percent difference permitted |
|
2407 TInt cFbsScreenDeviceResult = 1; |
|
2408 TInt cWsScreenDeviceResult = 1; |
|
2409 TReal32 percentDifference = 0.0; |
|
2410 CreateScrDevAndContextL(); |
|
2411 |
|
2412 RWsSession wsSession; |
|
2413 if (KErrNone == wsSession.Connect()) |
|
2414 { |
|
2415 CWsScreenDevice* wsScrDev = new (ELeave) CWsScreenDevice(wsSession); |
|
2416 wsScrDev->Construct(0); |
|
2417 |
|
2418 // first compare results of the two class's HorizontalPixelsToTwips and pass |
|
2419 // the test if they are within tolerance |
|
2420 cFbsScreenDeviceResult = iScrDev->HorizontalPixelsToTwips(KHorizontalTestPixels); |
|
2421 cWsScreenDeviceResult = wsScrDev->HorizontalPixelsToTwips(KHorizontalTestPixels); |
|
2422 percentDifference = Abs((TReal32)(cFbsScreenDeviceResult - cWsScreenDeviceResult)/cFbsScreenDeviceResult*100.0); |
|
2423 TEST(percentDifference < KTolerance); |
|
2424 |
|
2425 // convert the CWsScreenDevice result back again using each class's HorizontalTwipsToPixels |
|
2426 // and pass the test if these results are within tolerance |
|
2427 cFbsScreenDeviceResult = iScrDev->HorizontalTwipsToPixels(cWsScreenDeviceResult); |
|
2428 cWsScreenDeviceResult = wsScrDev->HorizontalTwipsToPixels(cWsScreenDeviceResult); |
|
2429 percentDifference = Abs((TReal32)(cFbsScreenDeviceResult - cWsScreenDeviceResult)/cFbsScreenDeviceResult*100.0); |
|
2430 TEST(percentDifference < KTolerance); |
|
2431 |
|
2432 // next compare results of the two class's VerticalPixelsToTwips and pass the test |
|
2433 // if they are within tolerance |
|
2434 cFbsScreenDeviceResult = iScrDev->VerticalPixelsToTwips(KVerticalTestPixels); |
|
2435 cWsScreenDeviceResult= wsScrDev->VerticalPixelsToTwips(KVerticalTestPixels); |
|
2436 percentDifference = Abs((TReal32)(cFbsScreenDeviceResult - cWsScreenDeviceResult)/cFbsScreenDeviceResult*100.0); |
|
2437 TEST(percentDifference < KTolerance); |
|
2438 |
|
2439 // convert the CWsScreenDevice result back again using each class's VerticalTwipsToPixels |
|
2440 // and pass the test if these results are within tolerance |
|
2441 cFbsScreenDeviceResult = iScrDev->VerticalTwipsToPixels(cWsScreenDeviceResult); |
|
2442 cWsScreenDeviceResult = wsScrDev->VerticalTwipsToPixels(cWsScreenDeviceResult); |
|
2443 percentDifference = Abs((TReal32)(cFbsScreenDeviceResult - cWsScreenDeviceResult)/cFbsScreenDeviceResult*100.0); |
|
2444 TEST(percentDifference < KTolerance); |
|
2445 |
|
2446 delete wsScrDev; |
|
2447 wsSession.Close(); |
|
2448 } |
|
2449 else |
|
2450 { |
|
2451 iStep->SetTestStepResult(EFail); |
|
2452 _LIT(KMessage,"ERROR: Test Failed"); |
|
2453 Logger().LogExtra((TText8*)__FILE__, __LINE__, ESevrErr,KMessage); |
|
2454 } |
|
2455 } |
|
2456 |
|
2457 /** |
|
2458 @SYMTestCaseID GRAPHICS-BITGDI-0113 |
|
2459 |
|
2460 @SYMDEF PDEF138111 |
|
2461 |
|
2462 @SYMTestCaseDesc Test CFbsBitGc::CopyRect() with non-trivial alpha channel |
|
2463 |
|
2464 @SYMTestPriority Normal |
|
2465 |
|
2466 @SYMTestStatus Implemented |
|
2467 |
|
2468 @SYMTestActions Create a 128 by 128 pixel bitmap with display mode EColor16MA. |
|
2469 Fill the upper half of the bitmap with semi-transparent gray. |
|
2470 Call CFbsBitGc::CopyRect() to copy the upper half to the lower half. |
|
2471 Sample one pixel from both the upper and lower half of the bitmap. |
|
2472 |
|
2473 @SYMTestExpectedResults The two pixels should be the same. Without the fix the lower part |
|
2474 would show a lighter shade of the gray. |
|
2475 */ |
|
2476 void CTDefect2::CopyRectAlphaL() |
|
2477 { |
|
2478 TSize size = TSize(128, 128); |
|
2479 |
|
2480 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); |
|
2481 CleanupStack::PushL(bitmap); |
|
2482 User::LeaveIfError(bitmap->Create(size, EColor16MA)); |
|
2483 |
|
2484 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap); |
|
2485 CleanupStack::PushL(bitmapDevice); |
|
2486 |
|
2487 CFbsBitGc* bitmapContext = NULL; |
|
2488 User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext)); |
|
2489 CleanupStack::PushL(bitmapContext); |
|
2490 |
|
2491 bitmap->BeginDataAccess(); |
|
2492 Mem::Fill(bitmap->DataAddress(), 128 * 4 * 64, 0x80); |
|
2493 bitmap->EndDataAccess(); |
|
2494 bitmapContext->CopyRect(TPoint(0, 64), TRect(0, 0, 128, 64)); |
|
2495 |
|
2496 //sample a pixel from the lower part of the bitmap and it should be the same as the upper half |
|
2497 TRgb pixelColorUpper; |
|
2498 bitmap->GetPixel(pixelColorUpper, TPoint(2, 3)); |
|
2499 TRgb pixelColorLower; |
|
2500 bitmap->GetPixel(pixelColorLower, TPoint(80, 90)); |
|
2501 TEST(pixelColorUpper == pixelColorLower); |
|
2502 |
|
2503 CleanupStack::PopAndDestroy(3, bitmap); |
|
2504 } |
|
2505 |
|
2506 // |
|
2507 |
|
2508 class TTestSetBitsThread: public TFunctionThread |
|
2509 { |
|
2510 public: |
|
2511 TTestSetBitsThread(TDisplayMode aDisplayMode, TBool aVerticalResize, TBool aScaling); |
|
2512 private: |
|
2513 virtual TInt ThreadFunctionL(); |
|
2514 private: |
|
2515 TDisplayMode iDisplayMode; |
|
2516 TBool iVerticalResize; |
|
2517 TBool iScaling; |
|
2518 }; |
|
2519 |
|
2520 TTestSetBitsThread::TTestSetBitsThread(TDisplayMode aDisplayMode, TBool aVerticalResize, TBool aScaling) |
|
2521 : iDisplayMode(aDisplayMode), iVerticalResize(aVerticalResize), iScaling(aScaling) |
|
2522 { |
|
2523 TBuf<32> threadName; |
|
2524 threadName.Format(_L("TestSetBits-%d-%d-%d"), TInt(aDisplayMode), TInt(aVerticalResize), TInt(aScaling)); |
|
2525 LaunchThreadFunction(threadName); |
|
2526 } |
|
2527 |
|
2528 TInt TTestSetBitsThread::ThreadFunctionL() |
|
2529 { |
|
2530 CFbsBitmap* bmp = new(ELeave) CFbsBitmap; |
|
2531 CleanupStack::PushL(bmp); |
|
2532 User::LeaveIfError(bmp->Create(TSize(256, 256), iDisplayMode)); |
|
2533 CFbsBitmapDevice* bmpDev = CFbsBitmapDevice::NewL(bmp); |
|
2534 CleanupStack::PushL(bmpDev); |
|
2535 if (iScaling) |
|
2536 { |
|
2537 User::LeaveIfError(bmpDev->SetScalingFactor(TPoint(0, 0), 2, 2, 1, 1)); |
|
2538 } |
|
2539 if (iVerticalResize) |
|
2540 { |
|
2541 User::LeaveIfError(bmp->Resize(TSize(256, 128))); |
|
2542 } |
|
2543 else |
|
2544 { |
|
2545 User::LeaveIfError(bmp->Resize(TSize(128, 256))); |
|
2546 } |
|
2547 bmpDev->DrawingBegin(); |
|
2548 bmpDev->DrawingEnd(); |
|
2549 CleanupStack::PopAndDestroy(2); |
|
2550 return 0; |
|
2551 } |
|
2552 |
|
2553 /** |
|
2554 @SYMTestCaseID GRAPHICS-BITGDI-0112 |
|
2555 |
|
2556 @SYMDEF PDEF138375 |
|
2557 |
|
2558 @SYMTestCaseDesc Makes sure that CFbsBitmapDevice::SetBits() checks that the bitmap size is consistent. |
|
2559 |
|
2560 @SYMTestPriority Normal |
|
2561 |
|
2562 @SYMTestStatus Implemented |
|
2563 |
|
2564 @SYMTestActions 1. Creates a bitmap and an associated bitmap device. |
|
2565 2. Resizes the bitmap directly. |
|
2566 3. Calls DrawingBegin()/DrawingEnd() on the bitmap device. |
|
2567 |
|
2568 @SYMTestExpectedResults The call to DrawingBegin() should panic in debug builds. |
|
2569 */ |
|
2570 void CTDefect2::TestSetBitsL() |
|
2571 { |
|
2572 #ifdef _DEBUG |
|
2573 for (TBool verticalResize = 0; verticalResize <= 1; ++verticalResize) |
|
2574 { |
|
2575 for (TBool scaling = 0; scaling <= 1; ++scaling) |
|
2576 { |
|
2577 TTestSetBitsThread testThread1(EGray2, verticalResize, scaling); |
|
2578 TEST(testThread1.iExitHow == TFunctionThread::EPanic); |
|
2579 TEST(testThread1.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2580 |
|
2581 TTestSetBitsThread testThread2(EGray4, verticalResize, scaling); |
|
2582 TEST(testThread2.iExitHow == TFunctionThread::EPanic); |
|
2583 TEST(testThread2.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2584 |
|
2585 TTestSetBitsThread testThread3(EGray16, verticalResize, scaling); |
|
2586 TEST(testThread3.iExitHow == TFunctionThread::EPanic); |
|
2587 TEST(testThread3.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2588 |
|
2589 TTestSetBitsThread testThread4(EColor16, verticalResize, scaling); |
|
2590 TEST(testThread4.iExitHow == TFunctionThread::EPanic); |
|
2591 TEST(testThread4.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2592 |
|
2593 TTestSetBitsThread testThread5(EGray256, verticalResize, scaling); |
|
2594 TEST(testThread5.iExitHow == TFunctionThread::EPanic); |
|
2595 TEST(testThread5.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2596 |
|
2597 TTestSetBitsThread testThread6(EColor256, verticalResize, scaling); |
|
2598 TEST(testThread6.iExitHow == TFunctionThread::EPanic); |
|
2599 TEST(testThread6.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2600 |
|
2601 TTestSetBitsThread testThread7(EColor4K, verticalResize, scaling); |
|
2602 TEST(testThread7.iExitHow == TFunctionThread::EPanic); |
|
2603 TEST(testThread7.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2604 |
|
2605 TTestSetBitsThread testThread8(EColor64K, verticalResize, scaling); |
|
2606 TEST(testThread8.iExitHow == TFunctionThread::EPanic); |
|
2607 TEST(testThread8.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2608 |
|
2609 TTestSetBitsThread testThread9(EColor16M, verticalResize, scaling); |
|
2610 TEST(testThread9.iExitHow == TFunctionThread::EPanic); |
|
2611 TEST(testThread9.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2612 |
|
2613 TTestSetBitsThread testThread10(EColor16MU, verticalResize, scaling); |
|
2614 TEST(testThread10.iExitHow == TFunctionThread::EPanic); |
|
2615 TEST(testThread10.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2616 |
|
2617 TTestSetBitsThread testThread11(EColor16MA, verticalResize, scaling); |
|
2618 TEST(testThread11.iExitHow == TFunctionThread::EPanic); |
|
2619 TEST(testThread11.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2620 |
|
2621 TTestSetBitsThread testThread12(EColor16MAP, verticalResize, scaling); |
|
2622 TEST(testThread12.iExitHow == TFunctionThread::EPanic); |
|
2623 TEST(testThread12.iExitCode == EBitgdiPanicInvalidBitmap); |
|
2624 } |
|
2625 } |
|
2626 #else |
|
2627 WARN_PRINTF1(_L("Test skipped because it needs udeb build")); |
|
2628 #endif |
|
2629 } |
|
2630 |
|
2631 //-------------- |
|
2632 __CONSTRUCT_STEP__(Defect2) |
|
2633 |
|
2634 void CTDefect2Step::TestSetupL() |
|
2635 { |
|
2636 } |
|
2637 |
|
2638 void CTDefect2Step::TestClose() |
|
2639 { |
|
2640 ::DeleteDataFile(KArchiveFileName); |
|
2641 } |