| 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" |
| 11 #include "SkRegion.h" | 11 #include "SkRegion.h" |
| 12 #include "SkSurface.h" | 12 #include "SkSurface.h" |
| 13 #include "Test.h" | 13 #include "Test.h" |
| 14 | 14 |
| 15 #if SK_SUPPORT_GPU | 15 #if SK_SUPPORT_GPU |
| 16 #include "GrContextFactory.h" | 16 #include "GrContext.h" |
| 17 #include "SkGpuDevice.h" | |
| 18 #include "SkGr.h" | 17 #include "SkGr.h" |
| 19 #endif | 18 #endif |
| 20 | 19 |
| 20 #include <initializer_list> |
| 21 |
| 21 static const int DEV_W = 100, DEV_H = 100; | 22 static const int DEV_W = 100, DEV_H = 100; |
| 22 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H); | 23 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H); |
| 23 static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1, | 24 static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1, |
| 24 DEV_H * SK_Scalar1); | 25 DEV_H * SK_Scalar1); |
| 25 | 26 |
| 26 static SkPMColor get_src_color(int x, int y) { | 27 static SkPMColor get_src_color(int x, int y) { |
| 27 SkASSERT(x >= 0 && x < DEV_W); | 28 SkASSERT(x >= 0 && x < DEV_W); |
| 28 SkASSERT(y >= 0 && y < DEV_H); | 29 SkASSERT(y >= 0 && y < DEV_H); |
| 29 | 30 |
| 30 U8CPU r = x; | 31 U8CPU r = x; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 break; | 251 break; |
| 251 } | 252 } |
| 252 | 253 |
| 253 if (alloc) { | 254 if (alloc) { |
| 254 bitmap->allocPixels(info); | 255 bitmap->allocPixels(info); |
| 255 } else { | 256 } else { |
| 256 bitmap->setInfo(info, rowBytes); | 257 bitmap->setInfo(info, rowBytes); |
| 257 } | 258 } |
| 258 } | 259 } |
| 259 | 260 |
| 260 DEF_GPUTEST(ReadPixels, reporter, factory) { | 261 static const struct { |
| 261 const SkIRect testRects[] = { | 262 SkColorType fColorType; |
| 262 // entire thing | 263 SkAlphaType fAlphaType; |
| 263 DEV_RECT, | 264 } gReadPixelsConfigs[] = { |
| 264 // larger on all sides | 265 { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, |
| 265 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10), | 266 { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType }, |
| 266 // fully contained | 267 { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, |
| 267 SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4), | 268 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, |
| 268 // outside top left | 269 }; |
| 269 SkIRect::MakeLTRB(-10, -10, -1, -1), | 270 const SkIRect gReadPixelsTestRects[] = { |
| 270 // touching top left corner | 271 // entire thing |
| 271 SkIRect::MakeLTRB(-10, -10, 0, 0), | 272 DEV_RECT, |
| 272 // overlapping top left corner | 273 // larger on all sides |
| 273 SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4), | 274 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10), |
| 274 // overlapping top left and top right corners | 275 // fully contained |
| 275 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H / 4), | 276 SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4), |
| 276 // touching entire top edge | 277 // outside top left |
| 277 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, 0), | 278 SkIRect::MakeLTRB(-10, -10, -1, -1), |
| 278 // overlapping top right corner | 279 // touching top left corner |
| 279 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H / 4), | 280 SkIRect::MakeLTRB(-10, -10, 0, 0), |
| 280 // contained in x, overlapping top edge | 281 // overlapping top left corner |
| 281 SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W / 4, DEV_H / 4), | 282 SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4), |
| 282 // outside top right corner | 283 // overlapping top left and top right corners |
| 283 SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1), | 284 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H / 4), |
| 284 // touching top right corner | 285 // touching entire top edge |
| 285 SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0), | 286 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, 0), |
| 286 // overlapping top left and bottom left corners | 287 // overlapping top right corner |
| 287 SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10), | 288 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H / 4), |
| 288 // touching entire left edge | 289 // contained in x, overlapping top edge |
| 289 SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10), | 290 SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W / 4, DEV_H / 4), |
| 290 // overlapping bottom left corner | 291 // outside top right corner |
| 291 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10), | 292 SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1), |
| 292 // contained in y, overlapping left edge | 293 // touching top right corner |
| 293 SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4), | 294 SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0), |
| 294 // outside bottom left corner | 295 // overlapping top left and bottom left corners |
| 295 SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10), | 296 SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10), |
| 296 // touching bottom left corner | 297 // touching entire left edge |
| 297 SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10), | 298 SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10), |
| 298 // overlapping bottom left and bottom right corners | 299 // overlapping bottom left corner |
| 299 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), | 300 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10), |
| 300 // touching entire left edge | 301 // contained in y, overlapping left edge |
| 301 SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10), | 302 SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4), |
| 302 // overlapping bottom right corner | 303 // outside bottom left corner |
| 303 SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), | 304 SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10), |
| 304 // overlapping top right and bottom right corners | 305 // touching bottom left corner |
| 305 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10), | 306 SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10), |
| 306 }; | 307 // overlapping bottom left and bottom right corners |
| 308 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), |
| 309 // touching entire left edge |
| 310 SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10), |
| 311 // overlapping bottom right corner |
| 312 SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), |
| 313 // overlapping top right and bottom right corners |
| 314 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10), |
| 315 }; |
| 307 | 316 |
| 308 for (int dtype = 0; dtype < 3; ++dtype) { | 317 static void test_readpixels(skiatest::Reporter* reporter, SkSurface* surface) { |
| 309 int glCtxTypeCnt = 1; | 318 SkCanvas* canvas = surface->getCanvas(); |
| 319 fill_src_canvas(canvas); |
| 320 for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) { |
| 321 const SkIRect& srcRect = gReadPixelsTestRects[rect]; |
| 322 for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = next
BMI(bmi)) { |
| 323 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) { |
| 324 SkBitmap bmp; |
| 325 init_bitmap(&bmp, srcRect, bmi, |
| 326 gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs
[c].fAlphaType); |
| 327 |
| 328 // if the bitmap has pixels allocated before the readPixels, |
| 329 // note that and fill them with pattern |
| 330 bool startsWithPixels = !bmp.isNull(); |
| 331 if (startsWithPixels) { |
| 332 fill_dst_bmp_with_init_data(&bmp); |
| 333 } |
| 334 uint32_t idBefore = surface->generationID(); |
| 335 bool success = canvas->readPixels(&bmp, srcRect.fLeft, srcRect.f
Top); |
| 336 uint32_t idAfter = surface->generationID(); |
| 337 |
| 338 // we expect to succeed when the read isn't fully clipped |
| 339 // out. |
| 340 bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RECT); |
| 341 // determine whether we expected the read to succeed. |
| 342 REPORTER_ASSERT(reporter, success == expectSuccess); |
| 343 // read pixels should never change the gen id |
| 344 REPORTER_ASSERT(reporter, idBefore == idAfter); |
| 345 |
| 346 if (success || startsWithPixels) { |
| 347 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop, |
| 348 success, startsWithPixels); |
| 349 } else { |
| 350 // if we had no pixels beforehand and the readPixels |
| 351 // failed then our bitmap should still not have pixels |
| 352 REPORTER_ASSERT(reporter, bmp.isNull()); |
| 353 } |
| 354 } |
| 355 // check the old webkit version of readPixels that clips the |
| 356 // bitmap size |
| 357 SkBitmap wkbmp; |
| 358 bool success = canvas->readPixels(srcRect, &wkbmp); |
| 359 SkIRect clippedRect = DEV_RECT; |
| 360 if (clippedRect.intersect(srcRect)) { |
| 361 REPORTER_ASSERT(reporter, success); |
| 362 REPORTER_ASSERT(reporter, kN32_SkColorType == wkbmp.colorType())
; |
| 363 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == wkbmp.alphaType
()); |
| 364 check_read(reporter, wkbmp, clippedRect.fLeft, |
| 365 clippedRect.fTop, true, false); |
| 366 } else { |
| 367 REPORTER_ASSERT(reporter, !success); |
| 368 } |
| 369 } |
| 370 } |
| 371 } |
| 372 DEF_TEST(ReadPixels, reporter) { |
| 373 const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); |
| 374 SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info)); |
| 375 test_readpixels(reporter, surface); |
| 376 } |
| 310 #if SK_SUPPORT_GPU | 377 #if SK_SUPPORT_GPU |
| 311 // On the GPU we will also try reading back from a non-renderable textur
e. | 378 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Gpu, reporter, context) { |
| 312 SkAutoTUnref<GrTexture> texture; | 379 for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin})
{ |
| 313 | 380 GrSurfaceDesc desc; |
| 314 if (0 != dtype) { | 381 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 315 glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt; | 382 desc.fWidth = DEV_W; |
| 316 } | 383 desc.fHeight = DEV_H; |
| 384 desc.fConfig = kSkia8888_GrPixelConfig; |
| 385 desc.fOrigin = origin; |
| 386 SkAutoTUnref<GrTexture> surfaceTexture( |
| 387 context->textureProvider()->createTexture(desc, false)); |
| 388 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(surface
Texture->asRenderTarget())); |
| 389 desc.fFlags = kNone_GrSurfaceFlags; |
| 390 test_readpixels(reporter, surface); |
| 391 } |
| 392 } |
| 317 #endif | 393 #endif |
| 318 const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); | |
| 319 for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) { | |
| 320 SkAutoTUnref<SkSurface> surface; | |
| 321 if (0 == dtype) { | |
| 322 surface.reset(SkSurface::NewRaster(info)); | |
| 323 } else { | |
| 324 #if SK_SUPPORT_GPU | |
| 325 GrContextFactory::GLContextType type = | |
| 326 static_cast<GrContextFactory::GLContextType>(glCtxType); | |
| 327 if (!GrContextFactory::IsRenderingGLContext(type)) { | |
| 328 continue; | |
| 329 } | |
| 330 GrContext* context = factory->get(type); | |
| 331 if (nullptr == context) { | |
| 332 continue; | |
| 333 } | |
| 334 GrSurfaceDesc desc; | |
| 335 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
| 336 desc.fWidth = DEV_W; | |
| 337 desc.fHeight = DEV_H; | |
| 338 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 339 desc.fOrigin = 1 == dtype ? kBottomLeft_GrSurfaceOrigin : kTopLe
ft_GrSurfaceOrigin; | |
| 340 SkAutoTUnref<GrTexture> surfaceTexture( | |
| 341 context->textureProvider()->createTexture(desc, false)); | |
| 342 surface.reset(SkSurface::NewRenderTargetDirect(surfaceTexture->a
sRenderTarget())); | |
| 343 desc.fFlags = kNone_GrSurfaceFlags; | |
| 344 | |
| 345 texture.reset(context->textureProvider()->createTexture(desc, fa
lse)); | |
| 346 #else | |
| 347 continue; | |
| 348 #endif | |
| 349 } | |
| 350 SkCanvas& canvas = *surface->getCanvas(); | |
| 351 fill_src_canvas(&canvas); | |
| 352 | 394 |
| 353 #if SK_SUPPORT_GPU | 395 #if SK_SUPPORT_GPU |
| 354 if (texture) { | 396 static void test_readpixels_texture(skiatest::Reporter* reporter, GrTexture* tex
ture) { |
| 355 fill_src_texture(texture); | 397 fill_src_texture(texture); |
| 356 } | 398 for (size_t rect = 0; rect < SK_ARRAY_COUNT(gReadPixelsTestRects); ++rect) { |
| 357 #endif | 399 const SkIRect& srcRect = gReadPixelsTestRects[rect]; |
| 400 for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = next
BMI(bmi)) { |
| 401 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadPixelsConfigs); ++c) { |
| 402 SkBitmap bmp; |
| 403 init_bitmap(&bmp, srcRect, bmi, |
| 404 gReadPixelsConfigs[c].fColorType, gReadPixelsConfigs
[c].fAlphaType); |
| 358 | 405 |
| 359 static const struct { | 406 // if the bitmap has pixels allocated before the readPixels, |
| 360 SkColorType fColorType; | 407 // note that and fill them with pattern |
| 361 SkAlphaType fAlphaType; | 408 bool startsWithPixels = !bmp.isNull(); |
| 362 } gReadConfigs[] = { | 409 // Try doing the read directly from a non-renderable texture |
| 363 { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, | 410 if (startsWithPixels) { |
| 364 { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType }, | 411 fill_dst_bmp_with_init_data(&bmp); |
| 365 { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, | 412 GrPixelConfig dstConfig = |
| 366 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, | 413 SkImageInfo2GrPixelConfig(gReadPixelsConfigs[c].fCol
orType, |
| 367 }; | 414 gReadPixelsConfigs[c].fAlp
haType, |
| 368 for (size_t rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) { | 415 kLinear_SkColorProfileType
); |
| 369 const SkIRect& srcRect = testRects[rect]; | 416 uint32_t flags = 0; |
| 370 for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bm
i = nextBMI(bmi)) { | 417 if (gReadPixelsConfigs[c].fAlphaType == kUnpremul_SkAlphaTyp
e) { |
| 371 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadConfigs); ++c) { | 418 flags = GrContext::kUnpremul_PixelOpsFlag; |
| 372 SkBitmap bmp; | |
| 373 init_bitmap(&bmp, srcRect, bmi, | |
| 374 gReadConfigs[c].fColorType, gReadConfigs[c].
fAlphaType); | |
| 375 | |
| 376 // if the bitmap has pixels allocated before the readPix
els, | |
| 377 // note that and fill them with pattern | |
| 378 bool startsWithPixels = !bmp.isNull(); | |
| 379 if (startsWithPixels) { | |
| 380 fill_dst_bmp_with_init_data(&bmp); | |
| 381 } | |
| 382 uint32_t idBefore = surface->generationID(); | |
| 383 bool success = canvas.readPixels(&bmp, srcRect.fLeft, sr
cRect.fTop); | |
| 384 uint32_t idAfter = surface->generationID(); | |
| 385 | |
| 386 // we expect to succeed when the read isn't fully clippe
d | |
| 387 // out. | |
| 388 bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RE
CT); | |
| 389 // determine whether we expected the read to succeed. | |
| 390 REPORTER_ASSERT(reporter, success == expectSuccess); | |
| 391 // read pixels should never change the gen id | |
| 392 REPORTER_ASSERT(reporter, idBefore == idAfter); | |
| 393 | |
| 394 if (success || startsWithPixels) { | |
| 395 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTo
p, | |
| 396 success, startsWithPixels); | |
| 397 } else { | |
| 398 // if we had no pixels beforehand and the readPixels | |
| 399 // failed then our bitmap should still not have pixe
ls | |
| 400 REPORTER_ASSERT(reporter, bmp.isNull()); | |
| 401 } | |
| 402 #if SK_SUPPORT_GPU | |
| 403 // Try doing the read directly from a non-renderable tex
ture | |
| 404 if (texture && startsWithPixels) { | |
| 405 fill_dst_bmp_with_init_data(&bmp); | |
| 406 GrPixelConfig dstConfig = | |
| 407 SkImageInfo2GrPixelConfig(gReadConfigs[c].fColor
Type, | |
| 408 gReadConfigs[c].fAlpha
Type, | |
| 409 kLinear_SkColorProfile
Type); | |
| 410 uint32_t flags = 0; | |
| 411 if (gReadConfigs[c].fAlphaType == kUnpremul_SkAlphaT
ype) { | |
| 412 flags = GrContext::kUnpremul_PixelOpsFlag; | |
| 413 } | |
| 414 bmp.lockPixels(); | |
| 415 success = texture->readPixels(srcRect.fLeft, srcRect
.fTop, bmp.width(), | |
| 416 bmp.height(), dstConfig, bmp.get
Pixels(), | |
| 417 bmp.rowBytes(), flags); | |
| 418 bmp.unlockPixels(); | |
| 419 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTo
p, | |
| 420 success, true); | |
| 421 } | |
| 422 #endif | |
| 423 } | 419 } |
| 424 // check the old webkit version of readPixels that clips the | 420 bmp.lockPixels(); |
| 425 // bitmap size | 421 bool success = texture->readPixels(srcRect.fLeft, srcRect.fT
op, bmp.width(), |
| 426 SkBitmap wkbmp; | 422 bmp.height(), dstConfig,
bmp.getPixels(), |
| 427 bool success = canvas.readPixels(srcRect, &wkbmp); | 423 bmp.rowBytes(), flags); |
| 428 SkIRect clippedRect = DEV_RECT; | 424 bmp.unlockPixels(); |
| 429 if (clippedRect.intersect(srcRect)) { | 425 check_read(reporter, bmp, srcRect.fLeft, srcRect.fTop, |
| 430 REPORTER_ASSERT(reporter, success); | 426 success, true); |
| 431 REPORTER_ASSERT(reporter, kN32_SkColorType == wkbmp.colo
rType()); | |
| 432 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == wkbmp.a
lphaType()); | |
| 433 check_read(reporter, wkbmp, clippedRect.fLeft, | |
| 434 clippedRect.fTop, true, false); | |
| 435 } else { | |
| 436 REPORTER_ASSERT(reporter, !success); | |
| 437 } | |
| 438 } | 427 } |
| 439 } | 428 } |
| 440 } | 429 } |
| 441 } | 430 } |
| 442 } | 431 } |
| 443 | 432 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadPixels_Texture, reporter, context) { |
| 433 // On the GPU we will also try reading back from a non-renderable texture. |
| 434 for (auto& origin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin})
{ |
| 435 SkAutoTUnref<GrTexture> texture; |
| 436 GrSurfaceDesc desc; |
| 437 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 438 desc.fWidth = DEV_W; |
| 439 desc.fHeight = DEV_H; |
| 440 desc.fConfig = kSkia8888_GrPixelConfig; |
| 441 desc.fOrigin = origin; |
| 442 desc.fFlags = kNone_GrSurfaceFlags; |
| 443 texture.reset(context->textureProvider()->createTexture(desc, false)); |
| 444 test_readpixels_texture(reporter, texture); |
| 445 } |
| 446 } |
| 447 #endif |
| 444 ///////////////////// | 448 ///////////////////// |
| 445 #if SK_SUPPORT_GPU | 449 #if SK_SUPPORT_GPU |
| 446 | 450 |
| 447 // make_ringed_bitmap was lifted from gm/bleed.cpp, as that GM was what showed t
he following | 451 // make_ringed_bitmap was lifted from gm/bleed.cpp, as that GM was what showed t
he following |
| 448 // bug when a change was made to SkImage_Raster.cpp. It is possible that other t
est bitmaps | 452 // bug when a change was made to SkImage_Raster.cpp. It is possible that other t
est bitmaps |
| 449 // would also tickle https://bug.skia.org/4351 but this one is know to do it, so
I've pasted the code | 453 // would also tickle https://bug.skia.org/4351 but this one is know to do it, so
I've pasted the code |
| 450 // here so we have a dependable repro case. | 454 // here so we have a dependable repro case. |
| 451 | 455 |
| 452 // Create a black&white checked texture with 2 1-pixel rings | 456 // Create a black&white checked texture with 2 1-pixel rings |
| 453 // around the outside edge. The inner ring is red and the outer ring is blue. | 457 // around the outside edge. The inner ring is red and the outer ring is blue. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 /* | 557 /* |
| 554 * Test two different ways to turn a subset of a bitmap into a texture | 558 * Test two different ways to turn a subset of a bitmap into a texture |
| 555 * - subset and then upload to a texture | 559 * - subset and then upload to a texture |
| 556 * - upload to a texture and then subset | 560 * - upload to a texture and then subset |
| 557 * | 561 * |
| 558 * These two techniques result in the same pixels (ala readPixels) | 562 * These two techniques result in the same pixels (ala readPixels) |
| 559 * but when we draw them (rotated+scaled) we don't always get the same results. | 563 * but when we draw them (rotated+scaled) we don't always get the same results. |
| 560 * | 564 * |
| 561 * https://bug.skia.org/4351 | 565 * https://bug.skia.org/4351 |
| 562 */ | 566 */ |
| 563 DEF_GPUTEST(ReadPixels_Subset_Gpu, reporter, factory) { | 567 DEF_GPUTEST_FOR_NATIVE_CONTEXT(ReadPixels_Subset_Gpu, reporter, context) { |
| 564 GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType); | |
| 565 if (!ctx) { | |
| 566 REPORTER_ASSERT(reporter, false); | |
| 567 return; | |
| 568 } | |
| 569 | |
| 570 SkBitmap bitmap; | 568 SkBitmap bitmap; |
| 571 make_ringed_bitmap(&bitmap, 6, 6); | 569 make_ringed_bitmap(&bitmap, 6, 6); |
| 572 const SkIRect subset = SkIRect::MakeLTRB(2, 2, 4, 4); | 570 const SkIRect subset = SkIRect::MakeLTRB(2, 2, 4, 4); |
| 573 | 571 |
| 574 // make two textures... | 572 // make two textures... |
| 575 SkBitmap bm_subset, tx_subset; | 573 SkBitmap bm_subset, tx_subset; |
| 576 | 574 |
| 577 // ... one from a texture-subset | 575 // ... one from a texture-subset |
| 578 SkAutoTUnref<GrTexture> fullTx(GrRefCachedBitmapTexture(ctx, bitmap, | 576 SkAutoTUnref<GrTexture> fullTx(GrRefCachedBitmapTexture(context, bitmap, |
| 579 GrTextureParams::Cla
mpNoFilter())); | 577 GrTextureParams::Cla
mpNoFilter())); |
| 580 SkBitmap tx_full; | 578 SkBitmap tx_full; |
| 581 GrWrapTextureInBitmap(fullTx, bitmap.width(), bitmap.height(), true, &tx_ful
l); | 579 GrWrapTextureInBitmap(fullTx, bitmap.width(), bitmap.height(), true, &tx_ful
l); |
| 582 tx_full.extractSubset(&tx_subset, subset); | 580 tx_full.extractSubset(&tx_subset, subset); |
| 583 | 581 |
| 584 // ... one from a bitmap-subset | 582 // ... one from a bitmap-subset |
| 585 SkBitmap tmp_subset; | 583 SkBitmap tmp_subset; |
| 586 bitmap.extractSubset(&tmp_subset, subset); | 584 bitmap.extractSubset(&tmp_subset, subset); |
| 587 SkAutoTUnref<GrTexture> subsetTx(GrRefCachedBitmapTexture(ctx, tmp_subset, | 585 SkAutoTUnref<GrTexture> subsetTx(GrRefCachedBitmapTexture(context, tmp_subse
t, |
| 588 GrTextureParams::C
lampNoFilter())); | 586 GrTextureParams::C
lampNoFilter())); |
| 589 GrWrapTextureInBitmap(subsetTx, tmp_subset.width(), tmp_subset.height(), tru
e, &bm_subset); | 587 GrWrapTextureInBitmap(subsetTx, tmp_subset.width(), tmp_subset.height(), tru
e, &bm_subset); |
| 590 | 588 |
| 591 // did we get the same subset? | 589 // did we get the same subset? |
| 592 compare_textures(reporter, bm_subset.getTexture(), tx_subset.getTexture()); | 590 compare_textures(reporter, bm_subset.getTexture(), tx_subset.getTexture()); |
| 593 | 591 |
| 594 // do they draw the same? | 592 // do they draw the same? |
| 595 const SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128); | 593 const SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128); |
| 596 SkAutoTUnref<SkSurface> surfA(SkSurface::NewRenderTarget(ctx, SkSurface::kNo
_Budgeted, info, 0)); | 594 SkAutoTUnref<SkSurface> surfA(SkSurface::NewRenderTarget(context, SkSurface:
:kNo_Budgeted, info, 0)); |
| 597 SkAutoTUnref<SkSurface> surfB(SkSurface::NewRenderTarget(ctx, SkSurface::kNo
_Budgeted, info, 0)); | 595 SkAutoTUnref<SkSurface> surfB(SkSurface::NewRenderTarget(context, SkSurface:
:kNo_Budgeted, info, 0)); |
| 598 | 596 |
| 599 if (false) { | 597 if (false) { |
| 600 // | 598 // |
| 601 // BUG: depending on the driver, if we calls this with various quality
settings, it | 599 // BUG: depending on the driver, if we calls this with various quality
settings, it |
| 602 // may fail. | 600 // may fail. |
| 603 // | 601 // |
| 604 SkFilterQuality quality = kLow_SkFilterQuality; | 602 SkFilterQuality quality = kLow_SkFilterQuality; |
| 605 | 603 |
| 606 SkAutoTUnref<SkData> dataA(draw_into_surface(surfA, bm_subset, quality))
; | 604 SkAutoTUnref<SkData> dataA(draw_into_surface(surfA, bm_subset, quality))
; |
| 607 SkAutoTUnref<SkData> dataB(draw_into_surface(surfB, tx_subset, quality))
; | 605 SkAutoTUnref<SkData> dataB(draw_into_surface(surfB, tx_subset, quality))
; |
| 608 | 606 |
| 609 REPORTER_ASSERT(reporter, dataA->equals(dataB)); | 607 REPORTER_ASSERT(reporter, dataA->equals(dataB)); |
| 610 if (false) { | 608 if (false) { |
| 611 dump_to_file("test_image_A.png", dataA); | 609 dump_to_file("test_image_A.png", dataA); |
| 612 dump_to_file("test_image_B.png", dataB); | 610 dump_to_file("test_image_B.png", dataB); |
| 613 } | 611 } |
| 614 } | 612 } |
| 615 } | 613 } |
| 616 #endif | 614 #endif |
| OLD | NEW |