| 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 |