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