Line data Source code
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 0 : 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 0 : SkASSERT(fNumAAHairlineConcavePaths <= fNumAAConcavePaths);
19 :
20 0 : int numNonDashedPathEffects = fNumPaintWithPathEffectUses -
21 0 : fNumFastPathDashEffects;
22 :
23 0 : bool suitableForDash = (0 == fNumPaintWithPathEffectUses) ||
24 : (numNonDashedPathEffects < kNumPaintWithPathEffectUsesTol
25 0 : && 0 == sampleCount);
26 :
27 0 : bool ret = suitableForDash &&
28 0 : (fNumAAConcavePaths - fNumAAHairlineConcavePaths - fNumAADFEligibleConcavePaths)
29 0 : < kNumAAConcavePaths;
30 0 : if (!ret && reason) {
31 0 : if (!suitableForDash) {
32 0 : if (0 != sampleCount) {
33 0 : *reason = "Can't use multisample on dash effect.";
34 : } else {
35 0 : *reason = "Too many non dashed path effects.";
36 : }
37 0 : } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths - fNumAADFEligibleConcavePaths)
38 : >= kNumAAConcavePaths) {
39 0 : *reason = "Too many anti-aliased concave paths.";
40 : } else {
41 0 : *reason = "Unknown reason for GPU unsuitability.";
42 : }
43 : }
44 0 : return ret;
45 : }
46 :
47 0 : void SkPictureContentInfo::onDrawPoints(size_t count, const SkPaint& paint) {
48 0 : if (paint.getPathEffect() != nullptr) {
49 0 : SkPathEffect::DashInfo info;
50 0 : SkPathEffect::DashType dashType = paint.getPathEffect()->asADash(&info);
51 0 : if (2 == count && SkPaint::kRound_Cap != paint.getStrokeCap() &&
52 0 : SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
53 0 : ++fNumFastPathDashEffects;
54 : }
55 : }
56 0 : }
57 :
58 0 : void SkPictureContentInfo::onDrawPath(const SkPath& path, const SkPaint& paint) {
59 0 : if (paint.isAntiAlias() && !path.isConvex()) {
60 0 : ++fNumAAConcavePaths;
61 :
62 0 : SkPaint::Style paintStyle = paint.getStyle();
63 0 : const SkRect& pathBounds = path.getBounds();
64 0 : if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
65 0 : ++fNumAAHairlineConcavePaths;
66 0 : } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width() < 64.f &&
67 0 : pathBounds.height() < 64.f && !path.isVolatile()) {
68 0 : ++fNumAADFEligibleConcavePaths;
69 : }
70 : }
71 0 : }
72 :
73 0 : void SkPictureContentInfo::onAddPaintPtr(const SkPaint* paint) {
74 0 : if (paint && paint->getPathEffect()) {
75 0 : ++fNumPaintWithPathEffectUses;
76 : }
77 0 : }
78 :
79 0 : void SkPictureContentInfo::onSaveLayer() {
80 0 : *fSaveStack.append() = kSaveLayer_Flag;
81 0 : }
82 :
83 0 : void SkPictureContentInfo::onSave() {
84 0 : *fSaveStack.append() = kSave_Flag;
85 0 : }
86 :
87 0 : void SkPictureContentInfo::onRestore() {
88 0 : SkASSERT(fSaveStack.count() > 0);
89 :
90 0 : bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
91 :
92 0 : if (fSaveStack.top() & kSaveLayer_Flag) {
93 0 : ++fNumLayers;
94 0 : if (containedSaveLayer) {
95 0 : ++fNumInteriorLayers;
96 : } else {
97 0 : ++fNumLeafLayers;
98 : }
99 0 : containedSaveLayer = true;
100 : }
101 :
102 0 : fSaveStack.pop();
103 :
104 0 : if (containedSaveLayer && fSaveStack.count() > 0) {
105 0 : fSaveStack.top() |= kContainedSaveLayer_Flag;
106 : }
107 0 : }
108 :
109 0 : void SkPictureContentInfo::rescindLastSave() {
110 0 : SkASSERT(fSaveStack.count() > 0);
111 0 : SkASSERT(fSaveStack.top() & kSave_Flag);
112 :
113 0 : bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
114 :
115 0 : fSaveStack.pop();
116 :
117 0 : if (containedSaveLayer && fSaveStack.count() > 0) {
118 0 : fSaveStack.top() |= kContainedSaveLayer_Flag;
119 : }
120 0 : }
121 :
122 0 : void SkPictureContentInfo::rescindLastSaveLayer() {
123 0 : SkASSERT(fSaveStack.count() > 0);
124 0 : SkASSERT(fSaveStack.top() & kSaveLayer_Flag);
125 :
126 0 : bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
127 :
128 0 : fSaveStack.pop();
129 :
130 0 : if (containedSaveLayer && fSaveStack.count() > 0) {
131 0 : fSaveStack.top() |= kContainedSaveLayer_Flag;
132 : }
133 0 : }
134 :
135 0 : void SkPictureContentInfo::set(const SkPictureContentInfo& src) {
136 0 : fNumOperations = src.fNumOperations;
137 0 : fNumTexts = src.fNumTexts;
138 0 : fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
139 0 : fNumFastPathDashEffects = src.fNumFastPathDashEffects;
140 0 : fNumAAConcavePaths = src.fNumAAConcavePaths;
141 0 : fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
142 0 : fNumAADFEligibleConcavePaths = src.fNumAADFEligibleConcavePaths;
143 0 : fNumLayers = src.fNumLayers;
144 0 : fNumInteriorLayers = src.fNumInteriorLayers;
145 0 : fNumLeafLayers = src.fNumLeafLayers;
146 0 : fSaveStack = src.fSaveStack;
147 0 : }
148 :
149 0 : void SkPictureContentInfo::reset() {
150 0 : fNumOperations = 0;
151 0 : fNumTexts = 0;
152 0 : fNumPaintWithPathEffectUses = 0;
153 0 : fNumFastPathDashEffects = 0;
154 0 : fNumAAConcavePaths = 0;
155 0 : fNumAAHairlineConcavePaths = 0;
156 0 : fNumAADFEligibleConcavePaths = 0;
157 0 : fNumLayers = 0;
158 0 : fNumInteriorLayers = 0;
159 0 : fNumLeafLayers = 0;
160 0 : fSaveStack.rewind();
161 0 : }
162 :
163 0 : void SkPictureContentInfo::swap(SkPictureContentInfo* other) {
164 0 : SkTSwap(fNumOperations, other->fNumOperations);
165 0 : SkTSwap(fNumTexts, other->fNumTexts);
166 0 : SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
167 0 : SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects);
168 0 : SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
169 0 : SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
170 0 : SkTSwap(fNumAADFEligibleConcavePaths, other->fNumAADFEligibleConcavePaths);
171 0 : SkTSwap(fNumLayers, other->fNumLayers);
172 0 : SkTSwap(fNumInteriorLayers, other->fNumInteriorLayers);
173 0 : SkTSwap(fNumLeafLayers, other->fNumLeafLayers);
174 0 : fSaveStack.swap(other->fSaveStack);
175 0 : }
|