Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / tests / ImageFilterCacheTest.cpp
1  /*
2   * Copyright 2016 Google Inc.
3   *
4   * Use of this source code is governed by a BSD-style license that can be
5   * found in the LICENSE file.
6   */
7
8 #include "tests/Test.h"
9
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkColorFilter.h"
12 #include "include/core/SkImage.h"
13 #include "include/core/SkImageFilter.h"
14 #include "include/core/SkMatrix.h"
15 #include "include/effects/SkImageFilters.h"
16 #include "src/core/SkImageFilterCache.h"
17 #include "src/core/SkSpecialImage.h"
18
19 static const int kSmallerSize = 10;
20 static const int kPad = 3;
21 static const int kFullSize = kSmallerSize + 2 * kPad;
22
23 static SkBitmap create_bm() {
24     SkImageInfo ii = SkImageInfo::Make(kFullSize, kFullSize, kRGBA_8888_SkColorType,
25                                        kPremul_SkAlphaType);
26
27     SkBitmap bm;
28     bm.allocPixels(ii);
29     bm.eraseColor(SK_ColorTRANSPARENT);
30     bm.setImmutable();
31     return bm;
32 }
33
34 static sk_sp<SkImageFilter> make_filter() {
35     sk_sp<SkColorFilter> filter(SkColorFilters::Blend(SK_ColorBLUE, SkBlendMode::kSrcIn));
36     return SkImageFilters::ColorFilter(std::move(filter), nullptr, nullptr);
37 }
38
39 // Ensure the cache can return a cached image
40 static void test_find_existing(skiatest::Reporter* reporter,
41                                const sk_sp<SkSpecialImage>& image,
42                                const sk_sp<SkSpecialImage>& subset) {
43     static const size_t kCacheSize = 1000000;
44     sk_sp<SkImageFilterCache> cache(SkImageFilterCache::Create(kCacheSize));
45
46     SkIRect clip = SkIRect::MakeWH(100, 100);
47     SkImageFilterCacheKey key1(0, SkMatrix::I(), clip, image->uniqueID(), image->subset());
48     SkImageFilterCacheKey key2(0, SkMatrix::I(), clip, subset->uniqueID(), subset->subset());
49
50     SkIPoint offset = SkIPoint::Make(3, 4);
51     auto filter = make_filter();
52     cache->set(key1, filter.get(), skif::FilterResult(image, skif::LayerSpace<SkIPoint>(offset)));
53
54     skif::FilterResult foundImage;
55     REPORTER_ASSERT(reporter, cache->get(key1, &foundImage));
56     REPORTER_ASSERT(reporter, offset == SkIPoint(foundImage.layerOrigin()));
57
58     REPORTER_ASSERT(reporter, !cache->get(key2, &foundImage));
59 }
60
61 // If either id is different or the clip or the matrix are different the
62 // cached image won't be found. Even if it is caching the same bitmap.
63 static void test_dont_find_if_diff_key(skiatest::Reporter* reporter,
64                                        const sk_sp<SkSpecialImage>& image,
65                                        const sk_sp<SkSpecialImage>& subset) {
66     static const size_t kCacheSize = 1000000;
67     sk_sp<SkImageFilterCache> cache(SkImageFilterCache::Create(kCacheSize));
68
69     SkIRect clip1 = SkIRect::MakeWH(100, 100);
70     SkIRect clip2 = SkIRect::MakeWH(200, 200);
71     SkImageFilterCacheKey key0(0, SkMatrix::I(), clip1, image->uniqueID(), image->subset());
72     SkImageFilterCacheKey key1(1, SkMatrix::I(), clip1, image->uniqueID(), image->subset());
73     SkImageFilterCacheKey key2(0, SkMatrix::Translate(5, 5), clip1,
74                                    image->uniqueID(), image->subset());
75     SkImageFilterCacheKey key3(0, SkMatrix::I(), clip2, image->uniqueID(), image->subset());
76     SkImageFilterCacheKey key4(0, SkMatrix::I(), clip1, subset->uniqueID(), subset->subset());
77
78     SkIPoint offset = SkIPoint::Make(3, 4);
79     auto filter = make_filter();
80     cache->set(key0, filter.get(), skif::FilterResult(image, skif::LayerSpace<SkIPoint>(offset)));
81
82     skif::FilterResult foundImage;
83     REPORTER_ASSERT(reporter, !cache->get(key1, &foundImage));
84     REPORTER_ASSERT(reporter, !cache->get(key2, &foundImage));
85     REPORTER_ASSERT(reporter, !cache->get(key3, &foundImage));
86     REPORTER_ASSERT(reporter, !cache->get(key4, &foundImage));
87 }
88
89 // Test purging when the max cache size is exceeded
90 static void test_internal_purge(skiatest::Reporter* reporter, const sk_sp<SkSpecialImage>& image) {
91     SkASSERT(image->getSize());
92     const size_t kCacheSize = image->getSize() + 10;
93     sk_sp<SkImageFilterCache> cache(SkImageFilterCache::Create(kCacheSize));
94
95     SkIRect clip = SkIRect::MakeWH(100, 100);
96     SkImageFilterCacheKey key1(0, SkMatrix::I(), clip, image->uniqueID(), image->subset());
97     SkImageFilterCacheKey key2(1, SkMatrix::I(), clip, image->uniqueID(), image->subset());
98
99     SkIPoint offset = SkIPoint::Make(3, 4);
100     auto filter1 = make_filter();
101     cache->set(key1, filter1.get(), skif::FilterResult(image, skif::LayerSpace<SkIPoint>(offset)));
102
103     skif::FilterResult foundImage;
104     REPORTER_ASSERT(reporter, cache->get(key1, &foundImage));
105
106     // This should knock the first one out of the cache
107     auto filter2 = make_filter();
108     cache->set(key2, filter2.get(),
109                skif::FilterResult(image, skif::LayerSpace<SkIPoint>(offset)));
110
111     REPORTER_ASSERT(reporter, cache->get(key2, &foundImage));
112     REPORTER_ASSERT(reporter, !cache->get(key1, &foundImage));
113 }
114
115 // Exercise the purgeByKey and purge methods
116 static void test_explicit_purging(skiatest::Reporter* reporter,
117                                   const sk_sp<SkSpecialImage>& image,
118                                   const sk_sp<SkSpecialImage>& subset) {
119     static const size_t kCacheSize = 1000000;
120     sk_sp<SkImageFilterCache> cache(SkImageFilterCache::Create(kCacheSize));
121
122     SkIRect clip = SkIRect::MakeWH(100, 100);
123     SkImageFilterCacheKey key1(0, SkMatrix::I(), clip, image->uniqueID(), image->subset());
124     SkImageFilterCacheKey key2(1, SkMatrix::I(), clip, subset->uniqueID(), image->subset());
125
126     SkIPoint offset = SkIPoint::Make(3, 4);
127     auto filter1 = make_filter();
128     auto filter2 = make_filter();
129     cache->set(key1, filter1.get(),
130                skif::FilterResult(image, skif::LayerSpace<SkIPoint>(offset)));
131     cache->set(key2, filter2.get(),
132                skif::FilterResult(image, skif::LayerSpace<SkIPoint>(offset)));
133     SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->count());)
134
135     skif::FilterResult foundImage;
136     REPORTER_ASSERT(reporter, cache->get(key1, &foundImage));
137     REPORTER_ASSERT(reporter, cache->get(key2, &foundImage));
138
139     cache->purgeByImageFilter(filter1.get());
140     SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->count());)
141
142     REPORTER_ASSERT(reporter, !cache->get(key1, &foundImage));
143     REPORTER_ASSERT(reporter, cache->get(key2, &foundImage));
144
145     cache->purge();
146     SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->count());)
147
148     REPORTER_ASSERT(reporter, !cache->get(key1, &foundImage));
149     REPORTER_ASSERT(reporter, !cache->get(key2, &foundImage));
150 }
151
152 DEF_TEST(ImageFilterCache_RasterBacked, reporter) {
153     SkBitmap srcBM = create_bm();
154
155     const SkIRect& full = SkIRect::MakeWH(kFullSize, kFullSize);
156
157     sk_sp<SkSpecialImage> fullImg(SkSpecialImage::MakeFromRaster(full, srcBM, SkSurfaceProps()));
158
159     const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
160
161     sk_sp<SkSpecialImage> subsetImg(SkSpecialImage::MakeFromRaster(subset, srcBM,
162                                                                    SkSurfaceProps()));
163
164     test_find_existing(reporter, fullImg, subsetImg);
165     test_dont_find_if_diff_key(reporter, fullImg, subsetImg);
166     test_internal_purge(reporter, fullImg);
167     test_explicit_purging(reporter, fullImg, subsetImg);
168 }
169
170
171 // Shared test code for both the raster and gpu-backed image cases
172 static void test_image_backed(skiatest::Reporter* reporter,
173                               GrRecordingContext* rContext,
174                               const sk_sp<SkImage>& srcImage) {
175     const SkIRect& full = SkIRect::MakeWH(kFullSize, kFullSize);
176
177     sk_sp<SkSpecialImage> fullImg(SkSpecialImage::MakeFromImage(rContext, full, srcImage,
178                                                                 SkSurfaceProps()));
179
180     const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
181
182     sk_sp<SkSpecialImage> subsetImg(SkSpecialImage::MakeFromImage(rContext, subset, srcImage,
183                                                                   SkSurfaceProps()));
184
185     test_find_existing(reporter, fullImg, subsetImg);
186     test_dont_find_if_diff_key(reporter, fullImg, subsetImg);
187     test_internal_purge(reporter, fullImg);
188     test_explicit_purging(reporter, fullImg, subsetImg);
189 }
190
191 DEF_TEST(ImageFilterCache_ImageBackedRaster, reporter) {
192     SkBitmap srcBM = create_bm();
193
194     sk_sp<SkImage> srcImage(srcBM.asImage());
195
196     test_image_backed(reporter, nullptr, srcImage);
197 }
198
199 #include "include/gpu/GrDirectContext.h"
200 #include "src/gpu/ganesh/GrDirectContextPriv.h"
201 #include "src/gpu/ganesh/GrProxyProvider.h"
202 #include "src/gpu/ganesh/GrResourceProvider.h"
203 #include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
204 #include "src/gpu/ganesh/GrTexture.h"
205 #include "src/gpu/ganesh/GrTextureProxy.h"
206 #include "src/gpu/ganesh/SkGr.h"
207
208 static GrSurfaceProxyView create_proxy_view(GrRecordingContext* rContext) {
209     SkBitmap srcBM = create_bm();
210     return std::get<0>(GrMakeUncachedBitmapProxyView(rContext, srcBM));
211 }
212
213 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ctxInfo) {
214     auto dContext = ctxInfo.directContext();
215
216     GrSurfaceProxyView srcView = create_proxy_view(dContext);
217     if (!srcView.proxy()) {
218         return;
219     }
220
221     if (!srcView.proxy()->instantiate(dContext->priv().resourceProvider())) {
222         return;
223     }
224     GrTexture* tex = srcView.proxy()->peekTexture();
225
226     GrBackendTexture backendTex = tex->getBackendTexture();
227
228     GrSurfaceOrigin texOrigin = kTopLeft_GrSurfaceOrigin;
229     sk_sp<SkImage> srcImage(SkImage::MakeFromTexture(dContext,
230                                                      backendTex,
231                                                      texOrigin,
232                                                      kRGBA_8888_SkColorType,
233                                                      kPremul_SkAlphaType, nullptr,
234                                                      nullptr, nullptr));
235     if (!srcImage) {
236         return;
237     }
238
239     GrSurfaceOrigin readBackOrigin;
240     GrBackendTexture readBackBackendTex = srcImage->getBackendTexture(false, &readBackOrigin);
241     if (!GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex)) {
242         ERRORF(reporter, "backend mismatch\n");
243     }
244     REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex));
245
246     if (readBackOrigin != texOrigin) {
247         ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
248     }
249     REPORTER_ASSERT(reporter, readBackOrigin == texOrigin);
250
251     test_image_backed(reporter, dContext, srcImage);
252 }
253
254 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_GPUBacked, reporter, ctxInfo) {
255     auto dContext = ctxInfo.directContext();
256
257     GrSurfaceProxyView srcView = create_proxy_view(dContext);
258     if (!srcView.proxy()) {
259         return;
260     }
261
262     const SkIRect& full = SkIRect::MakeWH(kFullSize, kFullSize);
263
264     sk_sp<SkSpecialImage> fullImg(SkSpecialImage::MakeDeferredFromGpu(
265                                                               dContext, full,
266                                                               kNeedNewImageUniqueID_SpecialImage,
267                                                               srcView,
268                                                               GrColorType::kRGBA_8888, nullptr,
269                                                               SkSurfaceProps()));
270
271     const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
272
273     sk_sp<SkSpecialImage> subsetImg(SkSpecialImage::MakeDeferredFromGpu(
274                                                                 dContext, subset,
275                                                                 kNeedNewImageUniqueID_SpecialImage,
276                                                                 std::move(srcView),
277                                                                 GrColorType::kRGBA_8888, nullptr,
278                                                                 SkSurfaceProps()));
279
280     test_find_existing(reporter, fullImg, subsetImg);
281     test_dont_find_if_diff_key(reporter, fullImg, subsetImg);
282     test_internal_purge(reporter, fullImg);
283     test_explicit_purging(reporter, fullImg, subsetImg);
284 }