OLD | NEW |
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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 } | 217 } |
218 return true; | 218 return true; |
219 } | 219 } |
220 | 220 |
221 enum BitmapInit { | 221 enum BitmapInit { |
222 kFirstBitmapInit = 0, | 222 kFirstBitmapInit = 0, |
223 | 223 |
224 kNoPixels_BitmapInit = kFirstBitmapInit, | 224 kNoPixels_BitmapInit = kFirstBitmapInit, |
225 kTight_BitmapInit, | 225 kTight_BitmapInit, |
226 kRowBytes_BitmapInit, | 226 kRowBytes_BitmapInit, |
| 227 kRowBytesOdd_BitmapInit, |
227 | 228 |
228 kBitmapInitCnt | 229 kLastAligned_BitmapInit = kRowBytes_BitmapInit, |
| 230 kLast_BitmapInit = kRowBytesOdd_BitmapInit |
229 }; | 231 }; |
230 | 232 |
231 static BitmapInit nextBMI(BitmapInit bmi) { | 233 static BitmapInit nextBMI(BitmapInit bmi) { |
232 int x = bmi; | 234 int x = bmi; |
233 return static_cast<BitmapInit>(++x); | 235 return static_cast<BitmapInit>(++x); |
234 } | 236 } |
235 | 237 |
236 static void init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init,
SkColorType ct, | 238 static void init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init,
SkColorType ct, |
237 SkAlphaType at) { | 239 SkAlphaType at) { |
238 SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), ct, at); | 240 SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), ct, at); |
239 size_t rowBytes = 0; | 241 size_t rowBytes = 0; |
240 bool alloc = true; | 242 bool alloc = true; |
241 switch (init) { | 243 switch (init) { |
242 case kNoPixels_BitmapInit: | 244 case kNoPixels_BitmapInit: |
243 alloc = false; | 245 alloc = false; |
244 case kTight_BitmapInit: | 246 case kTight_BitmapInit: |
245 break; | 247 break; |
246 case kRowBytes_BitmapInit: | 248 case kRowBytes_BitmapInit: |
247 rowBytes = (info.width() + 16) * sizeof(SkPMColor); | 249 rowBytes = (info.width() + 16) * sizeof(SkPMColor); |
248 break; | 250 break; |
| 251 case kRowBytesOdd_BitmapInit: |
| 252 rowBytes = (info.width() * sizeof(SkPMColor)) + 3; |
| 253 break; |
249 default: | 254 default: |
250 SkASSERT(0); | 255 SkASSERT(0); |
251 break; | 256 break; |
252 } | 257 } |
253 | 258 |
254 if (alloc) { | 259 if (alloc) { |
255 bitmap->allocPixels(info); | 260 bitmap->allocPixels(info, rowBytes); |
256 } else { | 261 } else { |
257 bitmap->setInfo(info, rowBytes); | 262 bitmap->setInfo(info, rowBytes); |
258 } | 263 } |
259 } | 264 } |
260 | 265 |
261 static const struct { | 266 static const struct { |
262 SkColorType fColorType; | 267 SkColorType fColorType; |
263 SkAlphaType fAlphaType; | 268 SkAlphaType fAlphaType; |
264 } gReadPixelsConfigs[] = { | 269 } gReadPixelsConfigs[] = { |
265 { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, | 270 { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 // overlapping bottom left and bottom right corners | 312 // overlapping bottom left and bottom right corners |
308 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), | 313 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), |
309 // touching entire left edge | 314 // touching entire left edge |
310 SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10), | 315 SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10), |
311 // overlapping bottom right corner | 316 // overlapping bottom right corner |
312 SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), | 317 SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), |
313 // overlapping top right and bottom right corners | 318 // overlapping top right and bottom right corners |
314 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10), | 319 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10), |
315 }; | 320 }; |
316 | 321 |
317 static void test_readpixels(skiatest::Reporter* reporter, SkSurface* surface) { | 322 static void test_readpixels(skiatest::Reporter* reporter, SkSurface* surface, |
| 323 BitmapInit lastBitmapInit) { |
318 SkCanvas* canvas = surface->getCanvas(); | 324 SkCanvas* canvas = surface->getCanvas(); |
319 fill_src_canvas(canvas); | 325 fill_src_canvas(canvas); |
320 for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) { | 326 for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) { |
321 const SkIRect& srcRect = gReadPixelsTestRects[rect]; | 327 const SkIRect& srcRect = gReadPixelsTestRects[rect]; |
322 for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = next
BMI(bmi)) { | 328 for (BitmapInit bmi = kFirstBitmapInit; bmi <= lastBitmapInit; bmi = nex
tBMI(bmi)) { |
323 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) { | 329 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) { |
324 SkBitmap bmp; | 330 SkBitmap bmp; |
325 init_bitmap(&bmp, srcRect, bmi, | 331 init_bitmap(&bmp, srcRect, bmi, |
326 gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs
[c].fAlphaType); | 332 gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs
[c].fAlphaType); |
327 | 333 |
328 // if the bitmap has pixels allocated before the readPixels, | 334 // if the bitmap has pixels allocated before the readPixels, |
329 // note that and fill them with pattern | 335 // note that and fill them with pattern |
330 bool startsWithPixels = !bmp.isNull(); | 336 bool startsWithPixels = !bmp.isNull(); |
331 if (startsWithPixels) { | 337 if (startsWithPixels) { |
332 fill_dst_bmp_with_init_data(&bmp); | 338 fill_dst_bmp_with_init_data(&bmp); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 clippedRect.fTop, true, false); | 371 clippedRect.fTop, true, false); |
366 } else { | 372 } else { |
367 REPORTER_ASSERT(reporter, !success); | 373 REPORTER_ASSERT(reporter, !success); |
368 } | 374 } |
369 } | 375 } |
370 } | 376 } |
371 } | 377 } |
372 DEF_TEST(ReadPixels, reporter) { | 378 DEF_TEST(ReadPixels, reporter) { |
373 const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); | 379 const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); |
374 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info)); | 380 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info)); |
375 test_readpixels(reporter, surface); | 381 // SW readback fails a premul check when reading back to an unaligned rowbyt
es. |
| 382 test_readpixels(reporter, surface, kLastAligned_BitmapInit); |
376 } | 383 } |
377 #if SK_SUPPORT_GPU | 384 #if SK_SUPPORT_GPU |
378 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Gpu, reporter, context) { | 385 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Gpu, reporter, context) { |
379 for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin})
{ | 386 for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin})
{ |
380 GrSurfaceDesc desc; | 387 GrSurfaceDesc desc; |
381 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 388 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
382 desc.fWidth = DEV_W; | 389 desc.fWidth = DEV_W; |
383 desc.fHeight = DEV_H; | 390 desc.fHeight = DEV_H; |
384 desc.fConfig = kSkia8888_GrPixelConfig; | 391 desc.fConfig = kSkia8888_GrPixelConfig; |
385 desc.fOrigin = origin; | 392 desc.fOrigin = origin; |
386 SkAutoTUnref<GrTexture> surfaceTexture( | 393 SkAutoTUnref<GrTexture> surfaceTexture( |
387 context->textureProvider()->createTexture(desc, false)); | 394 context->textureProvider()->createTexture(desc, false)); |
388 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(surface
Texture->asRenderTarget())); | 395 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(surface
Texture->asRenderTarget())); |
389 desc.fFlags = kNone_GrSurfaceFlags; | 396 desc.fFlags = kNone_GrSurfaceFlags; |
390 test_readpixels(reporter, surface); | 397 test_readpixels(reporter, surface, kLast_BitmapInit); |
391 } | 398 } |
392 } | 399 } |
393 #endif | 400 #endif |
394 | 401 |
395 #if SK_SUPPORT_GPU | 402 #if SK_SUPPORT_GPU |
396 static void test_readpixels_texture(skiatest::Reporter* reporter, GrTexture* tex
ture) { | 403 static void test_readpixels_texture(skiatest::Reporter* reporter, GrTexture* tex
ture) { |
397 fill_src_texture(texture); | 404 fill_src_texture(texture); |
398 for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) { | 405 for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) { |
399 const SkIRect& srcRect = gReadPixelsTestRects[rect]; | 406 const SkIRect& srcRect = gReadPixelsTestRects[rect]; |
400 for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = next
BMI(bmi)) { | 407 for (BitmapInit bmi = kFirstBitmapInit; bmi <= kLast_BitmapInit; bmi = n
extBMI(bmi)) { |
401 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) { | 408 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) { |
402 SkBitmap bmp; | 409 SkBitmap bmp; |
403 init_bitmap(&bmp, srcRect, bmi, | 410 init_bitmap(&bmp, srcRect, bmi, |
404 gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs
[c].fAlphaType); | 411 gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs
[c].fAlphaType); |
405 | 412 |
406 // if the bitmap has pixels allocated before the readPixels, | 413 // if the bitmap has pixels allocated before the readPixels, |
407 // note that and fill them with pattern | 414 // note that and fill them with pattern |
408 bool startsWithPixels = !bmp.isNull(); | 415 bool startsWithPixels = !bmp.isNull(); |
409 // Try doing the read directly from a non-renderable texture | 416 // Try doing the read directly from a non-renderable texture |
410 if (startsWithPixels) { | 417 if (startsWithPixels) { |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 SkAutoTUnref<SkData> dataB(draw_into_surface(surfB, tx_subset, quality))
; | 612 SkAutoTUnref<SkData> dataB(draw_into_surface(surfB, tx_subset, quality))
; |
606 | 613 |
607 REPORTER_ASSERT(reporter, dataA->equals(dataB)); | 614 REPORTER_ASSERT(reporter, dataA->equals(dataB)); |
608 if (false) { | 615 if (false) { |
609 dump_to_file("test_image_A.png", dataA); | 616 dump_to_file("test_image_A.png", dataA); |
610 dump_to_file("test_image_B.png", dataB); | 617 dump_to_file("test_image_B.png", dataB); |
611 } | 618 } |
612 } | 619 } |
613 } | 620 } |
614 #endif | 621 #endif |
OLD | NEW |