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