| /* | |
| * Copyright 2014 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "SkPaint.h" | |
| #include "SkPathEffect.h" | |
| #include "SkPictureContentInfo.h" | |
| bool SkPictureContentInfo::suitableForGpuRasterization(GrContext* context, const char **reason, | |
| int sampleCount) const { | |
| // TODO: the heuristic used here needs to be refined | |
| static const int kNumPaintWithPathEffectUsesTol = 1; | |
| static const int kNumAAConcavePaths = 5; | |
| SkASSERT(fNumAAHairlineConcavePaths <= fNumAAConcavePaths); | |
| int numNonDashedPathEffects = fNumPaintWithPathEffectUses - | |
| fNumFastPathDashEffects; | |
| bool suitableForDash = (0 == fNumPaintWithPathEffectUses) || | |
| (numNonDashedPathEffects < kNumPaintWithPathEffectUsesTol | |
| && 0 == sampleCount); | |
| bool ret = suitableForDash && | |
| (fNumAAConcavePaths - fNumAAHairlineConcavePaths) | |
| < kNumAAConcavePaths; | |
| if (!ret && NULL != reason) { | |
| if (!suitableForDash) { | |
| if (0 != sampleCount) { | |
| *reason = "Can't use multisample on dash effect."; | |
| } else { | |
| *reason = "Too many non dashed path effects."; | |
| } | |
| } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths) | |
| >= kNumAAConcavePaths) { | |
| *reason = "Too many anti-aliased concave paths."; | |
| } else { | |
| *reason = "Unknown reason for GPU unsuitability."; | |
| } | |
| } | |
| return ret; | |
| } | |
| void SkPictureContentInfo::onDrawPoints(size_t count, const SkPaint& paint) { | |
| if (paint.getPathEffect() != NULL) { | |
| SkPathEffect::DashInfo info; | |
| SkPathEffect::DashType dashType = paint.getPathEffect()->asADash(&info); | |
| if (2 == count && SkPaint::kRound_Cap != paint.getStrokeCap() && | |
| SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { | |
| ++fNumFastPathDashEffects; | |
| } | |
| } | |
| } | |
| void SkPictureContentInfo::onDrawPath(const SkPath& path, const SkPaint& paint) { | |
| if (paint.isAntiAlias() && !path.isConvex()) { | |
| ++fNumAAConcavePaths; | |
| if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) { | |
| ++fNumAAHairlineConcavePaths; | |
| } | |
| } | |
| } | |
| void SkPictureContentInfo::onAddPaintPtr(const SkPaint* paint) { | |
| if (NULL != paint && NULL != paint->getPathEffect()) { | |
| ++fNumPaintWithPathEffectUses; | |
| } | |
| } | |
| void SkPictureContentInfo::onSaveLayer() { | |
| *fSaveStack.append() = kSaveLayer_Flag; | |
| } | |
| void SkPictureContentInfo::onSave() { | |
| *fSaveStack.append() = kSave_Flag; | |
| } | |
| void SkPictureContentInfo::onRestore() { | |
| SkASSERT(fSaveStack.count() > 0); | |
| bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag; | |
| if (fSaveStack.top() & kSaveLayer_Flag) { | |
| ++fNumLayers; | |
| if (containedSaveLayer) { | |
| ++fNumInteriorLayers; | |
| } else { | |
| ++fNumLeafLayers; | |
| } | |
| containedSaveLayer = true; | |
| } | |
| fSaveStack.pop(); | |
| if (containedSaveLayer && fSaveStack.count() > 0) { | |
| fSaveStack.top() |= kContainedSaveLayer_Flag; | |
| } | |
| } | |
| void SkPictureContentInfo::rescindLastSave() { | |
| SkASSERT(fSaveStack.count() > 0); | |
| SkASSERT(fSaveStack.top() & kSave_Flag); | |
| bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag; | |
| fSaveStack.pop(); | |
| if (containedSaveLayer && fSaveStack.count() > 0) { | |
| fSaveStack.top() |= kContainedSaveLayer_Flag; | |
| } | |
| } | |
| void SkPictureContentInfo::rescindLastSaveLayer() { | |
| SkASSERT(fSaveStack.count() > 0); | |
| SkASSERT(fSaveStack.top() & kSaveLayer_Flag); | |
| bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag; | |
| fSaveStack.pop(); | |
| if (containedSaveLayer && fSaveStack.count() > 0) { | |
| fSaveStack.top() |= kContainedSaveLayer_Flag; | |
| } | |
| } | |
| void SkPictureContentInfo::set(const SkPictureContentInfo& src) { | |
| fNumOperations = src.fNumOperations; | |
| fNumTexts = src.fNumTexts; | |
| fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses; | |
| fNumFastPathDashEffects = src.fNumFastPathDashEffects; | |
| fNumAAConcavePaths = src.fNumAAConcavePaths; | |
| fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths; | |
| fNumLayers = src.fNumLayers; | |
| fNumInteriorLayers = src.fNumInteriorLayers; | |
| fNumLeafLayers = src.fNumLeafLayers; | |
| fSaveStack = src.fSaveStack; | |
| } | |
| void SkPictureContentInfo::reset() { | |
| fNumOperations = 0; | |
| fNumTexts = 0; | |
| fNumPaintWithPathEffectUses = 0; | |
| fNumFastPathDashEffects = 0; | |
| fNumAAConcavePaths = 0; | |
| fNumAAHairlineConcavePaths = 0; | |
| fNumLayers = 0; | |
| fNumInteriorLayers = 0; | |
| fNumLeafLayers = 0; | |
| fSaveStack.rewind(); | |
| } | |
| void SkPictureContentInfo::swap(SkPictureContentInfo* other) { | |
| SkTSwap(fNumOperations, other->fNumOperations); | |
| SkTSwap(fNumTexts, other->fNumTexts); | |
| SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses); | |
| SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects); | |
| SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths); | |
| SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths); | |
| SkTSwap(fNumLayers, other->fNumLayers); | |
| SkTSwap(fNumInteriorLayers, other->fNumInteriorLayers); | |
| SkTSwap(fNumLeafLayers, other->fNumLeafLayers); | |
| fSaveStack.swap(other->fSaveStack); | |
| } |