OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2007 The Android Open Source Project | 3 * Copyright 2007 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkPictureFlat.h" | 10 #include "SkPictureFlat.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 /** SkRecords visitor to determine heuristically whether or not a SkPicture | 128 /** SkRecords visitor to determine heuristically whether or not a SkPicture |
129 will be performant when rasterized on the GPU. | 129 will be performant when rasterized on the GPU. |
130 */ | 130 */ |
131 struct SkPicture::PathCounter { | 131 struct SkPicture::PathCounter { |
132 SK_CREATE_MEMBER_DETECTOR(paint); | 132 SK_CREATE_MEMBER_DETECTOR(paint); |
133 | 133 |
134 PathCounter() | 134 PathCounter() |
135 : numPaintWithPathEffectUses (0) | 135 : numPaintWithPathEffectUses (0) |
136 , numFastPathDashEffects (0) | 136 , numFastPathDashEffects (0) |
137 , numAAConcavePaths (0) | 137 , numAAConcavePaths (0) |
138 , numAAHairlineConcavePaths (0) { | 138 , numAAHairlineConcavePaths (0) |
| 139 , numAADFEligibleConcavePaths(0) { |
139 } | 140 } |
140 | 141 |
141 // Recurse into nested pictures. | 142 // Recurse into nested pictures. |
142 void operator()(const SkRecords::DrawPicture& op) { | 143 void operator()(const SkRecords::DrawPicture& op) { |
143 const SkPicture::Analysis& analysis = op.picture->fAnalysis; | 144 const SkPicture::Analysis& analysis = op.picture->fAnalysis; |
144 numPaintWithPathEffectUses += analysis.fNumPaintWithPathEffectUses; | 145 numPaintWithPathEffectUses += analysis.fNumPaintWithPathEffectUses; |
145 numFastPathDashEffects += analysis.fNumFastPathDashEffects; | 146 numFastPathDashEffects += analysis.fNumFastPathDashEffects; |
146 numAAConcavePaths += analysis.fNumAAConcavePaths; | 147 numAAConcavePaths += analysis.fNumAAConcavePaths; |
147 numAAHairlineConcavePaths += analysis.fNumAAHairlineConcavePaths; | 148 numAAHairlineConcavePaths += analysis.fNumAAHairlineConcavePaths; |
| 149 numAADFEligibleConcavePaths += analysis.fNumAADFEligibleConcavePaths; |
148 } | 150 } |
149 | 151 |
150 void checkPaint(const SkPaint* paint) { | 152 void checkPaint(const SkPaint* paint) { |
151 if (paint && paint->getPathEffect()) { | 153 if (paint && paint->getPathEffect()) { |
152 numPaintWithPathEffectUses++; | 154 numPaintWithPathEffectUses++; |
153 } | 155 } |
154 } | 156 } |
155 | 157 |
156 void operator()(const SkRecords::DrawPoints& op) { | 158 void operator()(const SkRecords::DrawPoints& op) { |
157 this->checkPaint(&op.paint); | 159 this->checkPaint(&op.paint); |
158 const SkPathEffect* effect = op.paint.getPathEffect(); | 160 const SkPathEffect* effect = op.paint.getPathEffect(); |
159 if (effect) { | 161 if (effect) { |
160 SkPathEffect::DashInfo info; | 162 SkPathEffect::DashInfo info; |
161 SkPathEffect::DashType dashType = effect->asADash(&info); | 163 SkPathEffect::DashType dashType = effect->asADash(&info); |
162 if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap()
&& | 164 if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap()
&& |
163 SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { | 165 SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { |
164 numFastPathDashEffects++; | 166 numFastPathDashEffects++; |
165 } | 167 } |
166 } | 168 } |
167 } | 169 } |
168 | 170 |
169 void operator()(const SkRecords::DrawPath& op) { | 171 void operator()(const SkRecords::DrawPath& op) { |
170 this->checkPaint(&op.paint); | 172 this->checkPaint(&op.paint); |
171 if (op.paint.isAntiAlias() && !op.path.isConvex()) { | 173 if (op.paint.isAntiAlias() && !op.path.isConvex()) { |
172 numAAConcavePaths++; | 174 numAAConcavePaths++; |
173 | 175 |
174 if (SkPaint::kStroke_Style == op.paint.getStyle() && | 176 SkPaint::Style paintStyle = op.paint.getStyle(); |
| 177 const SkRect& pathBounds = op.path.getBounds(); |
| 178 if (SkPaint::kStroke_Style == paintStyle && |
175 0 == op.paint.getStrokeWidth()) { | 179 0 == op.paint.getStrokeWidth()) { |
176 numAAHairlineConcavePaths++; | 180 numAAHairlineConcavePaths++; |
| 181 } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width()
< 64.f && |
| 182 pathBounds.height() < 64.f && !op.path.isVolatile()) { |
| 183 numAADFEligibleConcavePaths++; |
177 } | 184 } |
178 } | 185 } |
179 } | 186 } |
180 | 187 |
181 template <typename T> | 188 template <typename T> |
182 SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) { | 189 SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) { |
183 this->checkPaint(AsPtr(op.paint)); | 190 this->checkPaint(AsPtr(op.paint)); |
184 } | 191 } |
185 | 192 |
186 template <typename T> | 193 template <typename T> |
187 SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing *
/ } | 194 SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing *
/ } |
188 | 195 |
189 int numPaintWithPathEffectUses; | 196 int numPaintWithPathEffectUses; |
190 int numFastPathDashEffects; | 197 int numFastPathDashEffects; |
191 int numAAConcavePaths; | 198 int numAAConcavePaths; |
192 int numAAHairlineConcavePaths; | 199 int numAAHairlineConcavePaths; |
| 200 int numAADFEligibleConcavePaths; |
193 }; | 201 }; |
194 | 202 |
195 SkPicture::Analysis::Analysis(const SkRecord& record) { | 203 SkPicture::Analysis::Analysis(const SkRecord& record) { |
196 fWillPlaybackBitmaps = WillPlaybackBitmaps(record); | 204 fWillPlaybackBitmaps = WillPlaybackBitmaps(record); |
197 | 205 |
198 PathCounter counter; | 206 PathCounter counter; |
199 for (unsigned i = 0; i < record.count(); i++) { | 207 for (unsigned i = 0; i < record.count(); i++) { |
200 record.visit<void>(i, counter); | 208 record.visit<void>(i, counter); |
201 } | 209 } |
202 fNumPaintWithPathEffectUses = counter.numPaintWithPathEffectUses; | 210 fNumPaintWithPathEffectUses = counter.numPaintWithPathEffectUses; |
203 fNumFastPathDashEffects = counter.numFastPathDashEffects; | 211 fNumFastPathDashEffects = counter.numFastPathDashEffects; |
204 fNumAAConcavePaths = counter.numAAConcavePaths; | 212 fNumAAConcavePaths = counter.numAAConcavePaths; |
205 fNumAAHairlineConcavePaths = counter.numAAHairlineConcavePaths; | 213 fNumAAHairlineConcavePaths = counter.numAAHairlineConcavePaths; |
| 214 fNumAADFEligibleConcavePaths = counter.numAADFEligibleConcavePaths; |
206 | 215 |
207 fHasText = false; | 216 fHasText = false; |
208 TextHunter text; | 217 TextHunter text; |
209 for (unsigned i = 0; i < record.count(); i++) { | 218 for (unsigned i = 0; i < record.count(); i++) { |
210 if (record.visit<bool>(i, text)) { | 219 if (record.visit<bool>(i, text)) { |
211 fHasText = true; | 220 fHasText = true; |
212 break; | 221 break; |
213 } | 222 } |
214 } | 223 } |
215 } | 224 } |
216 | 225 |
217 bool SkPicture::Analysis::suitableForGpuRasterization(const char** reason, | 226 bool SkPicture::Analysis::suitableForGpuRasterization(const char** reason, |
218 int sampleCount) const { | 227 int sampleCount) const { |
219 // TODO: the heuristic used here needs to be refined | 228 // TODO: the heuristic used here needs to be refined |
220 static const int kNumPaintWithPathEffectsUsesTol = 1; | 229 static const int kNumPaintWithPathEffectsUsesTol = 1; |
221 static const int kNumAAConcavePathsTol = 5; | 230 static const int kNumAAConcavePathsTol = 5; |
222 | 231 |
223 int numNonDashedPathEffects = fNumPaintWithPathEffectUses - | 232 int numNonDashedPathEffects = fNumPaintWithPathEffectUses - |
224 fNumFastPathDashEffects; | 233 fNumFastPathDashEffects; |
225 bool suitableForDash = (0 == fNumPaintWithPathEffectUses) || | 234 bool suitableForDash = (0 == fNumPaintWithPathEffectUses) || |
226 (numNonDashedPathEffects < kNumPaintWithPathEffectsUs
esTol | 235 (numNonDashedPathEffects < kNumPaintWithPathEffectsUs
esTol |
227 && 0 == sampleCount); | 236 && 0 == sampleCount); |
228 | 237 |
229 bool ret = suitableForDash && | 238 bool ret = suitableForDash && |
230 (fNumAAConcavePaths - fNumAAHairlineConcavePaths) | 239 (fNumAAConcavePaths - fNumAAHairlineConcavePaths - fNumAADFEligib
leConcavePaths) |
231 < kNumAAConcavePathsTol; | 240 < kNumAAConcavePathsTol; |
232 | 241 |
233 if (!ret && reason) { | 242 if (!ret && reason) { |
234 if (!suitableForDash) { | 243 if (!suitableForDash) { |
235 if (0 != sampleCount) { | 244 if (0 != sampleCount) { |
236 *reason = "Can't use multisample on dash effect."; | 245 *reason = "Can't use multisample on dash effect."; |
237 } else { | 246 } else { |
238 *reason = "Too many non dashed path effects."; | 247 *reason = "Too many non dashed path effects."; |
239 } | 248 } |
240 } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths) | 249 } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths - fNumAADFEl
igibleConcavePaths) |
241 >= kNumAAConcavePathsTol) | 250 >= kNumAAConcavePathsTol) |
242 *reason = "Too many anti-aliased concave paths."; | 251 *reason = "Too many anti-aliased concave paths."; |
243 else | 252 else |
244 *reason = "Unknown reason for GPU unsuitability."; | 253 *reason = "Unknown reason for GPU unsuitability."; |
245 } | 254 } |
246 return ret; | 255 return ret; |
247 } | 256 } |
248 | 257 |
249 /////////////////////////////////////////////////////////////////////////////// | 258 /////////////////////////////////////////////////////////////////////////////// |
250 | 259 |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 int SkPicture::approximateOpCount() const { | 667 int SkPicture::approximateOpCount() const { |
659 SkASSERT(fRecord.get() || fData.get()); | 668 SkASSERT(fRecord.get() || fData.get()); |
660 if (fRecord.get()) { | 669 if (fRecord.get()) { |
661 return fRecord->count(); | 670 return fRecord->count(); |
662 } | 671 } |
663 if (fData.get()) { | 672 if (fData.get()) { |
664 return fData->opCount(); | 673 return fData->opCount(); |
665 } | 674 } |
666 return 0; | 675 return 0; |
667 } | 676 } |
OLD | NEW |