Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: src/gpu/GrAAFlatteningConvexPathRenderer.cpp

Issue 1158803002: Added GrAAFlatteningConvexPathRenderer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: hopefully fixed windows build issues Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1
2 /*
robertphillips 2015/05/27 18:10:53 Update this ?
ethannicholas 2015/05/27 19:22:30 Done.
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "GrAAFlatteningConvexPathRenderer.h"
10
11 #include "GrAAFlatteningConvexTessellator.h"
12 #include "GrBatch.h"
13 #include "GrBatchTarget.h"
14 #include "GrBatchTest.h"
15 #include "GrContext.h"
16 #include "GrDefaultGeoProcFactory.h"
17 #include "GrGeometryProcessor.h"
18 #include "GrInvariantOutput.h"
19 #include "GrPathUtils.h"
20 #include "GrProcessor.h"
21 #include "GrPipelineBuilder.h"
22 #include "GrStrokeInfo.h"
23 #include "SkGeometry.h"
24 #include "SkString.h"
25 #include "SkTraceEvent.h"
26 #include "gl/GrGLProcessor.h"
27 #include "gl/GrGLSL.h"
28 #include "gl/GrGLGeometryProcessor.h"
29 #include "gl/builders/GrGLProgramBuilder.h"
30
31 #define DEFAULT_BUFFER_SIZE 100
32
33 GrAAFlatteningConvexPathRenderer::GrAAFlatteningConvexPathRenderer() {
34 }
35
36 ///////////////////////////////////////////////////////////////////////////////
37
38 bool GrAAFlatteningConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
robertphillips 2015/05/27 18:10:54 Align these guys ?
ethannicholas 2015/05/27 19:22:30 Done.
39 const GrPipelineBuilder*,
40 const SkMatrix& viewMatrix,
41 const SkPath& path,
42 const GrStrokeInfo& stroke,
43 bool antiAlias) const {
44 return (target->caps()->shaderCaps()->shaderDerivativeSupport() && antiAlias &&
bsalomon 2015/05/27 17:11:07 probably don't need shader derivative support anym
ethannicholas 2015/05/27 19:22:30 Done.
45 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex() );
46 }
47
48 // extract the result vertices and indices from the GrAAFlatteningConvexTessella tor
49 static void extract_verts(const GrAAFlatteningConvexTessellator& tess,
50 void* vertices,
51 size_t vertexStride,
52 GrColor color,
53 uint16_t firstIndex,
54 uint16_t* idxs,
55 bool tweakAlphaForCoverage) {
56 intptr_t verts = reinterpret_cast<intptr_t>(vertices);
57
58 for (int i = 0; i < tess.numPts(); ++i) {
59 *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i);
60 }
61
62 // Make 'verts' point to the colors
63 verts += sizeof(SkPoint);
64 for (int i = 0; i < tess.numPts(); ++i) {
65 SkASSERT(tess.depth(i) >= -0.5f && tess.depth(i) <= 0.5f);
66 if (tweakAlphaForCoverage) {
67 SkASSERT(SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) <= 255) ;
68 unsigned scale = SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) ;
69 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, s cale);
70 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
71 } else {
72 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
73 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) =
74 tess.depth(i ) + 0.5f;
75 }
76 }
77
78 for (int i = 0; i < tess.numIndices(); ++i) {
79 idxs[i] = tess.index(i) + firstIndex;
80 }
81 }
82
83 static const GrGeometryProcessor* create_fill_gp(bool tweakAlphaForCoverage,
84 const SkMatrix& localMatrix,
85 bool usesLocalCoords,
86 bool coverageIgnored) {
87 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType;
88 if (!tweakAlphaForCoverage) {
89 flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
90 }
91
92 return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords , coverageIgnored,
93 SkMatrix::I(), localMatrix);
94 }
95
96 class AAFlatteningConvexPathBatch : public GrBatch {
97 public:
98 struct Geometry {
99 GrColor fColor;
100 SkMatrix fViewMatrix;
101 SkPath fPath;
102 };
103
104 static GrBatch* Create(const Geometry& geometry) {
105 return SkNEW_ARGS(AAFlatteningConvexPathBatch, (geometry));
106 }
107
108 const char* name() const override { return "AAConvexBatch"; }
109
110 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
111 // When this is called on a batch, there is only one geometry bundle
112 out->setKnownFourComponents(fGeoData[0].fColor);
113 }
114 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
115 out->setUnknownSingleComponent();
116 }
117
118 void initBatchTracker(const GrPipelineInfo& init) override {
119 // Handle any color overrides
120 if (init.fColorIgnored) {
121 fGeoData[0].fColor = GrColor_ILLEGAL;
122 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
123 fGeoData[0].fColor = init.fOverrideColor;
124 }
125
126 // setup batch properties
127 fBatch.fColorIgnored = init.fColorIgnored;
128 fBatch.fColor = fGeoData[0].fColor;
129 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
130 fBatch.fCoverageIgnored = init.fCoverageIgnored;
131 fBatch.fLinesOnly = SkPath::kLine_SegmentMask == fGeoData[0].fPath.getSe gmentMasks();
132 fBatch.fCanTweakAlphaForCoverage = init.fCanTweakAlphaForCoverage;
133 }
134
135 void draw(GrBatchTarget* batchTarget, const GrPipeline* pipeline, int vertex Count,
136 size_t vertexStride, void* vertices, int indexCount, uint16_t* indic es) {
137 if (vertexCount == 0 || indexCount == 0) {
138 return;
139 }
140 const GrVertexBuffer* vertexBuffer;
141 GrVertices info;
142 int firstVertex;
143 void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount, &ver texBuffer,
144 &firstVertex);
145 if (!verts) {
146 SkDebugf("Could not allocate vertices\n");
147 return;
148 }
149 memcpy(verts, vertices, vertexCount * vertexStride);
150
151 const GrIndexBuffer* indexBuffer;
152 int firstIndex;
153 uint16_t* idxs = batchTarget->makeIndexSpace(indexCount, &indexBuffer, & firstIndex);
154 if (!idxs) {
155 SkDebugf("Could not allocate indices\n");
156 return;
157 }
158 memcpy(idxs, indices, indexCount * sizeof(uint16_t));
159 info.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
160 firstIndex, vertexCount, indexCount);
161 batchTarget->draw(info);
162 }
163
164 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override {
165 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
166
167 SkMatrix invert;
168 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) {
169 SkDebugf("Could not invert viewmatrix\n");
170 return;
171 }
172
173 // Setup GrGeometryProcessor
174 SkAutoTUnref<const GrGeometryProcessor> gp(
175 create_fill_gp(canTweakAlphaForC overage, invert,
176 this->usesLocalCo ords(),
177 this->coverageIgn ored()));
178
179 batchTarget->initDraw(gp, pipeline);
180
181 size_t vertexStride = gp->getVertexStride();
182
183 SkASSERT(canTweakAlphaForCoverage ?
184 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) :
185 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr));
186
187 GrAAFlatteningConvexTessellator tess;
188
189 int instanceCount = fGeoData.count();
190
191 int vertexCount = 0;
192 int indexCount = 0;
193 int maxVertices = DEFAULT_BUFFER_SIZE;
194 int maxIndices = DEFAULT_BUFFER_SIZE;
195 uint8_t* vertices = (uint8_t*) malloc(maxVertices * vertexStride);
196 uint16_t* indices = (uint16_t*) malloc(maxIndices * sizeof(uint16_t));
197 for (int i = 0; i < instanceCount; i++) {
198 tess.rewind();
199
200 Geometry& args = fGeoData[i];
201
202 if (!tess.tessellate(args.fViewMatrix, args.fPath)) {
203 continue;
204 }
205
206 #define MAX(a, b) (a > b ? a : b)
bsalomon 2015/05/27 17:11:07 There is an SkTMax
ethannicholas 2015/05/27 19:22:30 Done.
207
208 int currentIndices = tess.numIndices();
209 SkASSERT(currentIndices <= UINT16_MAX);
210 if (indexCount + currentIndices > UINT16_MAX) {
211 // if we added the current instance, we would overflow the indic es we can store in a
212 // uint16_t. Draw what we've got so far and reset.
213 draw(batchTarget, pipeline, vertexCount, vertexStride, vertices, indexCount,
214 indices);
215 vertexCount = 0;
216 indexCount = 0;
217 }
218 int currentVertices = tess.numPts();
219 if (vertexCount + currentVertices > maxVertices) {
220 maxVertices = MAX(vertexCount + currentVertices, maxVertices * 2 );
221 vertices = (uint8_t*) realloc(vertices, maxVertices * vertexStri de);
222 }
223 if (indexCount + currentIndices > maxIndices) {
224 maxIndices = MAX(indexCount + currentIndices, maxIndices * 2);
225 indices = (uint16_t*) realloc(indices, maxIndices * sizeof(uint1 6_t));
226 }
227
228 #undef MAX
229
230 extract_verts(tess, vertices + vertexStride * vertexCount, vertexStr ide, args.fColor,
231 vertexCount, indices + indexCount, canTweakAlphaForCoverage) ;
232 vertexCount += currentVertices;
233 indexCount += currentIndices;
234 }
235 draw(batchTarget, pipeline, vertexCount, vertexStride, vertices, indexCo unt, indices);
236 free(vertices);
237 free(indices);
238 }
239
240 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
241
242 private:
243 AAFlatteningConvexPathBatch(const Geometry& geometry) {
244 this->initClassID<AAFlatteningConvexPathBatch>();
245 fGeoData.push_back(geometry);
246
247 // compute bounds
248 fBounds = geometry.fPath.getBounds();
249 geometry.fViewMatrix.mapRect(&fBounds);
250 }
251
252 bool onCombineIfPossible(GrBatch* t) override {
253 AAFlatteningConvexPathBatch* that = t->cast<AAFlatteningConvexPathBatch> ();
254
255 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
256 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi ewMatrix())) {
257 return false;
258 }
259
260 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to
261 // not tweaking
262 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage() ) {
263 fBatch.fCanTweakAlphaForCoverage = false;
264 }
265
266 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
267 this->joinBounds(that->bounds());
268 return true;
269 }
270
271 GrColor color() const { return fBatch.fColor; }
272 bool linesOnly() const { return fBatch.fLinesOnly; }
273 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
274 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover age; }
275 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
276 bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
277
278 struct BatchTracker {
279 GrColor fColor;
280 bool fUsesLocalCoords;
281 bool fColorIgnored;
282 bool fCoverageIgnored;
283 bool fLinesOnly;
284 bool fCanTweakAlphaForCoverage;
285 };
286
287 BatchTracker fBatch;
288 SkSTArray<1, Geometry, true> fGeoData;
289 };
290
291 bool GrAAFlatteningConvexPathRenderer::onDrawPath(GrDrawTarget* target,
292 GrPipelineBuilder* pipelineBuilder,
293 GrColor color,
294 const SkMatrix& vm,
295 const SkPath& path,
296 const GrStrokeInfo&,
297 bool antiAlias) {
298 if (path.isEmpty()) {
299 return true;
300 }
301 AAFlatteningConvexPathBatch::Geometry geometry;
302 geometry.fColor = color;
303 geometry.fViewMatrix = vm;
304 geometry.fPath = path;
305
306 SkAutoTUnref<GrBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
307 target->drawBatch(pipelineBuilder, batch);
308
309 return true;
310 }
311
312 //////////////////////////////////////////////////////////////////////////////// ///////////////////
313
314 #ifdef GR_TEST_UTILS
315
316 BATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) {
317 AAFlatteningConvexPathBatch::Geometry geometry;
318 geometry.fColor = GrRandomColor(random);
319 geometry.fViewMatrix = GrTest::TestMatrixInvertible(random);
320 geometry.fPath = GrTest::TestPathConvex(random);
321
322 return AAFlatteningConvexPathBatch::Create(geometry);
323 }
324
325 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698