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 "SkRecordOpts.h" | 8 #include "SkRecordOpts.h" |
9 | 9 |
10 #include "SkRecordPattern.h" | 10 #include "SkRecordPattern.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 Is<Restore>> | 80 Is<Restore>> |
81 Match; | 81 Match; |
82 | 82 |
83 bool onMatch(SkRecord* record, Match*, int begin, int end) { | 83 bool onMatch(SkRecord* record, Match*, int begin, int end) { |
84 record->replace<NoOp>(begin); // Save | 84 record->replace<NoOp>(begin); // Save |
85 record->replace<NoOp>(end-1); // Restore | 85 record->replace<NoOp>(end-1); // Restore |
86 return true; | 86 return true; |
87 } | 87 } |
88 }; | 88 }; |
89 | 89 |
90 static bool fold_opacity_layer_color_to_paint(const SkPaint& layerPaint, | 90 static bool fold_opacity_layer_color_to_paint(const SkPaint* layerPaint, |
91 bool isSaveLayer, | 91 bool isSaveLayer, |
92 SkPaint* paint) { | 92 SkPaint* paint) { |
93 // We assume layerPaint is always from a saveLayer. If isSaveLayer is | 93 // We assume layerPaint is always from a saveLayer. If isSaveLayer is |
94 // true, we assume paint is too. | 94 // true, we assume paint is too. |
95 | 95 |
96 // The alpha folding can proceed if the filter layer paint does not have pro
perties which cause | 96 // The alpha folding can proceed if the filter layer paint does not have pro
perties which cause |
97 // the resulting filter layer to be "blended" in complex ways to the parent
layer. For example, | 97 // the resulting filter layer to be "blended" in complex ways to the parent
layer. For example, |
98 // looper drawing unmodulated filter layer twice and then modulating the res
ult produces | 98 // looper drawing unmodulated filter layer twice and then modulating the res
ult produces |
99 // different image to drawing modulated filter layer twice. | 99 // different image to drawing modulated filter layer twice. |
100 // TODO: most likely the looper and only some xfer modes are the hard constr
aints | 100 // TODO: most likely the looper and only some xfer modes are the hard constr
aints |
(...skipping 13 matching lines...) Expand all Loading... |
114 if (paint->getColorFilter()) { | 114 if (paint->getColorFilter()) { |
115 // Filter input depends on the paint color. | 115 // Filter input depends on the paint color. |
116 | 116 |
117 // Here we could filter the color if we knew the draw is going to be uni
form color. This | 117 // Here we could filter the color if we knew the draw is going to be uni
form color. This |
118 // should be detectable as drawPath/drawRect/.. without a shader being u
niform, while | 118 // should be detectable as drawPath/drawRect/.. without a shader being u
niform, while |
119 // drawBitmap/drawSprite or a shader being non-uniform. However, current
matchers don't | 119 // drawBitmap/drawSprite or a shader being non-uniform. However, current
matchers don't |
120 // give the type out easily, so just do not optimize that at the moment. | 120 // give the type out easily, so just do not optimize that at the moment. |
121 return false; | 121 return false; |
122 } | 122 } |
123 | 123 |
124 const uint32_t layerColor = layerPaint.getColor(); | 124 if (layerPaint) { |
125 // The layer paint color must have only alpha component. | 125 const uint32_t layerColor = layerPaint->getColor(); |
126 if (SK_ColorTRANSPARENT != SkColorSetA(layerColor, SK_AlphaTRANSPARENT)) { | 126 // The layer paint color must have only alpha component. |
127 return false; | 127 if (SK_ColorTRANSPARENT != SkColorSetA(layerColor, SK_AlphaTRANSPARENT))
{ |
| 128 return false; |
| 129 } |
| 130 |
| 131 // The layer paint can not have any effects. |
| 132 if (layerPaint->getPathEffect() || |
| 133 layerPaint->getShader() || |
| 134 layerPaint->getXfermode() || |
| 135 layerPaint->getMaskFilter() || |
| 136 layerPaint->getColorFilter() || |
| 137 layerPaint->getRasterizer() || |
| 138 layerPaint->getLooper() || |
| 139 layerPaint->getImageFilter()) { |
| 140 return false; |
| 141 } |
| 142 paint->setAlpha(SkMulDiv255Round(paint->getAlpha(), SkColorGetA(layerCol
or))); |
128 } | 143 } |
129 | 144 |
130 // The layer paint can not have any effects. | |
131 if (layerPaint.getPathEffect() || | |
132 layerPaint.getShader() || | |
133 layerPaint.getXfermode() || | |
134 layerPaint.getMaskFilter() || | |
135 layerPaint.getColorFilter() || | |
136 layerPaint.getRasterizer() || | |
137 layerPaint.getLooper() || | |
138 layerPaint.getImageFilter()) { | |
139 return false; | |
140 } | |
141 | |
142 paint->setAlpha(SkMulDiv255Round(paint->getAlpha(), SkColorGetA(layerColor))
); | |
143 | |
144 return true; | 145 return true; |
145 } | 146 } |
146 | 147 |
147 // Turns logical no-op Save-[non-drawing command]*-Restore patterns into actual
no-ops. | 148 // Turns logical no-op Save-[non-drawing command]*-Restore patterns into actual
no-ops. |
148 struct SaveNoDrawsRestoreNooper { | 149 struct SaveNoDrawsRestoreNooper { |
149 // Greedy matches greedily, so we also have to exclude Save and Restore. | 150 // Greedy matches greedily, so we also have to exclude Save and Restore. |
150 // Nested SaveLayers need to be excluded, or we'll match their Restore! | 151 // Nested SaveLayers need to be excluded, or we'll match their Restore! |
151 typedef Pattern<Is<Save>, | 152 typedef Pattern<Is<Save>, |
152 Greedy<Not<Or<Is<Save>, | 153 Greedy<Not<Or<Is<Save>, |
153 Is<SaveLayer>, | 154 Is<SaveLayer>, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 // There wasn't really any point to this SaveLayer at all. | 205 // There wasn't really any point to this SaveLayer at all. |
205 return KillSaveLayerAndRestore(record, begin); | 206 return KillSaveLayerAndRestore(record, begin); |
206 } | 207 } |
207 | 208 |
208 if (drawPaint == nullptr) { | 209 if (drawPaint == nullptr) { |
209 // We can just give the draw the SaveLayer's paint. | 210 // We can just give the draw the SaveLayer's paint. |
210 // TODO(mtklein): figure out how to do this clearly | 211 // TODO(mtklein): figure out how to do this clearly |
211 return false; | 212 return false; |
212 } | 213 } |
213 | 214 |
214 if (!fold_opacity_layer_color_to_paint(*layerPaint, false /*isSaveLayer*
/, drawPaint)) { | 215 if (!fold_opacity_layer_color_to_paint(layerPaint, false /*isSaveLayer*/
, drawPaint)) { |
215 return false; | 216 return false; |
216 } | 217 } |
217 | 218 |
218 return KillSaveLayerAndRestore(record, begin); | 219 return KillSaveLayerAndRestore(record, begin); |
219 } | 220 } |
220 | 221 |
221 static bool KillSaveLayerAndRestore(SkRecord* record, int saveLayerIndex) { | 222 static bool KillSaveLayerAndRestore(SkRecord* record, int saveLayerIndex) { |
222 record->replace<NoOp>(saveLayerIndex); // SaveLayer | 223 record->replace<NoOp>(saveLayerIndex); // SaveLayer |
223 record->replace<NoOp>(saveLayerIndex+2); // Restore | 224 record->replace<NoOp>(saveLayerIndex+2); // Restore |
224 return true; | 225 return true; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 | 258 |
258 // This layer typically contains a filter, but this should work for laye
rs with for other | 259 // This layer typically contains a filter, but this should work for laye
rs with for other |
259 // purposes too. | 260 // purposes too. |
260 SkPaint* filterLayerPaint = match->fourth<SaveLayer>()->paint; | 261 SkPaint* filterLayerPaint = match->fourth<SaveLayer>()->paint; |
261 if (filterLayerPaint == nullptr) { | 262 if (filterLayerPaint == nullptr) { |
262 // We can just give the inner SaveLayer the paint of the outer SaveL
ayer. | 263 // We can just give the inner SaveLayer the paint of the outer SaveL
ayer. |
263 // TODO(mtklein): figure out how to do this clearly | 264 // TODO(mtklein): figure out how to do this clearly |
264 return false; | 265 return false; |
265 } | 266 } |
266 | 267 |
267 if (!fold_opacity_layer_color_to_paint(*opacityPaint, true /*isSaveLayer
*/, | 268 if (!fold_opacity_layer_color_to_paint(opacityPaint, true /*isSaveLayer*
/, |
268 filterLayerPaint)) { | 269 filterLayerPaint)) { |
269 return false; | 270 return false; |
270 } | 271 } |
271 | 272 |
272 return KillSaveLayerAndRestore(record, begin); | 273 return KillSaveLayerAndRestore(record, begin); |
273 } | 274 } |
274 | 275 |
275 static bool KillSaveLayerAndRestore(SkRecord* record, int saveLayerIndex) { | 276 static bool KillSaveLayerAndRestore(SkRecord* record, int saveLayerIndex) { |
276 record->replace<NoOp>(saveLayerIndex); // SaveLayer | 277 record->replace<NoOp>(saveLayerIndex); // SaveLayer |
277 record->replace<NoOp>(saveLayerIndex + 6); // Restore | 278 record->replace<NoOp>(saveLayerIndex + 6); // Restore |
(...skipping 25 matching lines...) Expand all Loading... |
303 } | 304 } |
304 | 305 |
305 void SkRecordOptimize2(SkRecord* record) { | 306 void SkRecordOptimize2(SkRecord* record) { |
306 multiple_set_matrices(record); | 307 multiple_set_matrices(record); |
307 SkRecordNoopSaveRestores(record); | 308 SkRecordNoopSaveRestores(record); |
308 SkRecordNoopSaveLayerDrawRestores(record); | 309 SkRecordNoopSaveLayerDrawRestores(record); |
309 SkRecordMergeSvgOpacityAndFilterLayers(record); | 310 SkRecordMergeSvgOpacityAndFilterLayers(record); |
310 | 311 |
311 record->defrag(); | 312 record->defrag(); |
312 } | 313 } |
OLD | NEW |