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

Side by Side Diff: tests/ReadPixelsTest.cpp

Issue 2407093002: implement A8 destination fast-path for SkPixelInfo::CopyPixels (Closed)
Patch Set: add testing of readPixels in kAlpha8_SkAlphaType in ReadPixelsTest Created 4 years, 2 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
« no previous file with comments | « src/core/SkConfig8888.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkMathPriv.h" 10 #include "SkMathPriv.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 128 }
129 #endif 129 #endif
130 130
131 static void fill_dst_bmp_with_init_data(SkBitmap* bitmap) { 131 static void fill_dst_bmp_with_init_data(SkBitmap* bitmap) {
132 SkAutoLockPixels alp(*bitmap); 132 SkAutoLockPixels alp(*bitmap);
133 int w = bitmap->width(); 133 int w = bitmap->width();
134 int h = bitmap->height(); 134 int h = bitmap->height();
135 intptr_t pixels = reinterpret_cast<intptr_t>(bitmap->getPixels()); 135 intptr_t pixels = reinterpret_cast<intptr_t>(bitmap->getPixels());
136 for (int y = 0; y < h; ++y) { 136 for (int y = 0; y < h; ++y) {
137 for (int x = 0; x < w; ++x) { 137 for (int x = 0; x < w; ++x) {
138 SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bitmap- >rowBytes() + x * bitmap->bytesPerPixel()); 138 SkPMColor initColor = get_dst_bmp_init_color(x, y, w);
139 *pixel = get_dst_bmp_init_color(x, y, w); 139 if (kAlpha_8_SkColorType == bitmap->colorType()) {
140 uint8_t* alpha = reinterpret_cast<uint8_t*>(pixels + y * bitmap- >rowBytes() + x);
141 *alpha = SkGetPackedA32(initColor);
142 } else {
143 SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bit map->rowBytes() + x * bitmap->bytesPerPixel());
144 *pixel = initColor;
145 }
140 } 146 }
141 } 147 }
142 } 148 }
143 149
144 static bool check_read_pixel(SkPMColor a, SkPMColor b, bool didPremulConversion) { 150 static bool check_read_pixel(SkPMColor a, SkPMColor b, bool didPremulConversion) {
145 if (!didPremulConversion) { 151 if (!didPremulConversion) {
146 return a == b; 152 return a == b;
147 } 153 }
148 int32_t aA = static_cast<int32_t>(SkGetPackedA32(a)); 154 int32_t aA = static_cast<int32_t>(SkGetPackedA32(a));
149 int32_t aR = static_cast<int32_t>(SkGetPackedR32(a)); 155 int32_t aR = static_cast<int32_t>(SkGetPackedR32(a));
(...skipping 11 matching lines...) Expand all
161 SkAbs32(aB - bB) <= 1; 167 SkAbs32(aB - bB) <= 1;
162 } 168 }
163 169
164 // checks the bitmap contains correct pixels after the readPixels 170 // checks the bitmap contains correct pixels after the readPixels
165 // if the bitmap was prefilled with pixels it checks that these weren't 171 // if the bitmap was prefilled with pixels it checks that these weren't
166 // overwritten in the area outside the readPixels. 172 // overwritten in the area outside the readPixels.
167 static bool check_read(skiatest::Reporter* reporter, 173 static bool check_read(skiatest::Reporter* reporter,
168 const SkBitmap& bitmap, 174 const SkBitmap& bitmap,
169 int x, int y, 175 int x, int y,
170 bool checkCanvasPixels, 176 bool checkCanvasPixels,
171 bool checkBitmapPixels) { 177 bool checkBitmapPixels,
172 SkASSERT(4 == bitmap.bytesPerPixel()); 178 SkColorType ct,
179 SkAlphaType at) {
180 SkASSERT(ct == bitmap.colorType() && at == bitmap.alphaType());
173 SkASSERT(!bitmap.isNull()); 181 SkASSERT(!bitmap.isNull());
174 SkASSERT(checkCanvasPixels || checkBitmapPixels); 182 SkASSERT(checkCanvasPixels || checkBitmapPixels);
175 183
176 const SkColorType ct = bitmap.colorType();
177 const SkAlphaType at = bitmap.alphaType();
178
179 int bw = bitmap.width(); 184 int bw = bitmap.width();
180 int bh = bitmap.height(); 185 int bh = bitmap.height();
181 186
182 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh); 187 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh);
183 SkIRect clippedSrcRect = DEV_RECT; 188 SkIRect clippedSrcRect = DEV_RECT;
184 if (!clippedSrcRect.intersect(srcRect)) { 189 if (!clippedSrcRect.intersect(srcRect)) {
185 clippedSrcRect.setEmpty(); 190 clippedSrcRect.setEmpty();
186 } 191 }
187 SkAutoLockPixels alp(bitmap); 192 SkAutoLockPixels alp(bitmap);
193 if (kAlpha_8_SkColorType == ct) {
194 for (int by = 0; by < bh; ++by) {
195 for (int bx = 0; bx < bw; ++bx) {
196 int devx = bx + srcRect.fLeft;
197 int devy = by + srcRect.fTop;
198 const uint8_t* alpha = bitmap.getAddr8(bx, by);
199
200 if (clippedSrcRect.contains(devx, devy)) {
201 if (checkCanvasPixels) {
202 uint8_t canvasAlpha = SkGetPackedA32(get_src_color(devx, devy));
203 if (canvasAlpha != *alpha) {
204 ERRORF(reporter, "Expected readback alpha (%d, %d) v alue 0x%02x, got 0x%02x. ",
205 bx, by, canvasAlpha, *alpha);
206 return false;
207 }
208 }
209 } else if (checkBitmapPixels) {
210 uint32_t origDstAlpha = SkGetPackedA32(get_dst_bmp_init_colo r(bx, by, bw));
211 if (origDstAlpha != *alpha) {
212 ERRORF(reporter, "Expected clipped out area of readback to be unchanged. "
213 "Expected 0x%02x, got 0x%02x", origDstAlpha, *alpha) ;
214 return false;
215 }
216 }
217 }
218 }
219 return true;
220 }
188 for (int by = 0; by < bh; ++by) { 221 for (int by = 0; by < bh; ++by) {
189 for (int bx = 0; bx < bw; ++bx) { 222 for (int bx = 0; bx < bw; ++bx) {
190 int devx = bx + srcRect.fLeft; 223 int devx = bx + srcRect.fLeft;
191 int devy = by + srcRect.fTop; 224 int devy = by + srcRect.fTop;
192 225
193 const uint32_t* pixel = bitmap.getAddr32(bx, by); 226 const uint32_t* pixel = bitmap.getAddr32(bx, by);
194 227
195 if (clippedSrcRect.contains(devx, devy)) { 228 if (clippedSrcRect.contains(devx, devy)) {
196 if (checkCanvasPixels) { 229 if (checkCanvasPixels) {
197 SkPMColor canvasPixel = get_src_color(devx, devy); 230 SkPMColor canvasPixel = get_src_color(devx, devy);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 SkAlphaType at) { 275 SkAlphaType at) {
243 SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), ct, at); 276 SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), ct, at);
244 size_t rowBytes = 0; 277 size_t rowBytes = 0;
245 bool alloc = true; 278 bool alloc = true;
246 switch (init) { 279 switch (init) {
247 case kNoPixels_BitmapInit: 280 case kNoPixels_BitmapInit:
248 alloc = false; 281 alloc = false;
249 case kTight_BitmapInit: 282 case kTight_BitmapInit:
250 break; 283 break;
251 case kRowBytes_BitmapInit: 284 case kRowBytes_BitmapInit:
252 rowBytes = (info.width() + 16) * sizeof(SkPMColor); 285 rowBytes = SkAlign4((info.width() + 16) * info.bytesPerPixel());
253 break; 286 break;
254 case kRowBytesOdd_BitmapInit: 287 case kRowBytesOdd_BitmapInit:
255 rowBytes = (info.width() * sizeof(SkPMColor)) + 3; 288 rowBytes = SkAlign4(info.width() * info.bytesPerPixel()) + 3;
256 break; 289 break;
257 default: 290 default:
258 SkASSERT(0); 291 SkASSERT(0);
259 break; 292 break;
260 } 293 }
261 294
262 if (alloc) { 295 if (alloc) {
263 bitmap->allocPixels(info, rowBytes); 296 bitmap->allocPixels(info, rowBytes);
264 } else { 297 } else {
265 bitmap->setInfo(info, rowBytes); 298 bitmap->setInfo(info, rowBytes);
266 } 299 }
267 } 300 }
268 301
269 static const struct { 302 static const struct {
270 SkColorType fColorType; 303 SkColorType fColorType;
271 SkAlphaType fAlphaType; 304 SkAlphaType fAlphaType;
272 } gReadPixelsConfigs[] = { 305 } gReadPixelsConfigs[] = {
273 { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, 306 { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
274 { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType }, 307 { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
275 { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, 308 { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
276 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, 309 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
310 { kAlpha_8_SkColorType, kPremul_SkAlphaType },
277 }; 311 };
278 const SkIRect gReadPixelsTestRects[] = { 312 const SkIRect gReadPixelsTestRects[] = {
279 // entire thing 313 // entire thing
280 DEV_RECT, 314 DEV_RECT,
281 // larger on all sides 315 // larger on all sides
282 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10), 316 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10),
283 // fully contained 317 // fully contained
284 SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4), 318 SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4),
285 // outside top left 319 // outside top left
286 SkIRect::MakeLTRB(-10, -10, -1, -1), 320 SkIRect::MakeLTRB(-10, -10, -1, -1),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 // we expect to succeed when the read isn't fully clipped 381 // we expect to succeed when the read isn't fully clipped
348 // out. 382 // out.
349 bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RECT); 383 bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RECT);
350 // determine whether we expected the read to succeed. 384 // determine whether we expected the read to succeed.
351 REPORTER_ASSERT(reporter, success == expectSuccess); 385 REPORTER_ASSERT(reporter, success == expectSuccess);
352 // read pixels should never change the gen id 386 // read pixels should never change the gen id
353 REPORTER_ASSERT(reporter, idBefore == idAfter); 387 REPORTER_ASSERT(reporter, idBefore == idAfter);
354 388
355 if (success || startsWithPixels) { 389 if (success || startsWithPixels) {
356 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop, 390 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
357 success, startsWithPixels); 391 success, startsWithPixels,
392 gReadPixelsConfigs[c].fColorType, gReadPixelsConf igs[c].fAlphaType);
358 } else { 393 } else {
359 // if we had no pixels beforehand and the readPixels 394 // if we had no pixels beforehand and the readPixels
360 // failed then our bitmap should still not have pixels 395 // failed then our bitmap should still not have pixels
361 REPORTER_ASSERT(reporter, bmp.isNull()); 396 REPORTER_ASSERT(reporter, bmp.isNull());
362 } 397 }
363 } 398 }
364 // check the old webkit version of readPixels that clips the 399 // check the old webkit version of readPixels that clips the
365 // bitmap size 400 // bitmap size
366 SkBitmap wkbmp; 401 SkBitmap wkbmp;
367 bool success = canvas->readPixels(srcRect, &wkbmp); 402 bool success = canvas->readPixels(srcRect, &wkbmp);
368 SkIRect clippedRect = DEV_RECT; 403 SkIRect clippedRect = DEV_RECT;
369 if (clippedRect.intersect(srcRect)) { 404 if (clippedRect.intersect(srcRect)) {
370 REPORTER_ASSERT(reporter, success); 405 REPORTER_ASSERT(reporter, success);
371 REPORTER_ASSERT(reporter, kN32_SkColorType == wkbmp.colorType()) ; 406 REPORTER_ASSERT(reporter, kN32_SkColorType == wkbmp.colorType()) ;
372 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == wkbmp.alphaType ()); 407 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == wkbmp.alphaType ());
373 check_read(reporter, wkbmp, clippedRect.fLeft, 408 check_read(reporter, wkbmp, clippedRect.fLeft,
374 clippedRect.fTop, true, false); 409 clippedRect.fTop, true, false,
410 kN32_SkColorType, kPremul_SkAlphaType);
375 } else { 411 } else {
376 REPORTER_ASSERT(reporter, !success); 412 REPORTER_ASSERT(reporter, !success);
377 } 413 }
378 } 414 }
379 } 415 }
380 } 416 }
381 DEF_TEST(ReadPixels, reporter) { 417 DEF_TEST(ReadPixels, reporter) {
382 const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); 418 const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
383 auto surface(SkSurface::MakeRaster(info)); 419 auto surface(SkSurface::MakeRaster(info));
384 // SW readback fails a premul check when reading back to an unaligned rowbyt es. 420 // SW readback fails a premul check when reading back to an unaligned rowbyt es.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 uint32_t flags = 0; 456 uint32_t flags = 0;
421 if (gReadPixelsConfigs[c].fAlphaType == kUnpremul_SkAlphaTyp e) { 457 if (gReadPixelsConfigs[c].fAlphaType == kUnpremul_SkAlphaTyp e) {
422 flags = GrContext::kUnpremul_PixelOpsFlag; 458 flags = GrContext::kUnpremul_PixelOpsFlag;
423 } 459 }
424 bmp.lockPixels(); 460 bmp.lockPixels();
425 bool success = texture->readPixels(srcRect.fLeft, srcRect.fT op, bmp.width(), 461 bool success = texture->readPixels(srcRect.fLeft, srcRect.fT op, bmp.width(),
426 bmp.height(), dstConfig, bmp.getPixels(), 462 bmp.height(), dstConfig, bmp.getPixels(),
427 bmp.rowBytes(), flags); 463 bmp.rowBytes(), flags);
428 bmp.unlockPixels(); 464 bmp.unlockPixels();
429 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop, 465 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop,
430 success, true); 466 success, true,
467 gReadPixelsConfigs[c].fColorType, gReadPixelsConf igs[c].fAlphaType);
431 } 468 }
432 } 469 }
433 } 470 }
434 } 471 }
435 } 472 }
436 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Texture, reporter, ctxInfo) { 473 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Texture, reporter, ctxInfo) {
437 // On the GPU we will also try reading back from a non-renderable texture. 474 // On the GPU we will also try reading back from a non-renderable texture.
438 for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) { 475 for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
439 SkAutoTUnref<GrTexture> texture; 476 SkAutoTUnref<GrTexture> texture;
440 GrSurfaceDesc desc; 477 GrSurfaceDesc desc;
441 desc.fFlags = kRenderTarget_GrSurfaceFlag; 478 desc.fFlags = kRenderTarget_GrSurfaceFlag;
442 desc.fWidth = DEV_W; 479 desc.fWidth = DEV_W;
443 desc.fHeight = DEV_H; 480 desc.fHeight = DEV_H;
444 desc.fConfig = kSkia8888_GrPixelConfig; 481 desc.fConfig = kSkia8888_GrPixelConfig;
445 desc.fOrigin = origin; 482 desc.fOrigin = origin;
446 desc.fFlags = kNone_GrSurfaceFlags; 483 desc.fFlags = kNone_GrSurfaceFlags;
447 texture.reset(ctxInfo.grContext()->textureProvider()->createTexture(desc , 484 texture.reset(ctxInfo.grContext()->textureProvider()->createTexture(desc ,
448 SkBu dgeted::kNo)); 485 SkBu dgeted::kNo));
449 test_readpixels_texture(reporter, texture); 486 test_readpixels_texture(reporter, texture);
450 } 487 }
451 } 488 }
452 #endif 489 #endif
OLDNEW
« no previous file with comments | « src/core/SkConfig8888.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698