Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: tests/ReadPixelsTest.cpp

Issue 199413013: add new readPixels with direct memory parameters (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapDevice.h" 8 #include "SkBitmapDevice.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 53
54 static SkPMColor getBitmapColor(int x, int y, int w) { 54 static SkPMColor getBitmapColor(int x, int y, int w) {
55 int n = y * w + x; 55 int n = y * w + x;
56 56
57 U8CPU b = n & 0xff; 57 U8CPU b = n & 0xff;
58 U8CPU g = (n >> 8) & 0xff; 58 U8CPU g = (n >> 8) & 0xff;
59 U8CPU r = (n >> 16) & 0xff; 59 U8CPU r = (n >> 16) & 0xff;
60 return SkPackARGB32(0xff, r, g , b); 60 return SkPackARGB32(0xff, r, g , b);
61 } 61 }
62 62
63 static SkPMColor convertConfig8888ToPMColor(SkCanvas::Config8888 config8888, 63 static SkPMColor convertToPMColor(SkColorType ct, SkAlphaType at, const uint32_t * addr,
64 uint32_t color, 64 bool* doUnpremul) {
65 bool* premul) { 65 *doUnpremul = (kUnpremul_SkAlphaType == at);
66 const uint8_t* c = reinterpret_cast<uint8_t*>(&color); 66
67 const uint8_t* c = reinterpret_cast<const uint8_t*>(addr);
67 U8CPU a,r,g,b; 68 U8CPU a,r,g,b;
68 *premul = false; 69 switch (ct) {
69 switch (config8888) { 70 case kBGRA_8888_SkColorType:
70 case SkCanvas::kNative_Premul_Config8888: 71 b = static_cast<U8CPU>(c[0]);
71 return color; 72 g = static_cast<U8CPU>(c[1]);
72 case SkCanvas::kNative_Unpremul_Config8888: 73 r = static_cast<U8CPU>(c[2]);
73 *premul = true; 74 a = static_cast<U8CPU>(c[3]);
74 a = SkGetPackedA32(color);
75 r = SkGetPackedR32(color);
76 g = SkGetPackedG32(color);
77 b = SkGetPackedB32(color);
78 break; 75 break;
79 case SkCanvas::kBGRA_Unpremul_Config8888: 76 case kRGBA_8888_SkColorType:
80 *premul = true; // fallthru
81 case SkCanvas::kBGRA_Premul_Config8888:
82 a = static_cast<U8CPU>(c[3]);
83 r = static_cast<U8CPU>(c[2]);
84 g = static_cast<U8CPU>(c[1]);
85 b = static_cast<U8CPU>(c[0]);
86 break;
87 case SkCanvas::kRGBA_Unpremul_Config8888:
88 *premul = true; // fallthru
89 case SkCanvas::kRGBA_Premul_Config8888:
90 a = static_cast<U8CPU>(c[3]);
91 r = static_cast<U8CPU>(c[0]); 77 r = static_cast<U8CPU>(c[0]);
92 g = static_cast<U8CPU>(c[1]); 78 g = static_cast<U8CPU>(c[1]);
93 b = static_cast<U8CPU>(c[2]); 79 b = static_cast<U8CPU>(c[2]);
80 a = static_cast<U8CPU>(c[3]);
94 break; 81 break;
95 default: 82 default:
96 SkDEBUGFAIL("Unexpected Config8888"); 83 SkDEBUGFAIL("Unexpected colortype");
97 return 0; 84 return 0;
98 } 85 }
99 if (*premul) { 86
87 if (*doUnpremul) {
100 r = SkMulDiv255Ceiling(r, a); 88 r = SkMulDiv255Ceiling(r, a);
101 g = SkMulDiv255Ceiling(g, a); 89 g = SkMulDiv255Ceiling(g, a);
102 b = SkMulDiv255Ceiling(b, a); 90 b = SkMulDiv255Ceiling(b, a);
103 } 91 }
104 return SkPackARGB32(a, r, g, b); 92 return SkPackARGB32(a, r, g, b);
105 } 93 }
106 94
107 static void fillCanvas(SkCanvas* canvas) { 95 static void fillCanvas(SkCanvas* canvas) {
108 static SkBitmap bmp; 96 static SkBitmap bmp;
109 if (bmp.isNull()) { 97 if (bmp.isNull()) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 SkAbs32(aB - bB) <= 1; 149 SkAbs32(aB - bB) <= 1;
162 } 150 }
163 151
164 // checks the bitmap contains correct pixels after the readPixels 152 // checks the bitmap contains correct pixels after the readPixels
165 // if the bitmap was prefilled with pixels it checks that these weren't 153 // if the bitmap was prefilled with pixels it checks that these weren't
166 // overwritten in the area outside the readPixels. 154 // overwritten in the area outside the readPixels.
167 static bool checkRead(skiatest::Reporter* reporter, 155 static bool checkRead(skiatest::Reporter* reporter,
168 const SkBitmap& bitmap, 156 const SkBitmap& bitmap,
169 int x, int y, 157 int x, int y,
170 bool checkCanvasPixels, 158 bool checkCanvasPixels,
171 bool checkBitmapPixels, 159 bool checkBitmapPixels) {
172 SkCanvas::Config8888 config8888) { 160 SkASSERT(4 == bitmap.bytesPerPixel());
173 SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
174 SkASSERT(!bitmap.isNull()); 161 SkASSERT(!bitmap.isNull());
175 SkASSERT(checkCanvasPixels || checkBitmapPixels); 162 SkASSERT(checkCanvasPixels || checkBitmapPixels);
176 163
164 const SkColorType ct = bitmap.colorType();
165 const SkAlphaType at = bitmap.alphaType();
166
177 int bw = bitmap.width(); 167 int bw = bitmap.width();
178 int bh = bitmap.height(); 168 int bh = bitmap.height();
179 169
180 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh); 170 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh);
181 SkIRect clippedSrcRect = DEV_RECT; 171 SkIRect clippedSrcRect = DEV_RECT;
182 if (!clippedSrcRect.intersect(srcRect)) { 172 if (!clippedSrcRect.intersect(srcRect)) {
183 clippedSrcRect.setEmpty(); 173 clippedSrcRect.setEmpty();
184 } 174 }
185 SkAutoLockPixels alp(bitmap); 175 SkAutoLockPixels alp(bitmap);
186 intptr_t pixels = reinterpret_cast<intptr_t>(bitmap.getPixels());
187 for (int by = 0; by < bh; ++by) { 176 for (int by = 0; by < bh; ++by) {
188 for (int bx = 0; bx < bw; ++bx) { 177 for (int bx = 0; bx < bw; ++bx) {
189 int devx = bx + srcRect.fLeft; 178 int devx = bx + srcRect.fLeft;
190 int devy = by + srcRect.fTop; 179 int devy = by + srcRect.fTop;
191 180
192 uint32_t pixel = *reinterpret_cast<SkPMColor*>(pixels + by * bitmap. rowBytes() + bx * bitmap.bytesPerPixel()); 181 const uint32_t* pixel = bitmap.getAddr32(bx, by);
193 182
194 if (clippedSrcRect.contains(devx, devy)) { 183 if (clippedSrcRect.contains(devx, devy)) {
195 if (checkCanvasPixels) { 184 if (checkCanvasPixels) {
196 SkPMColor canvasPixel = getCanvasColor(devx, devy); 185 SkPMColor canvasPixel = getCanvasColor(devx, devy);
197 bool didPremul; 186 bool didPremul;
198 SkPMColor pmPixel = convertConfig8888ToPMColor(config8888, p ixel, &didPremul); 187 SkPMColor pmPixel = convertToPMColor(ct, at, pixel, &didPrem ul);
199 bool check; 188 bool check;
200 REPORTER_ASSERT(reporter, check = checkPixel(pmPixel, canvas Pixel, didPremul)); 189 REPORTER_ASSERT(reporter, check = checkPixel(pmPixel, canvas Pixel, didPremul));
201 if (!check) { 190 if (!check) {
202 return false; 191 return false;
203 } 192 }
204 } 193 }
205 } else if (checkBitmapPixels) { 194 } else if (checkBitmapPixels) {
206 REPORTER_ASSERT(reporter, getBitmapColor(bx, by, bw) == pixel); 195 REPORTER_ASSERT(reporter, getBitmapColor(bx, by, bw) == *pixel);
207 if (getBitmapColor(bx, by, bw) != pixel) { 196 if (getBitmapColor(bx, by, bw) != *pixel) {
208 return false; 197 return false;
209 } 198 }
210 } 199 }
211 } 200 }
212 } 201 }
213 return true; 202 return true;
214 } 203 }
215 204
216 enum BitmapInit { 205 enum BitmapInit {
217 kFirstBitmapInit = 0, 206 kFirstBitmapInit = 0,
218 207
219 kNoPixels_BitmapInit = kFirstBitmapInit, 208 kNoPixels_BitmapInit = kFirstBitmapInit,
220 kTight_BitmapInit, 209 kTight_BitmapInit,
221 kRowBytes_BitmapInit, 210 kRowBytes_BitmapInit,
222 211
223 kBitmapInitCnt 212 kBitmapInitCnt
224 }; 213 };
225 214
226 static BitmapInit nextBMI(BitmapInit bmi) { 215 static BitmapInit nextBMI(BitmapInit bmi) {
227 int x = bmi; 216 int x = bmi;
228 return static_cast<BitmapInit>(++x); 217 return static_cast<BitmapInit>(++x);
229 } 218 }
230 219
231 static void init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init) { 220 static void init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init, SkColorType ct,
232 SkImageInfo info = SkImageInfo::MakeN32Premul(rect.width(), rect.height()); 221 SkAlphaType at) {
222 SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), ct, at);
233 size_t rowBytes = 0; 223 size_t rowBytes = 0;
234 bool alloc = true; 224 bool alloc = true;
235 switch (init) { 225 switch (init) {
236 case kNoPixels_BitmapInit: 226 case kNoPixels_BitmapInit:
237 alloc = false; 227 alloc = false;
238 case kTight_BitmapInit: 228 case kTight_BitmapInit:
239 break; 229 break;
240 case kRowBytes_BitmapInit: 230 case kRowBytes_BitmapInit:
241 rowBytes = (info.width() + 16) * sizeof(SkPMColor); 231 rowBytes = (info.width() + 16) * sizeof(SkPMColor);
242 break; 232 break;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 GrAutoScratchTexture ast(context, desc, GrContext::kExact_Scratc hTexMatch); 323 GrAutoScratchTexture ast(context, desc, GrContext::kExact_Scratc hTexMatch);
334 SkAutoTUnref<GrTexture> tex(ast.detach()); 324 SkAutoTUnref<GrTexture> tex(ast.detach());
335 device.reset(new SkGpuDevice(context, tex)); 325 device.reset(new SkGpuDevice(context, tex));
336 #else 326 #else
337 continue; 327 continue;
338 #endif 328 #endif
339 } 329 }
340 SkCanvas canvas(device); 330 SkCanvas canvas(device);
341 fillCanvas(&canvas); 331 fillCanvas(&canvas);
342 332
343 static const SkCanvas::Config8888 gReadConfigs[] = { 333 static const struct {
344 SkCanvas::kNative_Premul_Config8888, 334 SkColorType fColorType;
345 SkCanvas::kNative_Unpremul_Config8888, 335 SkAlphaType fAlphaType;
346 336 } gReadConfigs[] = {
347 SkCanvas::kBGRA_Premul_Config8888, 337 { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
348 SkCanvas::kBGRA_Unpremul_Config8888, 338 { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
349 339 { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
350 SkCanvas::kRGBA_Premul_Config8888, 340 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
351 SkCanvas::kRGBA_Unpremul_Config8888,
352 }; 341 };
353 for (size_t rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) { 342 for (size_t rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) {
354 const SkIRect& srcRect = testRects[rect]; 343 const SkIRect& srcRect = testRects[rect];
355 for (BitmapInit bmi = kFirstBitmapInit; 344 for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bm i = nextBMI(bmi)) {
356 bmi < kBitmapInitCnt;
357 bmi = nextBMI(bmi)) {
358 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadConfigs); ++c) { 345 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadConfigs); ++c) {
359 SkCanvas::Config8888 config8888 = gReadConfigs[c];
360 SkBitmap bmp; 346 SkBitmap bmp;
361 init_bitmap(&bmp, srcRect, bmi); 347 init_bitmap(&bmp, srcRect, bmi,
348 gReadConfigs[c].fColorType, gReadConfigs[c]. fAlphaType);
362 349
363 // if the bitmap has pixels allocated before the readPix els, 350 // if the bitmap has pixels allocated before the readPix els,
364 // note that and fill them with pattern 351 // note that and fill them with pattern
365 bool startsWithPixels = !bmp.isNull(); 352 bool startsWithPixels = !bmp.isNull();
366 if (startsWithPixels) { 353 if (startsWithPixels) {
367 fillBitmap(&bmp); 354 fillBitmap(&bmp);
368 } 355 }
369 uint32_t idBefore = canvas.getDevice()->accessBitmap(fal se).getGenerationID(); 356 uint32_t idBefore = canvas.getDevice()->accessBitmap(fal se).getGenerationID();
370 bool success = 357 bool success = canvas.readPixels(&bmp, srcRect.fLeft, sr cRect.fTop);
371 canvas.readPixels(&bmp, srcRect.fLeft,
372 srcRect.fTop, config8888);
373 uint32_t idAfter = canvas.getDevice()->accessBitmap(fals e).getGenerationID(); 358 uint32_t idAfter = canvas.getDevice()->accessBitmap(fals e).getGenerationID();
374 359
375 // we expect to succeed when the read isn't fully clippe d 360 // we expect to succeed when the read isn't fully clippe d
376 // out. 361 // out.
377 bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RE CT); 362 bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RE CT);
378 // determine whether we expected the read to succeed. 363 // determine whether we expected the read to succeed.
379 REPORTER_ASSERT(reporter, success == expectSuccess); 364 REPORTER_ASSERT(reporter, success == expectSuccess);
380 // read pixels should never change the gen id 365 // read pixels should never change the gen id
381 REPORTER_ASSERT(reporter, idBefore == idAfter); 366 REPORTER_ASSERT(reporter, idBefore == idAfter);
382 367
383 if (success || startsWithPixels) { 368 if (success || startsWithPixels) {
384 checkRead(reporter, bmp, srcRect.fLeft, srcRect.fTop , 369 checkRead(reporter, bmp, srcRect.fLeft, srcRect.fTop ,
385 success, startsWithPixels, config8888); 370 success, startsWithPixels);
386 } else { 371 } else {
387 // if we had no pixels beforehand and the readPixels 372 // if we had no pixels beforehand and the readPixels
388 // failed then our bitmap should still not have pixe ls 373 // failed then our bitmap should still not have pixe ls
389 REPORTER_ASSERT(reporter, bmp.isNull()); 374 REPORTER_ASSERT(reporter, bmp.isNull());
390 } 375 }
391 } 376 }
392 // check the old webkit version of readPixels that clips the 377 // check the old webkit version of readPixels that clips the
393 // bitmap size 378 // bitmap size
394 SkBitmap wkbmp; 379 SkBitmap wkbmp;
395 bool success = canvas.readPixels(srcRect, &wkbmp); 380 bool success = canvas.readPixels(srcRect, &wkbmp);
396 SkIRect clippedRect = DEV_RECT; 381 SkIRect clippedRect = DEV_RECT;
397 if (clippedRect.intersect(srcRect)) { 382 if (clippedRect.intersect(srcRect)) {
398 REPORTER_ASSERT(reporter, success); 383 REPORTER_ASSERT(reporter, success);
384 REPORTER_ASSERT(reporter, kPMColor_SkColorType == wkbmp. colorType());
385 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == wkbmp.a lphaType());
399 checkRead(reporter, wkbmp, clippedRect.fLeft, 386 checkRead(reporter, wkbmp, clippedRect.fLeft,
400 clippedRect.fTop, true, false, 387 clippedRect.fTop, true, false);
401 SkCanvas::kNative_Premul_Config8888);
402 } else { 388 } else {
403 REPORTER_ASSERT(reporter, !success); 389 REPORTER_ASSERT(reporter, !success);
404 } 390 }
405 } 391 }
406 } 392 }
407 } 393 }
408 } 394 }
409 } 395 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698