| 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 |