OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "Test.h" | 8 #include "Test.h" |
9 #include "RecordTestUtils.h" | 9 #include "RecordTestUtils.h" |
10 | 10 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 } | 100 } |
101 } | 101 } |
102 | 102 |
103 static void assert_savelayer_restore(skiatest::Reporter* r, | 103 static void assert_savelayer_restore(skiatest::Reporter* r, |
104 SkRecord* record, | 104 SkRecord* record, |
105 int i, | 105 int i, |
106 bool shouldBeNoOped) { | 106 bool shouldBeNoOped) { |
107 SkRecordNoopSaveLayerDrawRestores(record); | 107 SkRecordNoopSaveLayerDrawRestores(record); |
108 if (shouldBeNoOped) { | 108 if (shouldBeNoOped) { |
109 assert_type<SkRecords::NoOp>(r, *record, i); | 109 assert_type<SkRecords::NoOp>(r, *record, i); |
| 110 assert_type<SkRecords::NoOp>(r, *record, i+1); |
| 111 } else { |
| 112 assert_type<SkRecords::SaveLayer>(r, *record, i); |
| 113 assert_type<SkRecords::Restore>(r, *record, i+1); |
| 114 } |
| 115 } |
| 116 |
| 117 static void assert_savelayer_draw_restore(skiatest::Reporter* r, |
| 118 SkRecord* record, |
| 119 int i, |
| 120 bool shouldBeNoOped) { |
| 121 SkRecordNoopSaveLayerDrawRestores(record); |
| 122 if (shouldBeNoOped) { |
| 123 assert_type<SkRecords::NoOp>(r, *record, i); |
110 assert_type<SkRecords::NoOp>(r, *record, i+2); | 124 assert_type<SkRecords::NoOp>(r, *record, i+2); |
111 } else { | 125 } else { |
112 assert_type<SkRecords::SaveLayer>(r, *record, i); | 126 assert_type<SkRecords::SaveLayer>(r, *record, i); |
113 assert_type<SkRecords::Restore>(r, *record, i+2); | 127 assert_type<SkRecords::Restore>(r, *record, i+2); |
114 } | 128 } |
115 } | 129 } |
116 | 130 |
| 131 #include "SkBlurImageFilter.h" |
117 DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) { | 132 DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) { |
118 SkRecord record; | 133 SkRecord record; |
119 SkRecorder recorder(&record, W, H); | 134 SkRecorder recorder(&record, W, H); |
120 | 135 |
121 SkRect bounds = SkRect::MakeWH(100, 200); | 136 SkRect bounds = SkRect::MakeWH(100, 200); |
122 SkRect draw = SkRect::MakeWH(50, 60); | 137 SkRect draw = SkRect::MakeWH(50, 60); |
123 | 138 |
124 SkPaint alphaOnlyLayerPaint, translucentLayerPaint, xfermodeLayerPaint; | 139 SkPaint alphaOnlyLayerPaint, translucentLayerPaint, xfermodeLayerPaint; |
125 alphaOnlyLayerPaint.setColor(0x03000000); // Only alpha. | 140 alphaOnlyLayerPaint.setColor(0x03000000); // Only alpha. |
126 translucentLayerPaint.setColor(0x03040506); // Not only alpha. | 141 translucentLayerPaint.setColor(0x03040506); // Not only alpha. |
127 xfermodeLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode); // Any effect
will do. | 142 xfermodeLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode); // Any effect
will do. |
128 | 143 |
129 SkPaint opaqueDrawPaint, translucentDrawPaint; | 144 SkPaint opaqueDrawPaint, translucentDrawPaint; |
130 opaqueDrawPaint.setColor(0xFF020202); // Opaque. | 145 opaqueDrawPaint.setColor(0xFF020202); // Opaque. |
131 translucentDrawPaint.setColor(0x0F020202); // Not opaque. | 146 translucentDrawPaint.setColor(0x0F020202); // Not opaque. |
132 | 147 |
133 // SaveLayer/Restore removed: No paint = no point. | 148 // SaveLayer/Restore removed: No paint = no point. |
134 recorder.saveLayer(nullptr, nullptr); | 149 recorder.saveLayer(nullptr, nullptr); |
135 recorder.drawRect(draw, opaqueDrawPaint); | 150 recorder.drawRect(draw, opaqueDrawPaint); |
136 recorder.restore(); | 151 recorder.restore(); |
137 assert_savelayer_restore(r, &record, 0, true); | 152 assert_savelayer_draw_restore(r, &record, 0, true); |
138 | 153 |
139 // Bounds don't matter. | 154 // Bounds don't matter. |
140 recorder.saveLayer(&bounds, nullptr); | 155 recorder.saveLayer(&bounds, nullptr); |
141 recorder.drawRect(draw, opaqueDrawPaint); | 156 recorder.drawRect(draw, opaqueDrawPaint); |
142 recorder.restore(); | 157 recorder.restore(); |
143 assert_savelayer_restore(r, &record, 3, true); | 158 assert_savelayer_draw_restore(r, &record, 3, true); |
144 | 159 |
145 // TODO(mtklein): test case with null draw paint | 160 // TODO(mtklein): test case with null draw paint |
146 | 161 |
147 // No change: layer paint isn't alpha-only. | 162 // No change: layer paint isn't alpha-only. |
148 recorder.saveLayer(nullptr, &translucentLayerPaint); | 163 recorder.saveLayer(nullptr, &translucentLayerPaint); |
149 recorder.drawRect(draw, opaqueDrawPaint); | 164 recorder.drawRect(draw, opaqueDrawPaint); |
150 recorder.restore(); | 165 recorder.restore(); |
151 assert_savelayer_restore(r, &record, 6, false); | 166 assert_savelayer_draw_restore(r, &record, 6, false); |
152 | 167 |
153 // No change: layer paint has an effect. | 168 // No change: layer paint has an effect. |
154 recorder.saveLayer(nullptr, &xfermodeLayerPaint); | 169 recorder.saveLayer(nullptr, &xfermodeLayerPaint); |
155 recorder.drawRect(draw, opaqueDrawPaint); | 170 recorder.drawRect(draw, opaqueDrawPaint); |
156 recorder.restore(); | 171 recorder.restore(); |
157 assert_savelayer_restore(r, &record, 9, false); | 172 assert_savelayer_draw_restore(r, &record, 9, false); |
158 | 173 |
159 // SaveLayer/Restore removed: we can fold in the alpha! | 174 // SaveLayer/Restore removed: we can fold in the alpha! |
160 recorder.saveLayer(nullptr, &alphaOnlyLayerPaint); | 175 recorder.saveLayer(nullptr, &alphaOnlyLayerPaint); |
161 recorder.drawRect(draw, translucentDrawPaint); | 176 recorder.drawRect(draw, translucentDrawPaint); |
162 recorder.restore(); | 177 recorder.restore(); |
163 assert_savelayer_restore(r, &record, 12, true); | 178 assert_savelayer_draw_restore(r, &record, 12, true); |
164 | 179 |
165 // SaveLayer/Restore removed: we can fold in the alpha! | 180 // SaveLayer/Restore removed: we can fold in the alpha! |
166 recorder.saveLayer(nullptr, &alphaOnlyLayerPaint); | 181 recorder.saveLayer(nullptr, &alphaOnlyLayerPaint); |
167 recorder.drawRect(draw, opaqueDrawPaint); | 182 recorder.drawRect(draw, opaqueDrawPaint); |
168 recorder.restore(); | 183 recorder.restore(); |
169 assert_savelayer_restore(r, &record, 15, true); | 184 assert_savelayer_draw_restore(r, &record, 15, true); |
170 | 185 |
171 const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, re
cord, 16); | 186 const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, re
cord, 16); |
172 REPORTER_ASSERT(r, drawRect != nullptr); | 187 REPORTER_ASSERT(r, drawRect != nullptr); |
173 REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202); | 188 REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202); |
| 189 |
| 190 // saveLayer w/ backdrop should NOT go away |
| 191 SkAutoTUnref<SkImageFilter> filter(SkBlurImageFilter::Create(3, 3)); |
| 192 recorder.saveLayer({ nullptr, nullptr, filter, 0}); |
| 193 recorder.drawRect(draw, opaqueDrawPaint); |
| 194 recorder.restore(); |
| 195 assert_savelayer_draw_restore(r, &record, 18, false); |
174 } | 196 } |
175 | 197 |
176 static void assert_merge_svg_opacity_and_filter_layers(skiatest::Reporter* r, | 198 static void assert_merge_svg_opacity_and_filter_layers(skiatest::Reporter* r, |
177 SkRecord* record, | 199 SkRecord* record, |
178 int i, | 200 int i, |
179 bool shouldBeNoOped) { | 201 bool shouldBeNoOped) { |
180 SkRecordMergeSvgOpacityAndFilterLayers(record); | 202 SkRecordMergeSvgOpacityAndFilterLayers(record); |
181 if (shouldBeNoOped) { | 203 if (shouldBeNoOped) { |
182 assert_type<SkRecords::NoOp>(r, *record, i); | 204 assert_type<SkRecords::NoOp>(r, *record, i); |
183 assert_type<SkRecords::NoOp>(r, *record, i + 6); | 205 assert_type<SkRecords::NoOp>(r, *record, i + 6); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 SkPaint shapePaint; | 237 SkPaint shapePaint; |
216 shapePaint.setColor(SK_ColorWHITE); | 238 shapePaint.setColor(SK_ColorWHITE); |
217 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50)), s
hapePaint); | 239 canvas->drawRect(SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50)), s
hapePaint); |
218 shape.reset(recorder.endRecordingAsPicture()); | 240 shape.reset(recorder.endRecordingAsPicture()); |
219 } | 241 } |
220 translucentFilterLayerPaint.setImageFilter(SkPictureImageFilter::Create(shap
e))->unref(); | 242 translucentFilterLayerPaint.setImageFilter(SkPictureImageFilter::Create(shap
e))->unref(); |
221 | 243 |
222 int index = 0; | 244 int index = 0; |
223 | 245 |
224 { | 246 { |
| 247 SkAutoTUnref<SkImageFilter> filter(SkBlurImageFilter::Create(3, 3)); |
| 248 // first (null) should be optimized, 2nd should not |
| 249 SkImageFilter* filters[] = { nullptr, filter.get() }; |
| 250 |
225 // Any combination of these should cause the pattern to be optimized. | 251 // Any combination of these should cause the pattern to be optimized. |
226 SkRect* firstBounds[] = { nullptr, &bounds }; | 252 SkRect* firstBounds[] = { nullptr, &bounds }; |
227 SkPaint* firstPaints[] = { nullptr, &alphaOnlyLayerPaint }; | 253 SkPaint* firstPaints[] = { nullptr, &alphaOnlyLayerPaint }; |
228 SkRect* secondBounds[] = { nullptr, &bounds }; | 254 SkRect* secondBounds[] = { nullptr, &bounds }; |
229 SkPaint* secondPaints[] = { &opaqueFilterLayerPaint, &translucentFilterL
ayerPaint }; | 255 SkPaint* secondPaints[] = { &opaqueFilterLayerPaint, &translucentFilterL
ayerPaint }; |
230 | 256 |
231 for (size_t i = 0; i < SK_ARRAY_COUNT(firstBounds); ++ i) { | 257 for (auto outerF : filters) { |
232 for (size_t j = 0; j < SK_ARRAY_COUNT(firstPaints); ++j) { | 258 bool outerNoOped = !outerF; |
233 for (size_t k = 0; k < SK_ARRAY_COUNT(secondBounds); ++k) { | 259 for (auto innerF : filters) { |
234 for (size_t m = 0; m < SK_ARRAY_COUNT(secondPaints); ++m) { | 260 for (size_t i = 0; i < SK_ARRAY_COUNT(firstBounds); ++ i) { |
235 recorder.saveLayer(firstBounds[i], firstPaints[j]); | 261 for (size_t j = 0; j < SK_ARRAY_COUNT(firstPaints); ++j) { |
236 recorder.save(); | 262 for (size_t k = 0; k < SK_ARRAY_COUNT(secondBounds); ++k
) { |
237 recorder.clipRect(clip); | 263 for (size_t m = 0; m < SK_ARRAY_COUNT(secondPaints);
++m) { |
238 recorder.saveLayer(secondBounds[k], secondPaints[m]); | 264 bool innerNoOped = !secondBounds[k] && !secondPa
ints[m] && !innerF; |
239 recorder.restore(); | 265 |
240 recorder.restore(); | 266 recorder.saveLayer({firstBounds[i], firstPaints[
j], outerF, 0}); |
241 recorder.restore(); | 267 recorder.save(); |
242 assert_merge_svg_opacity_and_filter_layers(r, &record, i
ndex, true); | 268 recorder.clipRect(clip); |
243 index += 7; | 269 recorder.saveLayer({secondBounds[k], secondPaint
s[m], innerF, 0}); |
| 270 recorder.restore(); |
| 271 recorder.restore(); |
| 272 recorder.restore(); |
| 273 assert_merge_svg_opacity_and_filter_layers(r, &r
ecord, index, |
| 274 outer
NoOped); |
| 275 assert_savelayer_restore(r, &record, index + 3,
innerNoOped); |
| 276 index += 7; |
| 277 } |
| 278 } |
244 } | 279 } |
245 } | 280 } |
246 } | 281 } |
247 } | 282 } |
248 } | 283 } |
249 | 284 |
250 // These should cause the pattern to stay unoptimized: | 285 // These should cause the pattern to stay unoptimized: |
251 struct { | 286 struct { |
252 SkPaint* firstPaint; | 287 SkPaint* firstPaint; |
253 SkPaint* secondPaint; | 288 SkPaint* secondPaint; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 recorder.saveLayer(nullptr, &opaqueFilterLayerPaint); | 336 recorder.saveLayer(nullptr, &opaqueFilterLayerPaint); |
302 recorder.restore(); | 337 recorder.restore(); |
303 recorder.restore(); | 338 recorder.restore(); |
304 SkRecordMergeSvgOpacityAndFilterLayers(&record); | 339 SkRecordMergeSvgOpacityAndFilterLayers(&record); |
305 assert_type<SkRecords::SaveLayer>(r, record, index); | 340 assert_type<SkRecords::SaveLayer>(r, record, index); |
306 assert_type<SkRecords::SaveLayer>(r, record, index + 1); | 341 assert_type<SkRecords::SaveLayer>(r, record, index + 1); |
307 assert_type<SkRecords::Restore>(r, record, index + 2); | 342 assert_type<SkRecords::Restore>(r, record, index + 2); |
308 assert_type<SkRecords::Restore>(r, record, index + 3); | 343 assert_type<SkRecords::Restore>(r, record, index + 3); |
309 index += 4; | 344 index += 4; |
310 } | 345 } |
OLD | NEW |