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 |