OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "SkData.h" | 9 #include "SkData.h" |
10 #include "SkDevice.h" | 10 #include "SkDevice.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 release_storage, storag
e); | 58 release_storage, storag
e); |
59 } | 59 } |
60 case kGpu_SurfaceType: | 60 case kGpu_SurfaceType: |
61 return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted,
info, 0, nullptr); | 61 return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted,
info, 0, nullptr); |
62 case kGpuScratch_SurfaceType: | 62 case kGpuScratch_SurfaceType: |
63 return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted,
info, 0, nullptr); | 63 return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted,
info, 0, nullptr); |
64 } | 64 } |
65 return nullptr; | 65 return nullptr; |
66 } | 66 } |
67 | 67 |
68 enum ImageType { | |
69 kRasterCopy_ImageType, | |
70 kRasterData_ImageType, | |
71 kRasterProc_ImageType, | |
72 kGpu_ImageType, | |
73 kCodec_ImageType, | |
74 }; | |
75 | |
76 #include "SkImageGenerator.h" | |
77 | |
78 class EmptyGenerator : public SkImageGenerator { | |
79 public: | |
80 EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {} | |
81 }; | |
82 | |
83 static void test_empty_image(skiatest::Reporter* reporter) { | |
84 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); | |
85 | |
86 REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterCopy(info, nullptr, 0
)); | |
87 REPORTER_ASSERT(reporter, nullptr == SkImage::NewRasterData(info, nullptr, 0
)); | |
88 REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromRaster(info, nullptr, 0
, nullptr, nullptr)); | |
89 REPORTER_ASSERT(reporter, nullptr == SkImage::NewFromGenerator(new EmptyGene
rator)); | |
90 } | |
91 | |
92 static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) { | 68 static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) { |
93 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); | 69 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); |
94 | 70 |
95 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRaster(info)); | 71 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRaster(info)); |
96 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRasterDirect(info, nullpt
r, 0)); | 72 REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRasterDirect(info, nullpt
r, 0)); |
97 if (ctx) { | 73 if (ctx) { |
98 REPORTER_ASSERT(reporter, nullptr == | 74 REPORTER_ASSERT(reporter, nullptr == |
99 SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted,
info, 0, nullptr)); | 75 SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted,
info, 0, nullptr)); |
100 } | 76 } |
101 } | 77 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 } | 144 } |
169 } | 145 } |
170 } | 146 } |
171 } | 147 } |
172 gpu->deleteTestingOnlyBackendTexture(texHandle); | 148 gpu->deleteTestingOnlyBackendTexture(texHandle); |
173 | 149 |
174 } | 150 } |
175 #endif | 151 #endif |
176 | 152 |
177 | 153 |
178 static void test_image(skiatest::Reporter* reporter) { | |
179 SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | |
180 size_t rowBytes = info.minRowBytes(); | |
181 size_t size = info.getSafeSize(rowBytes); | |
182 SkData* data = SkData::NewUninitialized(size); | |
183 | |
184 REPORTER_ASSERT(reporter, data->unique()); | |
185 SkImage* image = SkImage::NewRasterData(info, data, rowBytes); | |
186 REPORTER_ASSERT(reporter, !data->unique()); | |
187 image->unref(); | |
188 REPORTER_ASSERT(reporter, data->unique()); | |
189 data->unref(); | |
190 } | |
191 | |
192 // Want to ensure that our Release is called when the owning image is destroyed | |
193 struct ReleaseDataContext { | |
194 skiatest::Reporter* fReporter; | |
195 SkData* fData; | |
196 | |
197 static void Release(const void* pixels, void* context) { | |
198 ReleaseDataContext* state = (ReleaseDataContext*)context; | |
199 REPORTER_ASSERT(state->fReporter, state->fData); | |
200 state->fData->unref(); | |
201 state->fData = nullptr; | |
202 } | |
203 }; | |
204 | |
205 // May we (soon) eliminate the need to keep testing this, by hiding the bloody d
evice! | |
206 #include "SkDevice.h" | |
207 static uint32_t get_legacy_gen_id(SkSurface* surf) { | |
208 SkBaseDevice* device = surf->getCanvas()->getDevice_just_for_deprecated_comp
atibility_testing(); | |
209 return device->accessBitmap(false).getGenerationID(); | |
210 } | |
211 | |
212 /* | |
213 * Test legacy behavor of bumping the surface's device's bitmap's genID when we
access its | |
214 * texture handle for writing. | |
215 * | |
216 * Note: this needs to be tested separately from checking newImageSnapshot, as
calling that | |
217 * can also incidentally bump the genID (when a new backing surface is created)
. | |
218 */ | |
219 template <class F> | |
220 static void test_texture_handle_genID(skiatest::Reporter* reporter, SkSurface* s
urf, F f) { | |
221 const uint32_t gen0 = get_legacy_gen_id(surf); | |
222 f(surf, SkSurface::kFlushRead_BackendHandleAccess); | |
223 const uint32_t gen1 = get_legacy_gen_id(surf); | |
224 REPORTER_ASSERT(reporter, gen0 == gen1); | |
225 | |
226 f(surf, SkSurface::kFlushWrite_BackendHandleAccess); | |
227 const uint32_t gen2 = get_legacy_gen_id(surf); | |
228 REPORTER_ASSERT(reporter, gen0 != gen2); | |
229 | |
230 f(surf, SkSurface::kDiscardWrite_BackendHandleAccess); | |
231 const uint32_t gen3 = get_legacy_gen_id(surf); | |
232 REPORTER_ASSERT(reporter, gen0 != gen3); | |
233 REPORTER_ASSERT(reporter, gen2 != gen3); | |
234 } | |
235 | |
236 template <class F> | |
237 static void test_backend_handle(skiatest::Reporter* reporter, SkSurface* surf, F
f) { | |
238 SkAutoTUnref<SkImage> image0(surf->newImageSnapshot()); | |
239 GrBackendObject obj = f(surf, SkSurface::kFlushRead_BackendHandleAccess); | |
240 REPORTER_ASSERT(reporter, obj != 0); | |
241 SkAutoTUnref<SkImage> image1(surf->newImageSnapshot()); | |
242 // just read access should not affect the snapshot | |
243 REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID()); | |
244 | |
245 obj = f(surf, SkSurface::kFlushWrite_BackendHandleAccess); | |
246 REPORTER_ASSERT(reporter, obj != 0); | |
247 SkAutoTUnref<SkImage> image2(surf->newImageSnapshot()); | |
248 // expect a new image, since we claimed we would write | |
249 REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID()); | |
250 | |
251 obj = f(surf, SkSurface::kDiscardWrite_BackendHandleAccess); | |
252 REPORTER_ASSERT(reporter, obj != 0); | |
253 SkAutoTUnref<SkImage> image3(surf->newImageSnapshot()); | |
254 // expect a new(er) image, since we claimed we would write | |
255 REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID()); | |
256 REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID()); | |
257 } | |
258 | |
259 static SkImage* create_image(skiatest::Reporter* reporter, | |
260 ImageType imageType, GrContext* context, SkColor co
lor, | |
261 ReleaseDataContext* releaseContext) { | |
262 const SkPMColor pmcolor = SkPreMultiplyColor(color); | |
263 const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); | |
264 const size_t rowBytes = info.minRowBytes(); | |
265 const size_t size = rowBytes * info.height(); | |
266 | |
267 SkAutoTUnref<SkData> data(SkData::NewUninitialized(size)); | |
268 void* addr = data->writable_data(); | |
269 sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2)); | |
270 | |
271 switch (imageType) { | |
272 case kRasterCopy_ImageType: | |
273 return SkImage::NewRasterCopy(info, addr, rowBytes); | |
274 case kRasterData_ImageType: | |
275 return SkImage::NewRasterData(info, data, rowBytes); | |
276 case kRasterProc_ImageType: | |
277 SkASSERT(releaseContext); | |
278 releaseContext->fData = SkRef(data.get()); | |
279 return SkImage::NewFromRaster(info, addr, rowBytes, | |
280 ReleaseDataContext::Release, releaseCo
ntext); | |
281 case kGpu_ImageType: { | |
282 SkAutoTUnref<SkSurface> surf( | |
283 SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, inf
o, 0)); | |
284 surf->getCanvas()->clear(color); | |
285 // test our backing texture / rendertarget while were here... | |
286 auto textureAccessorFunc = | |
287 [](SkSurface* surf, SkSurface::BackendHandleAccess access) -
> GrBackendObject { | |
288 return surf->getTextureHandle(access); }; | |
289 auto renderTargetAccessorFunc = | |
290 [](SkSurface* surf, SkSurface::BackendHandleAccess access) -
> GrBackendObject { | |
291 GrBackendObject obj; | |
292 SkAssertResult(surf->getRenderTargetHandle(&obj, access)
); | |
293 return obj; }; | |
294 test_backend_handle(reporter, surf, textureAccessorFunc); | |
295 test_backend_handle(reporter, surf, renderTargetAccessorFunc); | |
296 test_texture_handle_genID(reporter, surf, textureAccessorFunc); | |
297 test_texture_handle_genID(reporter, surf, renderTargetAccessorFunc); | |
298 | |
299 // redraw so our returned image looks as expected. | |
300 surf->getCanvas()->clear(color); | |
301 return surf->newImageSnapshot(); | |
302 } | |
303 case kCodec_ImageType: { | |
304 SkBitmap bitmap; | |
305 bitmap.installPixels(info, addr, rowBytes); | |
306 SkAutoTUnref<SkData> src( | |
307 SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 1
00)); | |
308 return SkImage::NewFromEncoded(src); | |
309 } | |
310 } | |
311 SkASSERT(false); | |
312 return nullptr; | |
313 } | |
314 | |
315 static void set_pixels(SkPMColor pixels[], int count, SkPMColor color) { | |
316 sk_memset32(pixels, color, count); | |
317 } | |
318 static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected)
{ | |
319 for (int i = 0; i < count; ++i) { | |
320 if (pixels[i] != expected) { | |
321 return false; | |
322 } | |
323 } | |
324 return true; | |
325 } | |
326 | |
327 static void test_image_readpixels(skiatest::Reporter* reporter, SkImage* image, | |
328 SkPMColor expected) { | |
329 const SkPMColor notExpected = ~expected; | |
330 | |
331 const int w = 2, h = 2; | |
332 const size_t rowBytes = w * sizeof(SkPMColor); | |
333 SkPMColor pixels[w*h]; | |
334 | |
335 SkImageInfo info; | |
336 | |
337 info = SkImageInfo::MakeUnknown(w, h); | |
338 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0)); | |
339 | |
340 // out-of-bounds should fail | |
341 info = SkImageInfo::MakeN32Premul(w, h); | |
342 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0))
; | |
343 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h))
; | |
344 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->
width(), 0)); | |
345 REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, imag
e->height())); | |
346 | |
347 // top-left should succeed | |
348 set_pixels(pixels, w*h, notExpected); | |
349 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0)); | |
350 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected)); | |
351 | |
352 // bottom-right should succeed | |
353 set_pixels(pixels, w*h, notExpected); | |
354 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, | |
355 image->width() - w, image->heigh
t() - h)); | |
356 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected)); | |
357 | |
358 // partial top-left should succeed | |
359 set_pixels(pixels, w*h, notExpected); | |
360 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1))
; | |
361 REPORTER_ASSERT(reporter, pixels[3] == expected); | |
362 REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected)); | |
363 | |
364 // partial bottom-right should succeed | |
365 set_pixels(pixels, w*h, notExpected); | |
366 REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, | |
367 image->width() - 1, image->heigh
t() - 1)); | |
368 REPORTER_ASSERT(reporter, pixels[0] == expected); | |
369 REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected)); | |
370 } | |
371 | |
372 static void check_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* ima
ge, | |
373 const SkBitmap& bitmap, SkImage::LegacyBitmapMod
e mode) { | |
374 REPORTER_ASSERT(reporter, image->width() == bitmap.width()); | |
375 REPORTER_ASSERT(reporter, image->height() == bitmap.height()); | |
376 REPORTER_ASSERT(reporter, image->isOpaque() == bitmap.isOpaque()); | |
377 | |
378 if (SkImage::kRO_LegacyBitmapMode == mode) { | |
379 REPORTER_ASSERT(reporter, bitmap.isImmutable()); | |
380 } | |
381 | |
382 SkAutoLockPixels alp(bitmap); | |
383 REPORTER_ASSERT(reporter, bitmap.getPixels()); | |
384 | |
385 const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType()); | |
386 SkPMColor imageColor; | |
387 REPORTER_ASSERT(reporter, image->readPixels(info, &imageColor, sizeof(SkPMCo
lor), 0, 0)); | |
388 REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0)); | |
389 } | |
390 | |
391 static void test_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* imag
e) { | |
392 const SkImage::LegacyBitmapMode modes[] = { | |
393 SkImage::kRO_LegacyBitmapMode, | |
394 SkImage::kRW_LegacyBitmapMode, | |
395 }; | |
396 for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) { | |
397 SkBitmap bitmap; | |
398 REPORTER_ASSERT(reporter, image->asLegacyBitmap(&bitmap, modes[i])); | |
399 check_legacy_bitmap(reporter, image, bitmap, modes[i]); | |
400 | |
401 // Test subsetting to exercise the rowBytes logic. | |
402 SkBitmap tmp; | |
403 REPORTER_ASSERT(reporter, bitmap.extractSubset(&tmp, SkIRect::MakeWH(ima
ge->width() / 2, | |
404 ima
ge->height() / 2))); | |
405 SkAutoTUnref<SkImage> subsetImage(SkImage::NewFromBitmap(tmp)); | |
406 REPORTER_ASSERT(reporter, subsetImage); | |
407 | |
408 SkBitmap subsetBitmap; | |
409 REPORTER_ASSERT(reporter, subsetImage->asLegacyBitmap(&subsetBitmap, mod
es[i])); | |
410 check_legacy_bitmap(reporter, subsetImage, subsetBitmap, modes[i]); | |
411 } | |
412 } | |
413 | |
414 static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* facto
ry) { | |
415 static const struct { | |
416 ImageType fType; | |
417 bool fPeekShouldSucceed; | |
418 const char* fName; | |
419 } gRec[] = { | |
420 { kRasterCopy_ImageType, true, "RasterCopy" }, | |
421 { kRasterData_ImageType, true, "RasterData" }, | |
422 { kRasterProc_ImageType, true, "RasterProc" }, | |
423 { kGpu_ImageType, false, "Gpu" }, | |
424 { kCodec_ImageType, false, "Codec" }, | |
425 }; | |
426 | |
427 const SkColor color = SK_ColorRED; | |
428 const SkPMColor pmcolor = SkPreMultiplyColor(color); | |
429 | |
430 GrContext* ctx = nullptr; | |
431 #if SK_SUPPORT_GPU | |
432 ctx = factory->get(GrContextFactory::kNative_GLContextType); | |
433 if (nullptr == ctx) { | |
434 return; | |
435 } | |
436 #endif | |
437 | |
438 ReleaseDataContext releaseCtx; | |
439 releaseCtx.fReporter = reporter; | |
440 | |
441 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | |
442 SkImageInfo info; | |
443 size_t rowBytes; | |
444 | |
445 releaseCtx.fData = nullptr; | |
446 SkAutoTUnref<SkImage> image(create_image(reporter, gRec[i].fType, ctx, c
olor, &releaseCtx)); | |
447 if (!image.get()) { | |
448 SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName); | |
449 continue; // gpu may not be enabled | |
450 } | |
451 if (kRasterProc_ImageType == gRec[i].fType) { | |
452 REPORTER_ASSERT(reporter, nullptr != releaseCtx.fData); // we are t
racking the data | |
453 } else { | |
454 REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData); // we ignor
ed the context | |
455 } | |
456 | |
457 test_legacy_bitmap(reporter, image); | |
458 | |
459 const void* addr = image->peekPixels(&info, &rowBytes); | |
460 bool success = SkToBool(addr); | |
461 REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success); | |
462 if (success) { | |
463 REPORTER_ASSERT(reporter, 10 == info.width()); | |
464 REPORTER_ASSERT(reporter, 10 == info.height()); | |
465 REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType()); | |
466 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() || | |
467 kOpaque_SkAlphaType == info.alphaType()); | |
468 REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes); | |
469 REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr); | |
470 } | |
471 | |
472 test_image_readpixels(reporter, image, pmcolor); | |
473 } | |
474 REPORTER_ASSERT(reporter, nullptr == releaseCtx.fData); // we released the
data | |
475 } | |
476 | 154 |
477 static void test_canvaspeek(skiatest::Reporter* reporter, | 155 static void test_canvaspeek(skiatest::Reporter* reporter, |
478 GrContextFactory* factory) { | 156 GrContextFactory* factory) { |
479 static const struct { | 157 static const struct { |
480 SurfaceType fType; | 158 SurfaceType fType; |
481 bool fPeekShouldSucceed; | 159 bool fPeekShouldSucceed; |
482 } gRec[] = { | 160 } gRec[] = { |
483 { kRaster_SurfaceType, true }, | 161 { kRaster_SurfaceType, true }, |
484 { kRasterDirect_SurfaceType, true }, | 162 { kRasterDirect_SurfaceType, true }, |
485 #if SK_SUPPORT_GPU | 163 #if SK_SUPPORT_GPU |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 SkImage* image2 = surface->newImageSnapshot(); | 554 SkImage* image2 = surface->newImageSnapshot(); |
877 SkAutoTUnref<SkImage> aur_image2(image2); | 555 SkAutoTUnref<SkImage> aur_image2(image2); |
878 SkDEBUGCODE(image2->validate();) | 556 SkDEBUGCODE(image2->validate();) |
879 SkDEBUGCODE(surface->validate();) | 557 SkDEBUGCODE(surface->validate();) |
880 REPORTER_ASSERT(reporter, image1 != image2); | 558 REPORTER_ASSERT(reporter, image1 != image2); |
881 } | 559 } |
882 | 560 |
883 } | 561 } |
884 | 562 |
885 DEF_GPUTEST(Surface, reporter, factory) { | 563 DEF_GPUTEST(Surface, reporter, factory) { |
886 test_image(reporter); | |
887 | |
888 TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, nullptr); | 564 TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, nullptr); |
889 TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, nullp
tr); | 565 TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, nullp
tr); |
890 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kDisc
ard_ContentChangeMode); | 566 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kDisc
ard_ContentChangeMode); |
891 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kReta
in_ContentChangeMode); | 567 TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kReta
in_ContentChangeMode); |
892 | 568 |
893 test_empty_image(reporter); | 569 |
894 test_empty_surface(reporter, nullptr); | 570 test_empty_surface(reporter, nullptr); |
895 | 571 |
896 test_imagepeek(reporter, factory); | 572 |
897 test_canvaspeek(reporter, factory); | 573 test_canvaspeek(reporter, factory); |
898 | 574 |
899 test_accessPixels(reporter, factory); | 575 test_accessPixels(reporter, factory); |
900 | 576 |
901 test_snap_alphatype(reporter, factory); | 577 test_snap_alphatype(reporter, factory); |
902 | 578 |
903 #if SK_SUPPORT_GPU | 579 #if SK_SUPPORT_GPU |
904 TestGetTexture(reporter, kRaster_SurfaceType, nullptr); | 580 TestGetTexture(reporter, kRaster_SurfaceType, nullptr); |
905 if (factory) { | 581 if (factory) { |
906 for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { | 582 for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { |
(...skipping 17 matching lines...) Expand all Loading... |
924 TestGetTexture(reporter, kGpuScratch_SurfaceType, context); | 600 TestGetTexture(reporter, kGpuScratch_SurfaceType, context); |
925 test_empty_surface(reporter, context); | 601 test_empty_surface(reporter, context); |
926 test_surface_budget(reporter, context); | 602 test_surface_budget(reporter, context); |
927 test_wrapped_texture_surface(reporter, context); | 603 test_wrapped_texture_surface(reporter, context); |
928 } | 604 } |
929 } | 605 } |
930 } | 606 } |
931 #endif | 607 #endif |
932 } | 608 } |
933 | 609 |
934 #if SK_SUPPORT_GPU | |
935 | 610 |
936 struct ReleaseTextureContext { | |
937 ReleaseTextureContext(skiatest::Reporter* reporter) { | |
938 fReporter = reporter; | |
939 fIsReleased = false; | |
940 } | |
941 | |
942 skiatest::Reporter* fReporter; | |
943 bool fIsReleased; | |
944 | |
945 void doRelease() { | |
946 REPORTER_ASSERT(fReporter, false == fIsReleased); | |
947 fIsReleased = true; | |
948 } | |
949 | |
950 static void ReleaseProc(void* context) { | |
951 ((ReleaseTextureContext*)context)->doRelease(); | |
952 } | |
953 }; | |
954 | |
955 static SkImage* make_desc_image(GrContext* ctx, int w, int h, GrBackendObject te
xID, | |
956 ReleaseTextureContext* releaseContext) { | |
957 GrBackendTextureDesc desc; | |
958 desc.fConfig = kSkia8888_GrPixelConfig; | |
959 // need to be a rendertarget for now... | |
960 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | |
961 desc.fWidth = w; | |
962 desc.fHeight = h; | |
963 desc.fSampleCnt = 0; | |
964 desc.fTextureHandle = texID; | |
965 return releaseContext | |
966 ? SkImage::NewFromTexture(ctx, desc, kPremul_SkAlphaType, | |
967 ReleaseTextureContext::ReleaseProc, re
leaseContext) | |
968 : SkImage::NewFromTextureCopy(ctx, desc, kPremul_SkAlphaType); | |
969 } | |
970 | |
971 static void test_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMC
olor expected) { | |
972 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | |
973 SkPMColor pixel; | |
974 REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0,
0)); | |
975 REPORTER_ASSERT(reporter, pixel == expected); | |
976 } | |
977 | |
978 DEF_GPUTEST(SkImage_NewFromTexture, reporter, factory) { | |
979 GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType); | |
980 if (!ctx) { | |
981 REPORTER_ASSERT(reporter, false); | |
982 return; | |
983 } | |
984 GrTextureProvider* provider = ctx->textureProvider(); | |
985 | |
986 const int w = 10; | |
987 const int h = 10; | |
988 SkPMColor storage[w * h]; | |
989 const SkPMColor expected0 = SkPreMultiplyColor(SK_ColorRED); | |
990 sk_memset32(storage, expected0, w * h); | |
991 | |
992 GrSurfaceDesc desc; | |
993 desc.fFlags = kRenderTarget_GrSurfaceFlag; // needs to be a rendertarget fo
r readpixels(); | |
994 desc.fOrigin = kDefault_GrSurfaceOrigin; | |
995 desc.fWidth = w; | |
996 desc.fHeight = h; | |
997 desc.fConfig = kSkia8888_GrPixelConfig; | |
998 desc.fSampleCnt = 0; | |
999 | |
1000 SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w
* 4)); | |
1001 if (!tex) { | |
1002 REPORTER_ASSERT(reporter, false); | |
1003 return; | |
1004 } | |
1005 | |
1006 GrBackendObject srcTex = tex->getTextureHandle(); | |
1007 ReleaseTextureContext releaseCtx(reporter); | |
1008 | |
1009 SkAutoTUnref<SkImage> refImg(make_desc_image(ctx, w, h, srcTex, &releaseCtx)
); | |
1010 SkAutoTUnref<SkImage> cpyImg(make_desc_image(ctx, w, h, srcTex, nullptr)); | |
1011 | |
1012 test_image_color(reporter, refImg, expected0); | |
1013 test_image_color(reporter, cpyImg, expected0); | |
1014 | |
1015 // Now lets jam new colors into our "external" texture, and see if the image
s notice | |
1016 const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE); | |
1017 sk_memset32(storage, expected1, w * h); | |
1018 tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kF
lushWrites_PixelOp); | |
1019 | |
1020 // The cpy'd one should still see the old color | |
1021 #if 0 | |
1022 // There is no guarantee that refImg sees the new color. We are free to have
made a copy. Our | |
1023 // write pixels call violated the contract with refImg and refImg is now und
efined. | |
1024 test_image_color(reporter, refImg, expected1); | |
1025 #endif | |
1026 test_image_color(reporter, cpyImg, expected0); | |
1027 | |
1028 // Now exercise the release proc | |
1029 REPORTER_ASSERT(reporter, !releaseCtx.fIsReleased); | |
1030 refImg.reset(nullptr); // force a release of the image | |
1031 REPORTER_ASSERT(reporter, releaseCtx.fIsReleased); | |
1032 } | |
1033 #endif | |
OLD | NEW |