1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkPaint.h" 9 #include "SkPathEffect.h" 10 #include "SkPictureContentInfo.h" 11 12 bool SkPictureContentInfo::suitableForGpuRasterization(GrContext* context, const char **reason, 13 int sampleCount) const { 14 // TODO: the heuristic used here needs to be refined 15 static const int kNumPaintWithPathEffectUsesTol = 1; 16 static const int kNumAAConcavePaths = 5; 17 18 SkASSERT(fNumAAHairlineConcavePaths <= fNumAAConcavePaths); 19 20 int numNonDashedPathEffects = fNumPaintWithPathEffectUses - 21 fNumFastPathDashEffects; 22 23 bool suitableForDash = (0 == fNumPaintWithPathEffectUses) || 24 (numNonDashedPathEffects < kNumPaintWithPathEffectUsesTol 25 && 0 == sampleCount); 26 27 bool ret = suitableForDash && 28 (fNumAAConcavePaths - fNumAAHairlineConcavePaths) 29 < kNumAAConcavePaths; 30 if (!ret && reason) { 31 if (!suitableForDash) { 32 if (0 != sampleCount) { 33 *reason = "Can't use multisample on dash effect."; 34 } else { 35 *reason = "Too many non dashed path effects."; 36 } 37 } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths) 38 >= kNumAAConcavePaths) { 39 *reason = "Too many anti-aliased concave paths."; 40 } else { 41 *reason = "Unknown reason for GPU unsuitability."; 42 } 43 } 44 return ret; 45 } 46 47 void SkPictureContentInfo::onDrawPoints(size_t count, const SkPaint& paint) { 48 if (paint.getPathEffect() != NULL) { 49 SkPathEffect::DashInfo info; 50 SkPathEffect::DashType dashType = paint.getPathEffect()->asADash(&info); 51 if (2 == count && SkPaint::kRound_Cap != paint.getStrokeCap() && 52 SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { 53 ++fNumFastPathDashEffects; 54 } 55 } 56 } 57 58 void SkPictureContentInfo::onDrawPath(const SkPath& path, const SkPaint& paint) { 59 if (paint.isAntiAlias() && !path.isConvex()) { 60 ++fNumAAConcavePaths; 61 62 if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) { 63 ++fNumAAHairlineConcavePaths; 64 } 65 } 66 } 67 68 void SkPictureContentInfo::onAddPaintPtr(const SkPaint* paint) { 69 if (paint && paint->getPathEffect()) { 70 ++fNumPaintWithPathEffectUses; 71 } 72 } 73 74 void SkPictureContentInfo::onSaveLayer() { 75 *fSaveStack.append() = kSaveLayer_Flag; 76 } 77 78 void SkPictureContentInfo::onSave() { 79 *fSaveStack.append() = kSave_Flag; 80 } 81 82 void SkPictureContentInfo::onRestore() { 83 SkASSERT(fSaveStack.count() > 0); 84 85 bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag; 86 87 if (fSaveStack.top() & kSaveLayer_Flag) { 88 ++fNumLayers; 89 if (containedSaveLayer) { 90 ++fNumInteriorLayers; 91 } else { 92 ++fNumLeafLayers; 93 } 94 containedSaveLayer = true; 95 } 96 97 fSaveStack.pop(); 98 99 if (containedSaveLayer && fSaveStack.count() > 0) { 100 fSaveStack.top() |= kContainedSaveLayer_Flag; 101 } 102 } 103 104 void SkPictureContentInfo::rescindLastSave() { 105 SkASSERT(fSaveStack.count() > 0); 106 SkASSERT(fSaveStack.top() & kSave_Flag); 107 108 bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag; 109 110 fSaveStack.pop(); 111 112 if (containedSaveLayer && fSaveStack.count() > 0) { 113 fSaveStack.top() |= kContainedSaveLayer_Flag; 114 } 115 } 116 117 void SkPictureContentInfo::rescindLastSaveLayer() { 118 SkASSERT(fSaveStack.count() > 0); 119 SkASSERT(fSaveStack.top() & kSaveLayer_Flag); 120 121 bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag; 122 123 fSaveStack.pop(); 124 125 if (containedSaveLayer && fSaveStack.count() > 0) { 126 fSaveStack.top() |= kContainedSaveLayer_Flag; 127 } 128 } 129 130 void SkPictureContentInfo::set(const SkPictureContentInfo& src) { 131 fNumOperations = src.fNumOperations; 132 fNumTexts = src.fNumTexts; 133 fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses; 134 fNumFastPathDashEffects = src.fNumFastPathDashEffects; 135 fNumAAConcavePaths = src.fNumAAConcavePaths; 136 fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths; 137 fNumLayers = src.fNumLayers; 138 fNumInteriorLayers = src.fNumInteriorLayers; 139 fNumLeafLayers = src.fNumLeafLayers; 140 fSaveStack = src.fSaveStack; 141 } 142 143 void SkPictureContentInfo::reset() { 144 fNumOperations = 0; 145 fNumTexts = 0; 146 fNumPaintWithPathEffectUses = 0; 147 fNumFastPathDashEffects = 0; 148 fNumAAConcavePaths = 0; 149 fNumAAHairlineConcavePaths = 0; 150 fNumLayers = 0; 151 fNumInteriorLayers = 0; 152 fNumLeafLayers = 0; 153 fSaveStack.rewind(); 154 } 155 156 void SkPictureContentInfo::swap(SkPictureContentInfo* other) { 157 SkTSwap(fNumOperations, other->fNumOperations); 158 SkTSwap(fNumTexts, other->fNumTexts); 159 SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses); 160 SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects); 161 SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths); 162 SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths); 163 SkTSwap(fNumLayers, other->fNumLayers); 164 SkTSwap(fNumInteriorLayers, other->fNumInteriorLayers); 165 SkTSwap(fNumLeafLayers, other->fNumLeafLayers); 166 fSaveStack.swap(other->fSaveStack); 167 } 168