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