1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/flow/raster_cache.h"
6
7#include "gtest/gtest.h"
8#include "third_party/skia/include/core/SkCanvas.h"
9#include "third_party/skia/include/core/SkPaint.h"
10#include "third_party/skia/include/core/SkPicture.h"
11#include "third_party/skia/include/core/SkPictureRecorder.h"
12
13namespace flutter {
14namespace testing {
15namespace {
16
17sk_sp<SkPicture> GetSamplePicture() {
18 SkPictureRecorder recorder;
19 recorder.beginRecording(SkRect::MakeWH(150, 100));
20 SkPaint paint;
21 paint.setColor(SK_ColorRED);
22 recorder.getRecordingCanvas()->drawRect(SkRect::MakeXYWH(10, 10, 80, 80),
23 paint);
24 return recorder.finishRecordingAsPicture();
25}
26
27} // namespace
28
29TEST(RasterCache, SimpleInitialization) {
30 flutter::RasterCache cache;
31 ASSERT_TRUE(true);
32}
33
34TEST(RasterCache, ThresholdIsRespected) {
35 size_t threshold = 2;
36 flutter::RasterCache cache(threshold);
37
38 SkMatrix matrix = SkMatrix::I();
39
40 auto picture = GetSamplePicture();
41
42 sk_sp<SkImage> image;
43
44 SkCanvas dummy_canvas;
45
46 sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
47 ASSERT_FALSE(
48 cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));
49 // 1st access.
50 ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
51
52 cache.SweepAfterFrame();
53
54 ASSERT_FALSE(
55 cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));
56
57 // 2nd access.
58 ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
59
60 cache.SweepAfterFrame();
61
62 // Now Prepare should cache it.
63 ASSERT_TRUE(
64 cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));
65 ASSERT_TRUE(cache.Draw(*picture, dummy_canvas));
66}
67
68TEST(RasterCache, AccessThresholdOfZeroDisablesCaching) {
69 size_t threshold = 0;
70 flutter::RasterCache cache(threshold);
71
72 SkMatrix matrix = SkMatrix::I();
73
74 auto picture = GetSamplePicture();
75
76 sk_sp<SkImage> image;
77
78 SkCanvas dummy_canvas;
79
80 sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
81 ASSERT_FALSE(
82 cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));
83
84 ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
85}
86
87TEST(RasterCache, PictureCacheLimitPerFrameIsRespectedWhenZero) {
88 size_t picture_cache_limit_per_frame = 0;
89 flutter::RasterCache cache(3, picture_cache_limit_per_frame);
90
91 SkMatrix matrix = SkMatrix::I();
92
93 auto picture = GetSamplePicture();
94
95 sk_sp<SkImage> image;
96
97 SkCanvas dummy_canvas;
98
99 sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
100 ASSERT_FALSE(
101 cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false));
102
103 ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
104}
105
106TEST(RasterCache, SweepsRemoveUnusedFrames) {
107 size_t threshold = 1;
108 flutter::RasterCache cache(threshold);
109
110 SkMatrix matrix = SkMatrix::I();
111
112 auto picture = GetSamplePicture();
113
114 sk_sp<SkImage> image;
115
116 SkCanvas dummy_canvas;
117
118 sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
119 ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true,
120 false)); // 1
121 ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
122
123 cache.SweepAfterFrame();
124
125 ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true,
126 false)); // 2
127 ASSERT_TRUE(cache.Draw(*picture, dummy_canvas));
128
129 cache.SweepAfterFrame();
130 cache.SweepAfterFrame(); // Extra frame without a Get image access.
131
132 ASSERT_FALSE(cache.Draw(*picture, dummy_canvas));
133}
134
135// Construct a cache result whose device target rectangle rounds out to be one
136// pixel wider than the cached image. Verify that it can be drawn without
137// triggering any assertions.
138TEST(RasterCache, DeviceRectRoundOut) {
139 size_t threshold = 1;
140 flutter::RasterCache cache(threshold);
141
142 SkPictureRecorder recorder;
143 SkRect logical_rect = SkRect::MakeLTRB(28, 0, 354.56731, 310.288);
144 recorder.beginRecording(logical_rect);
145 SkPaint paint;
146 paint.setColor(SK_ColorRED);
147 recorder.getRecordingCanvas()->drawRect(logical_rect, paint);
148 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
149
150 SkMatrix ctm = SkMatrix::MakeAll(1.3312, 0, 233, 0, 1.3312, 206, 0, 0, 1);
151
152 SkCanvas canvas(100, 100, nullptr);
153 canvas.setMatrix(ctm);
154
155 sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
156 ASSERT_FALSE(
157 cache.Prepare(NULL, picture.get(), ctm, srgb.get(), true, false));
158 ASSERT_FALSE(cache.Draw(*picture, canvas));
159 cache.SweepAfterFrame();
160 ASSERT_TRUE(cache.Prepare(NULL, picture.get(), ctm, srgb.get(), true, false));
161 ASSERT_TRUE(cache.Draw(*picture, canvas));
162
163 canvas.translate(248, 0);
164 ASSERT_TRUE(cache.Draw(*picture, canvas));
165}
166
167} // namespace testing
168} // namespace flutter
169