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 |