2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkPicture.h"
10 #include "include/core/SkPictureRecorder.h"
11 #include "include/core/SkShader.h"
12 #include "include/core/SkSurface.h"
13 #include "src/core/SkPicturePriv.h"
14 #include "src/core/SkResourceCache.h"
15 #include "src/shaders/SkPictureShader.h"
16 #include "tests/Test.h"
18 // Test that the SkPictureShader cache is purged on shader deletion.
19 DEF_TEST(PictureShader_caching, reporter) {
20 auto makePicture = [] () {
21 SkPictureRecorder recorder;
22 recorder.beginRecording(100, 100)->drawColor(SK_ColorGREEN);
23 return recorder.finishRecordingAsPicture();
26 sk_sp<SkPicture> picture = makePicture();
27 REPORTER_ASSERT(reporter, picture->unique());
29 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(100, 100);
33 paint.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
34 SkFilterMode::kNearest));
35 surface->getCanvas()->drawPaint(paint);
37 // We should have about 3 refs by now: local + shader + shader cache.
38 REPORTER_ASSERT(reporter, !picture->unique());
41 // Draw another picture shader to have a chance to purge.
44 paint.setShader(makePicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
45 SkFilterMode::kNearest));
46 surface->getCanvas()->drawPaint(paint);
50 // All but the local ref should be gone now.
51 REPORTER_ASSERT(reporter, picture->unique());
55 * Check caching of picture-shaders
56 * - we do cache the underlying image (i.e. there is a cache entry)
57 * - there is only 1 entry, even with differing tile modes
58 * - after deleting the picture, the cache entry is purged
60 DEF_TEST(PictureShader_caching2, reporter) {
62 SkPictureRecorder recorder;
63 recorder.beginRecording(100, 100)->drawColor(SK_ColorGREEN);
64 return recorder.finishRecordingAsPicture();
66 REPORTER_ASSERT(reporter, picture->unique());
72 SkPicturePriv::MakeSharedID(picture->uniqueID()),
76 auto counter = [](const SkResourceCache::Rec& rec, void* dataPtr) {
77 if (rec.getKey().getSharedID() == ((Data*)dataPtr)->sharedID) {
78 ((Data*)dataPtr)->counter += 1;
82 SkResourceCache::VisitAll(counter, &data);
83 REPORTER_ASSERT(reporter, data.counter == 0);
85 // Draw with a view variants of picture-shaders that all use the same picture.
86 // Only expect 1 cache entry for all (since same CTM for all).
87 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(100, 100);
89 SkTileMode::kClamp, SkTileMode::kRepeat, SkTileMode::kRepeat, SkTileMode::kDecal
92 paint.setShader(picture->makeShader(m, m, SkFilterMode::kNearest));
93 surface->getCanvas()->drawPaint(paint);
96 // Don't expect any additional refs on the picture
97 REPORTER_ASSERT(reporter, picture->unique());
99 // Check that we did cache something, but only 1 thing
101 SkResourceCache::VisitAll(counter, &data);
102 REPORTER_ASSERT(reporter, data.counter == 1);
104 // Now delete the picture, and check the we purge the cache entry
107 SkResourceCache::CheckMessages();
110 SkResourceCache::VisitAll(counter, &data);
111 REPORTER_ASSERT(reporter, data.counter == 0);