| 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 "SkImageEncoder.h" | 10 #include "SkImageEncoder.h" |
| 11 #include "SkRRect.h" | 11 #include "SkRRect.h" |
| 12 #include "SkSurface.h" | 12 #include "SkSurface.h" |
| 13 #include "SkUtils.h" | 13 #include "SkUtils.h" |
| 14 #include "Test.h" | 14 #include "Test.h" |
| 15 | 15 |
| 16 #if SK_SUPPORT_GPU | 16 #if SK_SUPPORT_GPU |
| 17 #include "GrContextFactory.h" | 17 #include "GrContextFactory.h" |
| 18 #else | 18 #else |
| 19 class GrContextFactory; | 19 class GrContextFactory; |
| 20 class GrContext; | 20 class GrContext; |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 enum SurfaceType { | 23 enum SurfaceType { |
| 24 kRaster_SurfaceType, | 24 kRaster_SurfaceType, |
| 25 kRasterDirect_SurfaceType, | 25 kRasterDirect_SurfaceType, |
| 26 kGpu_SurfaceType, | 26 kGpu_SurfaceType, |
| 27 kGpuScratch_SurfaceType, |
| 27 kPicture_SurfaceType | 28 kPicture_SurfaceType |
| 28 }; | 29 }; |
| 29 | 30 |
| 30 static const int gSurfaceSize = 10; | 31 static const int gSurfaceSize = 10; |
| 31 static SkPMColor gSurfaceStorage[gSurfaceSize * gSurfaceSize]; | 32 static SkPMColor gSurfaceStorage[gSurfaceSize * gSurfaceSize]; |
| 32 | 33 |
| 33 static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context, | 34 static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context, |
| 34 SkImageInfo* requestedInfo = NULL) { | 35 SkImageInfo* requestedInfo = NULL) { |
| 35 static const SkImageInfo info = SkImageInfo::MakeN32Premul(gSurfaceSize, | 36 static const SkImageInfo info = SkImageInfo::MakeN32Premul(gSurfaceSize, |
| 36 gSurfaceSize); | 37 gSurfaceSize); |
| 37 | 38 |
| 38 if (requestedInfo) { | 39 if (requestedInfo) { |
| 39 *requestedInfo = info; | 40 *requestedInfo = info; |
| 40 } | 41 } |
| 41 | 42 |
| 42 switch (surfaceType) { | 43 switch (surfaceType) { |
| 43 case kRaster_SurfaceType: | 44 case kRaster_SurfaceType: |
| 44 return SkSurface::NewRaster(info); | 45 return SkSurface::NewRaster(info); |
| 45 case kRasterDirect_SurfaceType: | 46 case kRasterDirect_SurfaceType: |
| 46 return SkSurface::NewRasterDirect(info, gSurfaceStorage, | 47 return SkSurface::NewRasterDirect(info, gSurfaceStorage, |
| 47 info.minRowBytes()); | 48 info.minRowBytes()); |
| 48 case kGpu_SurfaceType: | 49 case kGpu_SurfaceType: |
| 49 #if SK_SUPPORT_GPU | 50 #if SK_SUPPORT_GPU |
| 50 return context ? SkSurface::NewRenderTarget(context, info) : NULL; | 51 return context ? SkSurface::NewRenderTarget(context, info) : NULL; |
| 51 #endif | 52 #endif |
| 52 break; | 53 break; |
| 54 case kGpuScratch_SurfaceType: |
| 55 #if SK_SUPPORT_GPU |
| 56 return context ? SkSurface::NewScratchRenderTarget(context, info) :
NULL; |
| 57 #endif |
| 58 break; |
| 53 case kPicture_SurfaceType: | 59 case kPicture_SurfaceType: |
| 54 return SkSurface::NewPicture(info.fWidth, info.fHeight); | 60 return SkSurface::NewPicture(info.fWidth, info.fHeight); |
| 55 } | 61 } |
| 56 return NULL; | 62 return NULL; |
| 57 } | 63 } |
| 58 | 64 |
| 59 enum ImageType { | 65 enum ImageType { |
| 60 kRasterCopy_ImageType, | 66 kRasterCopy_ImageType, |
| 61 kRasterData_ImageType, | 67 kRasterData_ImageType, |
| 62 kGpu_ImageType, | 68 kGpu_ImageType, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 return NULL; | 122 return NULL; |
| 117 } | 123 } |
| 118 | 124 |
| 119 static void test_imagepeek(skiatest::Reporter* reporter) { | 125 static void test_imagepeek(skiatest::Reporter* reporter) { |
| 120 static const struct { | 126 static const struct { |
| 121 ImageType fType; | 127 ImageType fType; |
| 122 bool fPeekShouldSucceed; | 128 bool fPeekShouldSucceed; |
| 123 } gRec[] = { | 129 } gRec[] = { |
| 124 { kRasterCopy_ImageType, true }, | 130 { kRasterCopy_ImageType, true }, |
| 125 { kRasterData_ImageType, true }, | 131 { kRasterData_ImageType, true }, |
| 126 { kGpu_ImageType, false }, | 132 { kGpu_ImageType, false }, |
| 127 { kPicture_ImageType, false }, | 133 { kPicture_ImageType, false }, |
| 128 { kCodec_ImageType, false }, | 134 { kCodec_ImageType, false }, |
| 129 }; | 135 }; |
| 130 | 136 |
| 131 const SkColor color = SK_ColorRED; | 137 const SkColor color = SK_ColorRED; |
| 132 const SkPMColor pmcolor = SkPreMultiplyColor(color); | 138 const SkPMColor pmcolor = SkPreMultiplyColor(color); |
| 133 | 139 |
| 134 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 140 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { |
| 135 SkImageInfo info; | 141 SkImageInfo info; |
| 136 size_t rowBytes; | 142 size_t rowBytes; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 157 static void test_canvaspeek(skiatest::Reporter* reporter, | 163 static void test_canvaspeek(skiatest::Reporter* reporter, |
| 158 GrContextFactory* factory) { | 164 GrContextFactory* factory) { |
| 159 static const struct { | 165 static const struct { |
| 160 SurfaceType fType; | 166 SurfaceType fType; |
| 161 bool fPeekShouldSucceed; | 167 bool fPeekShouldSucceed; |
| 162 } gRec[] = { | 168 } gRec[] = { |
| 163 { kRaster_SurfaceType, true }, | 169 { kRaster_SurfaceType, true }, |
| 164 { kRasterDirect_SurfaceType, true }, | 170 { kRasterDirect_SurfaceType, true }, |
| 165 #if SK_SUPPORT_GPU | 171 #if SK_SUPPORT_GPU |
| 166 { kGpu_SurfaceType, false }, | 172 { kGpu_SurfaceType, false }, |
| 173 { kGpuScratch_SurfaceType, false }, |
| 167 #endif | 174 #endif |
| 168 { kPicture_SurfaceType, false }, | 175 { kPicture_SurfaceType, false }, |
| 169 }; | 176 }; |
| 170 | 177 |
| 171 const SkColor color = SK_ColorRED; | 178 const SkColor color = SK_ColorRED; |
| 172 const SkPMColor pmcolor = SkPreMultiplyColor(color); | 179 const SkPMColor pmcolor = SkPreMultiplyColor(color); |
| 173 | 180 |
| 174 GrContext* context = NULL; | 181 GrContext* context = NULL; |
| 175 #if SK_SUPPORT_GPU | 182 #if SK_SUPPORT_GPU |
| 176 context = factory->get(GrContextFactory::kNative_GLContextType); | 183 context = factory->get(GrContextFactory::kNative_GLContextType); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 // The test verifies that the surface remains writable (usable) after | 305 // The test verifies that the surface remains writable (usable) after |
| 299 // acquiring and releasing a snapshot without triggering a copy on write. | 306 // acquiring and releasing a snapshot without triggering a copy on write. |
| 300 SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context)); | 307 SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context)); |
| 301 SkCanvas* canvas = surface->getCanvas(); | 308 SkCanvas* canvas = surface->getCanvas(); |
| 302 canvas->clear(1); | 309 canvas->clear(1); |
| 303 surface->newImageSnapshot()->unref(); // Create and destroy SkImage | 310 surface->newImageSnapshot()->unref(); // Create and destroy SkImage |
| 304 canvas->clear(2); // Must not assert internally | 311 canvas->clear(2); // Must not assert internally |
| 305 } | 312 } |
| 306 | 313 |
| 307 #if SK_SUPPORT_GPU | 314 #if SK_SUPPORT_GPU |
| 315 static void TestSurfaceInCache(skiatest::Reporter* reporter, |
| 316 SurfaceType surfaceType, |
| 317 GrContext* context) { |
| 318 context->freeGpuResources(); |
| 319 REPORTER_ASSERT(reporter, 0 == context->getGpuTextureCacheResourceCount()); |
| 320 SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context)); |
| 321 // Note: the stencil buffer is always cached, so kGpu_SurfaceType uses |
| 322 // one cached resource, and kGpuScratch_SurfaceType uses two. |
| 323 int expectedCachedResources = surfaceType == kGpuScratch_SurfaceType ? 2 : 1
; |
| 324 REPORTER_ASSERT(reporter, expectedCachedResources == context->getGpuTextureC
acheResourceCount()); |
| 325 |
| 326 // Verify that all the cached resources are locked in cache. |
| 327 context->freeGpuResources(); |
| 328 REPORTER_ASSERT(reporter, expectedCachedResources == context->getGpuTextureC
acheResourceCount()); |
| 329 |
| 330 // Verify that all the cached resources are unlocked upon surface release |
| 331 surface.reset(0); |
| 332 context->freeGpuResources(); |
| 333 REPORTER_ASSERT(reporter, 0 == context->getGpuTextureCacheResourceCount()); |
| 334 } |
| 335 |
| 308 static void Test_crbug263329(skiatest::Reporter* reporter, | 336 static void Test_crbug263329(skiatest::Reporter* reporter, |
| 337 SurfaceType surfaceType, |
| 309 GrContext* context) { | 338 GrContext* context) { |
| 310 // This is a regression test for crbug.com/263329 | 339 // This is a regression test for crbug.com/263329 |
| 311 // Bug was caused by onCopyOnWrite releasing the old surface texture | 340 // Bug was caused by onCopyOnWrite releasing the old surface texture |
| 312 // back to the scratch texture pool even though the texture is used | 341 // back to the scratch texture pool even though the texture is used |
| 313 // by and active SkImage_Gpu. | 342 // by and active SkImage_Gpu. |
| 314 SkAutoTUnref<SkSurface> surface1(createSurface(kGpu_SurfaceType, context)); | 343 SkAutoTUnref<SkSurface> surface1(createSurface(surfaceType, context)); |
| 315 SkAutoTUnref<SkSurface> surface2(createSurface(kGpu_SurfaceType, context)); | 344 SkAutoTUnref<SkSurface> surface2(createSurface(surfaceType, context)); |
| 316 SkCanvas* canvas1 = surface1->getCanvas(); | 345 SkCanvas* canvas1 = surface1->getCanvas(); |
| 317 SkCanvas* canvas2 = surface2->getCanvas(); | 346 SkCanvas* canvas2 = surface2->getCanvas(); |
| 318 canvas1->clear(1); | 347 canvas1->clear(1); |
| 319 SkAutoTUnref<SkImage> image1(surface1->newImageSnapshot()); | 348 SkAutoTUnref<SkImage> image1(surface1->newImageSnapshot()); |
| 320 // Trigger copy on write, new backing is a scratch texture | 349 // Trigger copy on write, new backing is a scratch texture |
| 321 canvas1->clear(2); | 350 canvas1->clear(2); |
| 322 SkAutoTUnref<SkImage> image2(surface1->newImageSnapshot()); | 351 SkAutoTUnref<SkImage> image2(surface1->newImageSnapshot()); |
| 323 // Trigger copy on write, old backing should not be returned to scratch | 352 // Trigger copy on write, old backing should not be returned to scratch |
| 324 // pool because it is held by image2 | 353 // pool because it is held by image2 |
| 325 canvas1->clear(3); | 354 canvas1->clear(3); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 338 REPORTER_ASSERT(reporter, image3->getTexture() != image1->getTexture()); | 367 REPORTER_ASSERT(reporter, image3->getTexture() != image1->getTexture()); |
| 339 REPORTER_ASSERT(reporter, image2->getTexture() != image1->getTexture()); | 368 REPORTER_ASSERT(reporter, image2->getTexture() != image1->getTexture()); |
| 340 } | 369 } |
| 341 | 370 |
| 342 static void TestGetTexture(skiatest::Reporter* reporter, | 371 static void TestGetTexture(skiatest::Reporter* reporter, |
| 343 SurfaceType surfaceType, | 372 SurfaceType surfaceType, |
| 344 GrContext* context) { | 373 GrContext* context) { |
| 345 SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context)); | 374 SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context)); |
| 346 SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); | 375 SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); |
| 347 GrTexture* texture = image->getTexture(); | 376 GrTexture* texture = image->getTexture(); |
| 348 if (surfaceType == kGpu_SurfaceType) { | 377 if (surfaceType == kGpu_SurfaceType || surfaceType == kGpuScratch_SurfaceTyp
e) { |
| 349 REPORTER_ASSERT(reporter, NULL != texture); | 378 REPORTER_ASSERT(reporter, NULL != texture); |
| 350 REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle()); | 379 REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle()); |
| 351 } else { | 380 } else { |
| 352 REPORTER_ASSERT(reporter, NULL == texture); | 381 REPORTER_ASSERT(reporter, NULL == texture); |
| 353 } | 382 } |
| 354 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); | 383 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); |
| 355 REPORTER_ASSERT(reporter, image->getTexture() == texture); | 384 REPORTER_ASSERT(reporter, image->getTexture() == texture); |
| 356 } | 385 } |
| 357 #endif | 386 #endif |
| 358 | 387 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 | 429 |
| 401 test_imagepeek(reporter); | 430 test_imagepeek(reporter); |
| 402 test_canvaspeek(reporter, factory); | 431 test_canvaspeek(reporter, factory); |
| 403 | 432 |
| 404 #if SK_SUPPORT_GPU | 433 #if SK_SUPPORT_GPU |
| 405 TestGetTexture(reporter, kRaster_SurfaceType, NULL); | 434 TestGetTexture(reporter, kRaster_SurfaceType, NULL); |
| 406 TestGetTexture(reporter, kPicture_SurfaceType, NULL); | 435 TestGetTexture(reporter, kPicture_SurfaceType, NULL); |
| 407 if (NULL != factory) { | 436 if (NULL != factory) { |
| 408 GrContext* context = factory->get(GrContextFactory::kNative_GLContextTyp
e); | 437 GrContext* context = factory->get(GrContextFactory::kNative_GLContextTyp
e); |
| 409 if (NULL != context) { | 438 if (NULL != context) { |
| 410 Test_crbug263329(reporter, context); | 439 TestSurfaceInCache(reporter, kGpu_SurfaceType, context); |
| 440 TestSurfaceInCache(reporter, kGpuScratch_SurfaceType, context); |
| 441 Test_crbug263329(reporter, kGpu_SurfaceType, context); |
| 442 Test_crbug263329(reporter, kGpuScratch_SurfaceType, context); |
| 411 TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context); | 443 TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context); |
| 444 TestSurfaceCopyOnWrite(reporter, kGpuScratch_SurfaceType, context); |
| 412 TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType,
context); | 445 TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType,
context); |
| 446 TestSurfaceWritableAfterSnapshotRelease(reporter, kGpuScratch_Surfac
eType, context); |
| 413 TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::
kDiscard_ContentChangeMode); | 447 TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::
kDiscard_ContentChangeMode); |
| 448 TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSu
rface::kDiscard_ContentChangeMode); |
| 414 TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::
kRetain_ContentChangeMode); | 449 TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::
kRetain_ContentChangeMode); |
| 450 TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSu
rface::kRetain_ContentChangeMode); |
| 415 TestGetTexture(reporter, kGpu_SurfaceType, context); | 451 TestGetTexture(reporter, kGpu_SurfaceType, context); |
| 452 TestGetTexture(reporter, kGpuScratch_SurfaceType, context); |
| 416 } | 453 } |
| 417 } | 454 } |
| 418 #endif | 455 #endif |
| 419 } | 456 } |
| OLD | NEW |