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 | |
13 | namespace flutter { |
14 | namespace testing { |
15 | namespace { |
16 | |
17 | sk_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 | |
29 | TEST(RasterCache, SimpleInitialization) { |
30 | flutter::RasterCache cache; |
31 | ASSERT_TRUE(true); |
32 | } |
33 | |
34 | TEST(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 | |
68 | TEST(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 | |
87 | TEST(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 | |
106 | TEST(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. |
138 | TEST(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 | |