OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2007 The Android Open Source Project | 2 * Copyright 2007 The Android Open Source Project |
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 | 8 |
9 #include "SkPictureFlat.h" | 9 #include "SkPictureFlat.h" |
10 #include "SkPictureData.h" | 10 #include "SkPictureData.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 }; | 126 }; |
127 | 127 |
128 } // namespace | 128 } // namespace |
129 | 129 |
130 /** SkRecords visitor to determine heuristically whether or not a SkPicture | 130 /** SkRecords visitor to determine heuristically whether or not a SkPicture |
131 will be performant when rasterized on the GPU. | 131 will be performant when rasterized on the GPU. |
132 */ | 132 */ |
133 struct SkPicture::PathCounter { | 133 struct SkPicture::PathCounter { |
134 SK_CREATE_MEMBER_DETECTOR(paint); | 134 SK_CREATE_MEMBER_DETECTOR(paint); |
135 | 135 |
136 PathCounter() | 136 PathCounter() : fNumSlowPathsAndDashEffects(0) {} |
137 : numPaintWithPathEffectUses (0) | |
138 , numFastPathDashEffects (0) | |
139 , numAAConcavePaths (0) | |
140 , numAAHairlineConcavePaths (0) | |
141 , numAADFEligibleConcavePaths(0) { | |
142 } | |
143 | 137 |
144 // Recurse into nested pictures. | 138 // Recurse into nested pictures. |
145 void operator()(const SkRecords::DrawPicture& op) { | 139 void operator()(const SkRecords::DrawPicture& op) { |
146 const SkPicture::Analysis& analysis = op.picture->fAnalysis; | 140 const SkPicture::Analysis& analysis = op.picture->fAnalysis; |
147 numPaintWithPathEffectUses += analysis.fNumPaintWithPathEffectUses; | 141 fNumSlowPathsAndDashEffects += analysis.fNumSlowPathsAndDashEffects; |
148 numFastPathDashEffects += analysis.fNumFastPathDashEffects; | |
149 numAAConcavePaths += analysis.fNumAAConcavePaths; | |
150 numAAHairlineConcavePaths += analysis.fNumAAHairlineConcavePaths; | |
151 numAADFEligibleConcavePaths += analysis.fNumAADFEligibleConcavePaths; | |
152 } | 142 } |
153 | 143 |
154 void checkPaint(const SkPaint* paint) { | 144 void checkPaint(const SkPaint* paint) { |
155 if (paint && paint->getPathEffect()) { | 145 if (paint && paint->getPathEffect()) { |
156 numPaintWithPathEffectUses++; | 146 // Initially assume it's slow. |
| 147 fNumSlowPathsAndDashEffects++; |
157 } | 148 } |
158 } | 149 } |
159 | 150 |
160 void operator()(const SkRecords::DrawPoints& op) { | 151 void operator()(const SkRecords::DrawPoints& op) { |
161 this->checkPaint(&op.paint); | 152 this->checkPaint(&op.paint); |
162 const SkPathEffect* effect = op.paint.getPathEffect(); | 153 const SkPathEffect* effect = op.paint.getPathEffect(); |
163 if (effect) { | 154 if (effect) { |
164 SkPathEffect::DashInfo info; | 155 SkPathEffect::DashInfo info; |
165 SkPathEffect::DashType dashType = effect->asADash(&info); | 156 SkPathEffect::DashType dashType = effect->asADash(&info); |
166 if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap()
&& | 157 if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap()
&& |
167 SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { | 158 SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { |
168 numFastPathDashEffects++; | 159 fNumSlowPathsAndDashEffects--; |
169 } | 160 } |
170 } | 161 } |
171 } | 162 } |
172 | 163 |
173 void operator()(const SkRecords::DrawPath& op) { | 164 void operator()(const SkRecords::DrawPath& op) { |
174 this->checkPaint(&op.paint); | 165 this->checkPaint(&op.paint); |
175 if (op.paint.isAntiAlias() && !op.path.isConvex()) { | 166 if (op.paint.isAntiAlias() && !op.path.isConvex()) { |
176 numAAConcavePaths++; | |
177 | |
178 SkPaint::Style paintStyle = op.paint.getStyle(); | 167 SkPaint::Style paintStyle = op.paint.getStyle(); |
179 const SkRect& pathBounds = op.path.getBounds(); | 168 const SkRect& pathBounds = op.path.getBounds(); |
180 if (SkPaint::kStroke_Style == paintStyle && | 169 if (SkPaint::kStroke_Style == paintStyle && |
181 0 == op.paint.getStrokeWidth()) { | 170 0 == op.paint.getStrokeWidth()) { |
182 numAAHairlineConcavePaths++; | 171 // AA hairline concave path is not slow. |
183 } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width()
< 64.f && | 172 } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width()
< 64.f && |
184 pathBounds.height() < 64.f && !op.path.isVolatile()) { | 173 pathBounds.height() < 64.f && !op.path.isVolatile()) { |
185 numAADFEligibleConcavePaths++; | 174 // AADF eligible concave path is not slow. |
| 175 } else { |
| 176 fNumSlowPathsAndDashEffects++; |
186 } | 177 } |
187 } | 178 } |
188 } | 179 } |
189 | 180 |
190 template <typename T> | 181 template <typename T> |
191 SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) { | 182 SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) { |
192 this->checkPaint(AsPtr(op.paint)); | 183 this->checkPaint(AsPtr(op.paint)); |
193 } | 184 } |
194 | 185 |
195 template <typename T> | 186 template <typename T> |
196 SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing *
/ } | 187 SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing *
/ } |
197 | 188 |
198 int numPaintWithPathEffectUses; | 189 int fNumSlowPathsAndDashEffects; |
199 int numFastPathDashEffects; | |
200 int numAAConcavePaths; | |
201 int numAAHairlineConcavePaths; | |
202 int numAADFEligibleConcavePaths; | |
203 }; | 190 }; |
204 | 191 |
205 SkPicture::Analysis::Analysis(const SkRecord& record) { | 192 SkPicture::Analysis::Analysis(const SkRecord& record) { |
206 fWillPlaybackBitmaps = WillPlaybackBitmaps(record); | 193 fWillPlaybackBitmaps = WillPlaybackBitmaps(record); |
207 | 194 |
208 PathCounter counter; | 195 PathCounter counter; |
209 for (unsigned i = 0; i < record.count(); i++) { | 196 for (unsigned i = 0; i < record.count(); i++) { |
210 record.visit<void>(i, counter); | 197 record.visit<void>(i, counter); |
211 } | 198 } |
212 fNumPaintWithPathEffectUses = counter.numPaintWithPathEffectUses; | 199 fNumSlowPathsAndDashEffects = SkTMin<int>(counter.fNumSlowPathsAndDashEffect
s, 255); |
213 fNumFastPathDashEffects = counter.numFastPathDashEffects; | |
214 fNumAAConcavePaths = counter.numAAConcavePaths; | |
215 fNumAAHairlineConcavePaths = counter.numAAHairlineConcavePaths; | |
216 fNumAADFEligibleConcavePaths = counter.numAADFEligibleConcavePaths; | |
217 | 200 |
218 fHasText = false; | 201 fHasText = false; |
219 TextHunter text; | 202 TextHunter text; |
220 for (unsigned i = 0; i < record.count(); i++) { | 203 for (unsigned i = 0; i < record.count(); i++) { |
221 if (record.visit<bool>(i, text)) { | 204 if (record.visit<bool>(i, text)) { |
222 fHasText = true; | 205 fHasText = true; |
223 break; | 206 break; |
224 } | 207 } |
225 } | 208 } |
226 } | 209 } |
227 | 210 |
228 bool SkPicture::Analysis::suitableForGpuRasterization(const char** reason, | 211 bool SkPicture::Analysis::suitableForGpuRasterization(const char** reason, |
229 int sampleCount) const { | 212 int sampleCount) const { |
230 // TODO: the heuristic used here needs to be refined | 213 // TODO: the heuristic used here needs to be refined |
231 static const int kNumSlowPathsTol = 6; | 214 static const int kNumSlowPathsTol = 6; |
232 | 215 |
233 int numSlowPathDashedPaths = fNumPaintWithPathEffectUses - fNumFastPathDashE
ffects; | 216 bool ret = fNumSlowPathsAndDashEffects < kNumSlowPathsTol; |
234 | |
235 int numSlowPaths = fNumAAConcavePaths - | |
236 fNumAAHairlineConcavePaths - | |
237 fNumAADFEligibleConcavePaths; | |
238 | |
239 bool ret = numSlowPathDashedPaths + numSlowPaths < kNumSlowPathsTol; | |
240 | 217 |
241 if (!ret && reason) { | 218 if (!ret && reason) { |
242 *reason = "Too many slow paths (either concave or dashed)."; | 219 *reason = "Too many slow paths (either concave or dashed)."; |
243 } | 220 } |
244 return ret; | 221 return ret; |
245 } | 222 } |
246 | 223 |
247 /////////////////////////////////////////////////////////////////////////////// | 224 /////////////////////////////////////////////////////////////////////////////// |
248 | 225 |
249 int SkPicture::drawableCount() const { | 226 int SkPicture::drawableCount() const { |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 if (sk_atomic_compare_exchange(&fUniqueID, &id, next, | 472 if (sk_atomic_compare_exchange(&fUniqueID, &id, next, |
496 sk_memory_order_relaxed, | 473 sk_memory_order_relaxed, |
497 sk_memory_order_relaxed)) { | 474 sk_memory_order_relaxed)) { |
498 id = next; | 475 id = next; |
499 } else { | 476 } else { |
500 // sk_atomic_compare_exchange replaced id with the current value of
fUniqueID. | 477 // sk_atomic_compare_exchange replaced id with the current value of
fUniqueID. |
501 } | 478 } |
502 } | 479 } |
503 return id; | 480 return id; |
504 } | 481 } |
OLD | NEW |