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 |