| 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 return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted,
info, 0, NULL); | 58 return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted,
info, 0, NULL); |
| 59 case kGpuScratch_SurfaceType: | 59 case kGpuScratch_SurfaceType: |
| 60 return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted,
info, 0, NULL); | 60 return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted,
info, 0, NULL); |
| 61 } | 61 } |
| 62 return NULL; | 62 return NULL; |
| 63 } | 63 } |
| 64 | 64 |
| 65 enum ImageType { | 65 enum ImageType { |
| 66 kRasterCopy_ImageType, | 66 kRasterCopy_ImageType, |
| 67 kRasterData_ImageType, | 67 kRasterData_ImageType, |
| 68 kRasterProc_ImageType, |
| 68 kGpu_ImageType, | 69 kGpu_ImageType, |
| 69 kCodec_ImageType, | 70 kCodec_ImageType, |
| 70 }; | 71 }; |
| 71 | 72 |
| 72 #include "SkImageGenerator.h" | 73 #include "SkImageGenerator.h" |
| 73 | 74 |
| 74 class EmptyGenerator : public SkImageGenerator { | 75 class EmptyGenerator : public SkImageGenerator { |
| 75 public: | 76 public: |
| 76 EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {} | 77 EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {} |
| 77 }; | 78 }; |
| 78 | 79 |
| 79 static void test_empty_image(skiatest::Reporter* reporter) { | 80 static void test_empty_image(skiatest::Reporter* reporter) { |
| 80 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); | 81 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); |
| 81 | 82 |
| 82 REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterCopy(info, NULL, 0)); | 83 REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterCopy(info, NULL, 0)); |
| 83 REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterData(info, NULL, 0)); | 84 REPORTER_ASSERT(reporter, NULL == SkImage::NewRasterData(info, NULL, 0)); |
| 85 REPORTER_ASSERT(reporter, NULL == SkImage::NewFromRaster(info, NULL, 0, NULL
, NULL)); |
| 84 REPORTER_ASSERT(reporter, NULL == SkImage::NewFromGenerator(SkNEW(EmptyGener
ator))); | 86 REPORTER_ASSERT(reporter, NULL == SkImage::NewFromGenerator(SkNEW(EmptyGener
ator))); |
| 85 } | 87 } |
| 86 | 88 |
| 87 static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) { | 89 static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) { |
| 88 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); | 90 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); |
| 89 | 91 |
| 90 REPORTER_ASSERT(reporter, NULL == SkSurface::NewRaster(info)); | 92 REPORTER_ASSERT(reporter, NULL == SkSurface::NewRaster(info)); |
| 91 REPORTER_ASSERT(reporter, NULL == SkSurface::NewRasterDirect(info, NULL, 0))
; | 93 REPORTER_ASSERT(reporter, NULL == SkSurface::NewRasterDirect(info, NULL, 0))
; |
| 92 if (ctx) { | 94 if (ctx) { |
| 93 REPORTER_ASSERT(reporter, NULL == | 95 REPORTER_ASSERT(reporter, NULL == |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 SkData* data = SkData::NewUninitialized(size); | 199 SkData* data = SkData::NewUninitialized(size); |
| 198 | 200 |
| 199 REPORTER_ASSERT(reporter, data->unique()); | 201 REPORTER_ASSERT(reporter, data->unique()); |
| 200 SkImage* image = SkImage::NewRasterData(info, data, rowBytes); | 202 SkImage* image = SkImage::NewRasterData(info, data, rowBytes); |
| 201 REPORTER_ASSERT(reporter, !data->unique()); | 203 REPORTER_ASSERT(reporter, !data->unique()); |
| 202 image->unref(); | 204 image->unref(); |
| 203 REPORTER_ASSERT(reporter, data->unique()); | 205 REPORTER_ASSERT(reporter, data->unique()); |
| 204 data->unref(); | 206 data->unref(); |
| 205 } | 207 } |
| 206 | 208 |
| 207 static SkImage* createImage(ImageType imageType, GrContext* context, SkColor col
or) { | 209 // Want to ensure that our Release is called when the owning image is destroyed |
| 210 struct ReleaseDataContext { |
| 211 skiatest::Reporter* fReporter; |
| 212 SkData* fData; |
| 213 |
| 214 static void Release(const void* pixels, void* context) { |
| 215 ReleaseDataContext* state = (ReleaseDataContext*)context; |
| 216 REPORTER_ASSERT(state->fReporter, state->fData); |
| 217 state->fData->unref(); |
| 218 state->fData = NULL; |
| 219 } |
| 220 }; |
| 221 |
| 222 static SkImage* createImage(ImageType imageType, GrContext* context, SkColor col
or, |
| 223 ReleaseDataContext* releaseContext) { |
| 208 const SkPMColor pmcolor = SkPreMultiplyColor(color); | 224 const SkPMColor pmcolor = SkPreMultiplyColor(color); |
| 209 const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); | 225 const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); |
| 210 const size_t rowBytes = info.minRowBytes(); | 226 const size_t rowBytes = info.minRowBytes(); |
| 211 const size_t size = rowBytes * info.height(); | 227 const size_t size = rowBytes * info.height(); |
| 212 | 228 |
| 213 SkAutoTUnref<SkData> data(SkData::NewUninitialized(size)); | 229 SkAutoTUnref<SkData> data(SkData::NewUninitialized(size)); |
| 214 void* addr = data->writable_data(); | 230 void* addr = data->writable_data(); |
| 215 sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2)); | 231 sk_memset32((SkPMColor*)addr, pmcolor, SkToInt(size >> 2)); |
| 216 | 232 |
| 217 switch (imageType) { | 233 switch (imageType) { |
| 218 case kRasterCopy_ImageType: | 234 case kRasterCopy_ImageType: |
| 219 return SkImage::NewRasterCopy(info, addr, rowBytes); | 235 return SkImage::NewRasterCopy(info, addr, rowBytes); |
| 220 case kRasterData_ImageType: | 236 case kRasterData_ImageType: |
| 221 return SkImage::NewRasterData(info, data, rowBytes); | 237 return SkImage::NewRasterData(info, data, rowBytes); |
| 238 case kRasterProc_ImageType: |
| 239 SkASSERT(releaseContext); |
| 240 releaseContext->fData = SkRef(data.get()); |
| 241 return SkImage::NewFromRaster(info, addr, rowBytes, |
| 242 ReleaseDataContext::Release, releaseCo
ntext); |
| 222 case kGpu_ImageType: { | 243 case kGpu_ImageType: { |
| 223 SkAutoTUnref<SkSurface> surf( | 244 SkAutoTUnref<SkSurface> surf( |
| 224 SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, inf
o, 0)); | 245 SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, inf
o, 0)); |
| 225 surf->getCanvas()->clear(color); | 246 surf->getCanvas()->clear(color); |
| 226 return surf->newImageSnapshot(); | 247 return surf->newImageSnapshot(); |
| 227 } | 248 } |
| 228 case kCodec_ImageType: { | 249 case kCodec_ImageType: { |
| 229 SkBitmap bitmap; | 250 SkBitmap bitmap; |
| 230 bitmap.installPixels(info, addr, rowBytes); | 251 bitmap.installPixels(info, addr, rowBytes); |
| 231 SkAutoTUnref<SkData> src( | 252 SkAutoTUnref<SkData> src( |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 } | 316 } |
| 296 | 317 |
| 297 static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* facto
ry) { | 318 static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* facto
ry) { |
| 298 static const struct { | 319 static const struct { |
| 299 ImageType fType; | 320 ImageType fType; |
| 300 bool fPeekShouldSucceed; | 321 bool fPeekShouldSucceed; |
| 301 const char* fName; | 322 const char* fName; |
| 302 } gRec[] = { | 323 } gRec[] = { |
| 303 { kRasterCopy_ImageType, true, "RasterCopy" }, | 324 { kRasterCopy_ImageType, true, "RasterCopy" }, |
| 304 { kRasterData_ImageType, true, "RasterData" }, | 325 { kRasterData_ImageType, true, "RasterData" }, |
| 326 { kRasterProc_ImageType, true, "RasterProc" }, |
| 305 { kGpu_ImageType, false, "Gpu" }, | 327 { kGpu_ImageType, false, "Gpu" }, |
| 306 { kCodec_ImageType, false, "Codec" }, | 328 { kCodec_ImageType, false, "Codec" }, |
| 307 }; | 329 }; |
| 308 | 330 |
| 309 const SkColor color = SK_ColorRED; | 331 const SkColor color = SK_ColorRED; |
| 310 const SkPMColor pmcolor = SkPreMultiplyColor(color); | 332 const SkPMColor pmcolor = SkPreMultiplyColor(color); |
| 311 | 333 |
| 312 GrContext* ctx = NULL; | 334 GrContext* ctx = NULL; |
| 313 #if SK_SUPPORT_GPU | 335 #if SK_SUPPORT_GPU |
| 314 ctx = factory->get(GrContextFactory::kNative_GLContextType); | 336 ctx = factory->get(GrContextFactory::kNative_GLContextType); |
| 315 if (NULL == ctx) { | 337 if (NULL == ctx) { |
| 316 return; | 338 return; |
| 317 } | 339 } |
| 318 #endif | 340 #endif |
| 319 | 341 |
| 342 ReleaseDataContext releaseCtx; |
| 343 releaseCtx.fReporter = reporter; |
| 344 |
| 320 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 345 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { |
| 321 SkImageInfo info; | 346 SkImageInfo info; |
| 322 size_t rowBytes; | 347 size_t rowBytes; |
| 323 | 348 |
| 324 SkAutoTUnref<SkImage> image(createImage(gRec[i].fType, ctx, color)); | 349 releaseCtx.fData = NULL; |
| 350 SkAutoTUnref<SkImage> image(createImage(gRec[i].fType, ctx, color, &rele
aseCtx)); |
| 325 if (!image.get()) { | 351 if (!image.get()) { |
| 326 SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName); | 352 SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName); |
| 327 continue; // gpu may not be enabled | 353 continue; // gpu may not be enabled |
| 328 } | 354 } |
| 355 if (kRasterProc_ImageType == gRec[i].fType) { |
| 356 REPORTER_ASSERT(reporter, NULL != releaseCtx.fData); // we are trac
king the data |
| 357 } else { |
| 358 REPORTER_ASSERT(reporter, NULL == releaseCtx.fData); // we ignored
the context |
| 359 } |
| 360 |
| 329 const void* addr = image->peekPixels(&info, &rowBytes); | 361 const void* addr = image->peekPixels(&info, &rowBytes); |
| 330 bool success = SkToBool(addr); | 362 bool success = SkToBool(addr); |
| 331 REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success); | 363 REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success); |
| 332 if (success) { | 364 if (success) { |
| 333 REPORTER_ASSERT(reporter, 10 == info.width()); | 365 REPORTER_ASSERT(reporter, 10 == info.width()); |
| 334 REPORTER_ASSERT(reporter, 10 == info.height()); | 366 REPORTER_ASSERT(reporter, 10 == info.height()); |
| 335 REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType()); | 367 REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType()); |
| 336 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() || | 368 REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() || |
| 337 kOpaque_SkAlphaType == info.alphaType()); | 369 kOpaque_SkAlphaType == info.alphaType()); |
| 338 REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes); | 370 REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes); |
| 339 REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr); | 371 REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr); |
| 340 } | 372 } |
| 341 | 373 |
| 342 test_image_readpixels(reporter, image, pmcolor); | 374 test_image_readpixels(reporter, image, pmcolor); |
| 343 } | 375 } |
| 376 REPORTER_ASSERT(reporter, NULL == releaseCtx.fData); // we released the dat
a |
| 344 } | 377 } |
| 345 | 378 |
| 346 static void test_canvaspeek(skiatest::Reporter* reporter, | 379 static void test_canvaspeek(skiatest::Reporter* reporter, |
| 347 GrContextFactory* factory) { | 380 GrContextFactory* factory) { |
| 348 static const struct { | 381 static const struct { |
| 349 SurfaceType fType; | 382 SurfaceType fType; |
| 350 bool fPeekShouldSucceed; | 383 bool fPeekShouldSucceed; |
| 351 } gRec[] = { | 384 } gRec[] = { |
| 352 { kRaster_SurfaceType, true }, | 385 { kRaster_SurfaceType, true }, |
| 353 { kRasterDirect_SurfaceType, true }, | 386 { kRasterDirect_SurfaceType, true }, |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 test_empty_surface(reporter, context); | 765 test_empty_surface(reporter, context); |
| 733 test_surface_budget(reporter, context); | 766 test_surface_budget(reporter, context); |
| 734 test_wrapped_texture_surface(reporter, context); | 767 test_wrapped_texture_surface(reporter, context); |
| 735 } | 768 } |
| 736 } | 769 } |
| 737 } | 770 } |
| 738 #endif | 771 #endif |
| 739 } | 772 } |
| 740 | 773 |
| 741 #if SK_SUPPORT_GPU | 774 #if SK_SUPPORT_GPU |
| 742 static SkImage* make_desc_image(GrContext* ctx, int w, int h, GrBackendObject te
xID, bool doCopy) { | 775 |
| 776 struct ReleaseTextureContext { |
| 777 ReleaseTextureContext(skiatest::Reporter* reporter) { |
| 778 fReporter = reporter; |
| 779 fIsReleased = false; |
| 780 } |
| 781 |
| 782 skiatest::Reporter* fReporter; |
| 783 bool fIsReleased; |
| 784 |
| 785 void doRelease() { |
| 786 REPORTER_ASSERT(fReporter, false == fIsReleased); |
| 787 fIsReleased = true; |
| 788 } |
| 789 |
| 790 static void ReleaseProc(void* context) { |
| 791 ((ReleaseTextureContext*)context)->doRelease(); |
| 792 } |
| 793 }; |
| 794 |
| 795 static SkImage* make_desc_image(GrContext* ctx, int w, int h, GrBackendObject te
xID, |
| 796 ReleaseTextureContext* releaseContext) { |
| 743 GrBackendTextureDesc desc; | 797 GrBackendTextureDesc desc; |
| 744 desc.fConfig = kSkia8888_GrPixelConfig; | 798 desc.fConfig = kSkia8888_GrPixelConfig; |
| 745 // need to be a rendertarget for now... | 799 // need to be a rendertarget for now... |
| 746 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | 800 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
| 747 desc.fWidth = w; | 801 desc.fWidth = w; |
| 748 desc.fHeight = h; | 802 desc.fHeight = h; |
| 749 desc.fSampleCnt = 0; | 803 desc.fSampleCnt = 0; |
| 750 desc.fTextureHandle = texID; | 804 desc.fTextureHandle = texID; |
| 751 return doCopy ? SkImage::NewFromTextureCopy(ctx, desc) : SkImage::NewFromTex
ture(ctx, desc); | 805 return releaseContext |
| 806 ? SkImage::NewFromTexture(ctx, desc, kPremul_SkAlphaType, |
| 807 ReleaseTextureContext::ReleaseProc, re
leaseContext) |
| 808 : SkImage::NewFromTextureCopy(ctx, desc, kPremul_SkAlphaType); |
| 752 } | 809 } |
| 753 | 810 |
| 754 static void test_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMC
olor expected) { | 811 static void test_image_color(skiatest::Reporter* reporter, SkImage* image, SkPMC
olor expected) { |
| 755 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | 812 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); |
| 756 SkPMColor pixel; | 813 SkPMColor pixel; |
| 757 REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0,
0)); | 814 REPORTER_ASSERT(reporter, image->readPixels(info, &pixel, sizeof(pixel), 0,
0)); |
| 758 REPORTER_ASSERT(reporter, pixel == expected); | 815 REPORTER_ASSERT(reporter, pixel == expected); |
| 759 } | 816 } |
| 760 | 817 |
| 761 DEF_GPUTEST(SkImage_NewFromTexture, reporter, factory) { | 818 DEF_GPUTEST(SkImage_NewFromTexture, reporter, factory) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 778 desc.fWidth = w; | 835 desc.fWidth = w; |
| 779 desc.fHeight = h; | 836 desc.fHeight = h; |
| 780 desc.fConfig = kSkia8888_GrPixelConfig; | 837 desc.fConfig = kSkia8888_GrPixelConfig; |
| 781 desc.fSampleCnt = 0; | 838 desc.fSampleCnt = 0; |
| 782 | 839 |
| 783 SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w
* 4)); | 840 SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w
* 4)); |
| 784 if (!tex) { | 841 if (!tex) { |
| 785 REPORTER_ASSERT(reporter, false); | 842 REPORTER_ASSERT(reporter, false); |
| 786 return; | 843 return; |
| 787 } | 844 } |
| 788 | 845 |
| 789 GrBackendObject srcTex = tex->getTextureHandle(); | 846 GrBackendObject srcTex = tex->getTextureHandle(); |
| 790 SkAutoTUnref<SkImage> refImg(make_desc_image(ctx, w, h, srcTex, false)); | 847 ReleaseTextureContext releaseCtx(reporter); |
| 791 SkAutoTUnref<SkImage> cpyImg(make_desc_image(ctx, w, h, srcTex, true)); | 848 |
| 849 SkAutoTUnref<SkImage> refImg(make_desc_image(ctx, w, h, srcTex, &releaseCtx)
); |
| 850 SkAutoTUnref<SkImage> cpyImg(make_desc_image(ctx, w, h, srcTex, NULL)); |
| 792 | 851 |
| 793 test_image_color(reporter, refImg, expected0); | 852 test_image_color(reporter, refImg, expected0); |
| 794 test_image_color(reporter, cpyImg, expected0); | 853 test_image_color(reporter, cpyImg, expected0); |
| 795 | 854 |
| 796 // Now lets jam new colors into our "external" texture, and see if the image
s notice | 855 // Now lets jam new colors into our "external" texture, and see if the image
s notice |
| 797 const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE); | 856 const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE); |
| 798 sk_memset32(storage, expected1, w * h); | 857 sk_memset32(storage, expected1, w * h); |
| 799 tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kF
lushWrites_PixelOp); | 858 tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kF
lushWrites_PixelOp); |
| 800 | 859 |
| 801 // We expect the ref'd image to see the new color, but cpy'd one should stil
l see the old color | 860 // We expect the ref'd image to see the new color, but cpy'd one should stil
l see the old color |
| 802 test_image_color(reporter, refImg, expected1); | 861 test_image_color(reporter, refImg, expected1); |
| 803 test_image_color(reporter, cpyImg, expected0); | 862 test_image_color(reporter, cpyImg, expected0); |
| 863 |
| 864 // Now exercise the release proc |
| 865 REPORTER_ASSERT(reporter, !releaseCtx.fIsReleased); |
| 866 refImg.reset(NULL); // force a release of the image |
| 867 REPORTER_ASSERT(reporter, releaseCtx.fIsReleased); |
| 804 } | 868 } |
| 805 #endif | 869 #endif |
| OLD | NEW |