| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 |
| 101 if (paint->getXfermode() || paint->getLooper()) { | 101 if (!paint->isSrcOver() || paint->getLooper()) { |
| 102 return false; | 102 return false; |
| 103 } | 103 } |
| 104 | 104 |
| 105 if (!isSaveLayer && paint->getImageFilter()) { | 105 if (!isSaveLayer && paint->getImageFilter()) { |
| 106 // For normal draws, the paint color is used as one input for the color
for the draw. Image | 106 // For normal draws, the paint color is used as one input for the color
for the draw. Image |
| 107 // filter will operate on the result, and thus we can not change the inp
ut. | 107 // filter will operate on the result, and thus we can not change the inp
ut. |
| 108 // For layer saves, the image filter is applied to the layer contents. T
he layer is then | 108 // For layer saves, the image filter is applied to the layer contents. T
he layer is then |
| 109 // modulated with the paint color, so it's fine to proceed with the fold
for saveLayer | 109 // modulated with the paint color, so it's fine to proceed with the fold
for saveLayer |
| 110 // paints with image filters. | 110 // paints with image filters. |
| 111 return false; | 111 return false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 122 } | 122 } |
| 123 | 123 |
| 124 if (layerPaint) { | 124 if (layerPaint) { |
| 125 const uint32_t layerColor = layerPaint->getColor(); | 125 const uint32_t layerColor = layerPaint->getColor(); |
| 126 // The layer paint color must have only alpha component. | 126 // The layer paint color must have only alpha component. |
| 127 if (SK_ColorTRANSPARENT != SkColorSetA(layerColor, SK_AlphaTRANSPARENT))
{ | 127 if (SK_ColorTRANSPARENT != SkColorSetA(layerColor, SK_AlphaTRANSPARENT))
{ |
| 128 return false; | 128 return false; |
| 129 } | 129 } |
| 130 | 130 |
| 131 // The layer paint can not have any effects. | 131 // The layer paint can not have any effects. |
| 132 if (layerPaint->getPathEffect() || | 132 if (layerPaint->getPathEffect() || |
| 133 layerPaint->getShader() || | 133 layerPaint->getShader() || |
| 134 layerPaint->getXfermode() || | 134 !layerPaint->isSrcOver() || |
| 135 layerPaint->getMaskFilter() || | 135 layerPaint->getMaskFilter() || |
| 136 layerPaint->getColorFilter() || | 136 layerPaint->getColorFilter() || |
| 137 layerPaint->getRasterizer() || | 137 layerPaint->getRasterizer() || |
| 138 layerPaint->getLooper() || | 138 layerPaint->getLooper() || |
| 139 layerPaint->getImageFilter()) { | 139 layerPaint->getImageFilter()) { |
| 140 return false; | 140 return false; |
| 141 } | 141 } |
| 142 paint->setAlpha(SkMulDiv255Round(paint->getAlpha(), SkColorGetA(layerCol
or))); | 142 paint->setAlpha(SkMulDiv255Round(paint->getAlpha(), SkColorGetA(layerCol
or))); |
| 143 } | 143 } |
| 144 | 144 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 167 }; | 167 }; |
| 168 void SkRecordNoopSaveRestores(SkRecord* record) { | 168 void SkRecordNoopSaveRestores(SkRecord* record) { |
| 169 SaveOnlyDrawsRestoreNooper onlyDraws; | 169 SaveOnlyDrawsRestoreNooper onlyDraws; |
| 170 SaveNoDrawsRestoreNooper noDraws; | 170 SaveNoDrawsRestoreNooper noDraws; |
| 171 | 171 |
| 172 // Run until they stop changing things. | 172 // Run until they stop changing things. |
| 173 while (apply(&onlyDraws, record) || apply(&noDraws, record)); | 173 while (apply(&onlyDraws, record) || apply(&noDraws, record)); |
| 174 } | 174 } |
| 175 | 175 |
| 176 static bool effectively_srcover(const SkPaint* paint) { | 176 static bool effectively_srcover(const SkPaint* paint) { |
| 177 if (!paint) { | 177 if (!paint || paint->isSrcOver()) { |
| 178 return true; | |
| 179 } | |
| 180 SkXfermode* mode = paint->getXfermode(); | |
| 181 if (SkXfermode::IsMode(mode, SkXfermode::kSrcOver_Mode)) { | |
| 182 return true; | 178 return true; |
| 183 } | 179 } |
| 184 // src-mode with opaque and no effects (which might change opaqueness) is ok
too. | 180 // src-mode with opaque and no effects (which might change opaqueness) is ok
too. |
| 185 return !paint->getShader() && !paint->getColorFilter() && !paint->getImageFi
lter() && | 181 return !paint->getShader() && !paint->getColorFilter() && !paint->getImageFi
lter() && |
| 186 0xFF == paint->getAlpha() && SkXfermode::IsMode(mode, SkXfermode::kSr
c_Mode); | 182 0xFF == paint->getAlpha() && paint->getBlendMode() == SkBlendMode::kS
rc; |
| 187 } | 183 } |
| 188 | 184 |
| 189 // For some SaveLayer-[drawing command]-Restore patterns, merge the SaveLayer's
alpha into the | 185 // For some SaveLayer-[drawing command]-Restore patterns, merge the SaveLayer's
alpha into the |
| 190 // draw, and no-op the SaveLayer and Restore. | 186 // draw, and no-op the SaveLayer and Restore. |
| 191 struct SaveLayerDrawRestoreNooper { | 187 struct SaveLayerDrawRestoreNooper { |
| 192 typedef Pattern<Is<SaveLayer>, IsDraw, Is<Restore>> Match; | 188 typedef Pattern<Is<SaveLayer>, IsDraw, Is<Restore>> Match; |
| 193 | 189 |
| 194 bool onMatch(SkRecord* record, Match* match, int begin, int end) { | 190 bool onMatch(SkRecord* record, Match* match, int begin, int end) { |
| 195 if (match->first<SaveLayer>()->backdrop) { | 191 if (match->first<SaveLayer>()->backdrop) { |
| 196 // can't throw away the layer if we have a backdrop | 192 // can't throw away the layer if we have a backdrop |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 } | 300 } |
| 305 | 301 |
| 306 void SkRecordOptimize2(SkRecord* record) { | 302 void SkRecordOptimize2(SkRecord* record) { |
| 307 multiple_set_matrices(record); | 303 multiple_set_matrices(record); |
| 308 SkRecordNoopSaveRestores(record); | 304 SkRecordNoopSaveRestores(record); |
| 309 SkRecordNoopSaveLayerDrawRestores(record); | 305 SkRecordNoopSaveLayerDrawRestores(record); |
| 310 SkRecordMergeSvgOpacityAndFilterLayers(record); | 306 SkRecordMergeSvgOpacityAndFilterLayers(record); |
| 311 | 307 |
| 312 record->defrag(); | 308 record->defrag(); |
| 313 } | 309 } |
| OLD | NEW |