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

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

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

Powered by Google App Engine
This is Rietveld 408576698