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

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

Issue 1180903006: added stroking support to GrAALinearizingConvexPathRenderer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: debug fixes 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
1 1
2 /* 2 /*
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrAALinearizingConvexPathRenderer.h" 9 #include "GrAALinearizingConvexPathRenderer.h"
10 10
11 #include "GrAAConvexTessellator.h" 11 #include "GrAAConvexTessellator.h"
12 #include "GrBatch.h" 12 #include "GrBatch.h"
13 #include "GrBatchTarget.h" 13 #include "GrBatchTarget.h"
14 #include "GrBatchTest.h" 14 #include "GrBatchTest.h"
15 #include "GrContext.h" 15 #include "GrContext.h"
16 #include "GrDefaultGeoProcFactory.h" 16 #include "GrDefaultGeoProcFactory.h"
17 #include "GrGeometryProcessor.h" 17 #include "GrGeometryProcessor.h"
18 #include "GrInvariantOutput.h" 18 #include "GrInvariantOutput.h"
19 #include "GrPathUtils.h" 19 #include "GrPathUtils.h"
20 #include "GrProcessor.h" 20 #include "GrProcessor.h"
21 #include "GrPipelineBuilder.h" 21 #include "GrPipelineBuilder.h"
22 #include "GrStrokeInfo.h" 22 #include "GrStrokeInfo.h"
23 #include "SkGeometry.h" 23 #include "SkGeometry.h"
24 #include "SkString.h" 24 #include "SkString.h"
25 #include "SkTraceEvent.h" 25 #include "SkTraceEvent.h"
26 #include "SkPathPriv.h"
26 #include "gl/GrGLProcessor.h" 27 #include "gl/GrGLProcessor.h"
27 #include "gl/GrGLSL.h" 28 #include "gl/GrGLSL.h"
28 #include "gl/GrGLGeometryProcessor.h" 29 #include "gl/GrGLGeometryProcessor.h"
29 #include "gl/builders/GrGLProgramBuilder.h" 30 #include "gl/builders/GrGLProgramBuilder.h"
30 31
robertphillips 2015/06/16 13:13:02 More informative name? Which buffer ?
31 #define DEFAULT_BUFFER_SIZE 100 32 static const int DEFAULT_BUFFER_SIZE = 100;
33
34 // The thicker the stroke, the harder it is to produce high-quality results usin g tessellation. For
35 // the time being, we simply drop back to software rendering above this stroke w idth.
36 static const SkScalar kMaxStrokeWidth = 20.0;
32 37
33 GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() { 38 GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() {
34 } 39 }
35 40
36 /////////////////////////////////////////////////////////////////////////////// 41 ///////////////////////////////////////////////////////////////////////////////
37 42
38 bool GrAALinearizingConvexPathRenderer::canDrawPath(const GrDrawTarget* target, 43 bool GrAALinearizingConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
39 const GrPipelineBuilder*, 44 const GrPipelineBuilder*,
40 const SkMatrix& viewMatrix, 45 const SkMatrix& viewMatrix,
41 const SkPath& path, 46 const SkPath& path,
42 const GrStrokeInfo& stroke, 47 const GrStrokeInfo& stroke,
43 bool antiAlias) const { 48 bool antiAlias) const {
44 return (antiAlias && stroke.isFillStyle() && !path.isInverseFillType() && pa th.isConvex()); 49 if (!antiAlias) {
50 return false;
51 }
52 if (path.isInverseFillType()) {
53 return false;
54 }
55 if (!path.isConvex()) {
56 return false;
57 }
58 if (stroke.getStyle() == SkStrokeRec::kStroke_Style) {
59 return viewMatrix.isSimilarity() && stroke.getWidth() <= kMaxStrokeWidth &&
60 !stroke.isDashed() && SkPathPriv::LastVerbIsClose(path) &&
61 stroke.getJoin() != SkPaint::Join::kRound_Join;
62 }
63 return stroke.getStyle() == SkStrokeRec::kFill_Style;
45 } 64 }
46 65
47 // extract the result vertices and indices from the GrAAConvexTessellator 66 // extract the result vertices and indices from the GrAAConvexTessellator
48 static void extract_verts(const GrAAConvexTessellator& tess, 67 static void extract_verts(const GrAAConvexTessellator& tess,
49 void* vertices, 68 void* vertices,
50 size_t vertexStride, 69 size_t vertexStride,
51 GrColor color, 70 GrColor color,
52 uint16_t firstIndex, 71 uint16_t firstIndex,
53 uint16_t* idxs, 72 uint16_t* idxs,
54 bool tweakAlphaForCoverage) { 73 bool tweakAlphaForCoverage) {
55 intptr_t verts = reinterpret_cast<intptr_t>(vertices); 74 intptr_t verts = reinterpret_cast<intptr_t>(vertices);
56 75
57 for (int i = 0; i < tess.numPts(); ++i) { 76 for (int i = 0; i < tess.numPts(); ++i) {
58 *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i); 77 *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i);
59 } 78 }
60 79
61 // Make 'verts' point to the colors 80 // Make 'verts' point to the colors
62 verts += sizeof(SkPoint); 81 verts += sizeof(SkPoint);
63 for (int i = 0; i < tess.numPts(); ++i) { 82 for (int i = 0; i < tess.numPts(); ++i) {
64 SkASSERT(tess.depth(i) >= -0.5f && tess.depth(i) <= 0.5f);
65 if (tweakAlphaForCoverage) { 83 if (tweakAlphaForCoverage) {
66 SkASSERT(SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) <= 255) ; 84 SkASSERT(SkScalarRoundToInt(255.0f * tess.coverage(i)) <= 255);
67 unsigned scale = SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) ; 85 unsigned scale = SkScalarRoundToInt(255.0f * tess.coverage(i));
68 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, s cale); 86 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, s cale);
69 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; 87 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
70 } else { 88 } else {
71 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; 89 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
72 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = 90 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) =
73 tess.depth(i ) + 0.5f; 91 tess.coverage(i);
74 } 92 }
75 } 93 }
76 94
77 for (int i = 0; i < tess.numIndices(); ++i) { 95 for (int i = 0; i < tess.numIndices(); ++i) {
78 idxs[i] = tess.index(i) + firstIndex; 96 idxs[i] = tess.index(i) + firstIndex;
79 } 97 }
80 } 98 }
81 99
82 static const GrGeometryProcessor* create_fill_gp(bool tweakAlphaForCoverage, 100 static const GrGeometryProcessor* create_fill_gp(bool tweakAlphaForCoverage,
83 const SkMatrix& localMatrix, 101 const SkMatrix& localMatrix,
84 bool usesLocalCoords, 102 bool usesLocalCoords,
85 bool coverageIgnored) { 103 bool coverageIgnored) {
86 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; 104 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType;
87 if (!tweakAlphaForCoverage) { 105 if (!tweakAlphaForCoverage) {
88 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; 106 flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
89 } 107 }
90 108
91 return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords , coverageIgnored, 109 return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, usesLocalCoords , coverageIgnored,
92 SkMatrix::I(), localMatrix); 110 SkMatrix::I(), localMatrix);
93 } 111 }
94 112
95 class AAFlatteningConvexPathBatch : public GrBatch { 113 class AAFlatteningConvexPathBatch : public GrBatch {
96 public: 114 public:
97 struct Geometry { 115 struct Geometry {
98 GrColor fColor; 116 GrColor fColor;
99 SkMatrix fViewMatrix; 117 SkMatrix fViewMatrix;
100 SkPath fPath; 118 SkPath fPath;
119 SkScalar fStrokeWidth;
120 SkPaint::Join fJoin;
121 SkScalar fMiterLimit;
101 }; 122 };
102 123
103 static GrBatch* Create(const Geometry& geometry) { 124 static GrBatch* Create(const Geometry& geometry) {
104 return SkNEW_ARGS(AAFlatteningConvexPathBatch, (geometry)); 125 return SkNEW_ARGS(AAFlatteningConvexPathBatch, (geometry));
105 } 126 }
106 127
107 const char* name() const override { return "AAConvexBatch"; } 128 const char* name() const override { return "AAConvexBatch"; }
108 129
109 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 130 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
110 // When this is called on a batch, there is only one geometry bundle 131 // When this is called on a batch, there is only one geometry bundle
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 uint16_t* idxs = batchTarget->makeIndexSpace(indexCount, &indexBuffer, & firstIndex); 173 uint16_t* idxs = batchTarget->makeIndexSpace(indexCount, &indexBuffer, & firstIndex);
153 if (!idxs) { 174 if (!idxs) {
154 SkDebugf("Could not allocate indices\n"); 175 SkDebugf("Could not allocate indices\n");
155 return; 176 return;
156 } 177 }
157 memcpy(idxs, indices, indexCount * sizeof(uint16_t)); 178 memcpy(idxs, indices, indexCount * sizeof(uint16_t));
158 info.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex, 179 info.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
159 firstIndex, vertexCount, indexCount); 180 firstIndex, vertexCount, indexCount);
160 batchTarget->draw(info); 181 batchTarget->draw(info);
161 } 182 }
162 183
163 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override { 184 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override {
164 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); 185 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
165 186
166 SkMatrix invert; 187 SkMatrix invert;
167 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { 188 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) {
168 SkDebugf("Could not invert viewmatrix\n"); 189 SkDebugf("Could not invert viewmatrix\n");
169 return; 190 return;
170 } 191 }
171 192
172 // Setup GrGeometryProcessor 193 // Setup GrGeometryProcessor
173 SkAutoTUnref<const GrGeometryProcessor> gp( 194 SkAutoTUnref<const GrGeometryProcessor> gp(
174 create_fill_gp(canTweakAlphaForC overage, invert, 195 create_fill_gp(canTweakAlphaForC overage, invert,
175 this->usesLocalCo ords(), 196 this->usesLocalCo ords(),
176 this->coverageIgn ored())); 197 this->coverageIgn ored()));
177 198
178 batchTarget->initDraw(gp, pipeline); 199 batchTarget->initDraw(gp, pipeline);
179 200
180 size_t vertexStride = gp->getVertexStride(); 201 size_t vertexStride = gp->getVertexStride();
181 202
182 SkASSERT(canTweakAlphaForCoverage ? 203 SkASSERT(canTweakAlphaForCoverage ?
183 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) : 204 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) :
184 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr)); 205 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr));
185 206
186 GrAAConvexTessellator tess;
187
188 int instanceCount = fGeoData.count(); 207 int instanceCount = fGeoData.count();
189 208
190 int vertexCount = 0; 209 int vertexCount = 0;
191 int indexCount = 0; 210 int indexCount = 0;
192 int maxVertices = DEFAULT_BUFFER_SIZE; 211 int maxVertices = DEFAULT_BUFFER_SIZE;
193 int maxIndices = DEFAULT_BUFFER_SIZE; 212 int maxIndices = DEFAULT_BUFFER_SIZE;
194 uint8_t* vertices = (uint8_t*) malloc(maxVertices * vertexStride); 213 uint8_t* vertices = (uint8_t*) malloc(maxVertices * vertexStride);
195 uint16_t* indices = (uint16_t*) malloc(maxIndices * sizeof(uint16_t)); 214 uint16_t* indices = (uint16_t*) malloc(maxIndices * sizeof(uint16_t));
196 for (int i = 0; i < instanceCount; i++) { 215 for (int i = 0; i < instanceCount; i++) {
197 tess.rewind();
198
199 Geometry& args = fGeoData[i]; 216 Geometry& args = fGeoData[i];
217 GrAAConvexTessellator tess(args.fStrokeWidth, args.fJoin, args.fMite rLimit);
200 218
201 if (!tess.tessellate(args.fViewMatrix, args.fPath)) { 219 if (!tess.tessellate(args.fViewMatrix, args.fPath)) {
202 continue; 220 continue;
203 } 221 }
204 222
205 int currentIndices = tess.numIndices(); 223 int currentIndices = tess.numIndices();
206 SkASSERT(currentIndices <= UINT16_MAX); 224 SkASSERT(currentIndices <= UINT16_MAX);
207 if (indexCount + currentIndices > UINT16_MAX) { 225 if (indexCount + currentIndices > UINT16_MAX) {
208 // if we added the current instance, we would overflow the indic es we can store in a 226 // 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. 227 // uint16_t. Draw what we've got so far and reset.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 299
282 BatchTracker fBatch; 300 BatchTracker fBatch;
283 SkSTArray<1, Geometry, true> fGeoData; 301 SkSTArray<1, Geometry, true> fGeoData;
284 }; 302 };
285 303
286 bool GrAALinearizingConvexPathRenderer::onDrawPath(GrDrawTarget* target, 304 bool GrAALinearizingConvexPathRenderer::onDrawPath(GrDrawTarget* target,
287 GrPipelineBuilder* pipelineBu ilder, 305 GrPipelineBuilder* pipelineBu ilder,
288 GrColor color, 306 GrColor color,
289 const SkMatrix& vm, 307 const SkMatrix& vm,
290 const SkPath& path, 308 const SkPath& path,
291 const GrStrokeInfo&, 309 const GrStrokeInfo& stroke,
292 bool antiAlias) { 310 bool antiAlias) {
293 if (path.isEmpty()) { 311 if (path.isEmpty()) {
294 return true; 312 return true;
295 } 313 }
296 AAFlatteningConvexPathBatch::Geometry geometry; 314 AAFlatteningConvexPathBatch::Geometry geometry;
297 geometry.fColor = color; 315 geometry.fColor = color;
298 geometry.fViewMatrix = vm; 316 geometry.fViewMatrix = vm;
299 geometry.fPath = path; 317 geometry.fPath = path;
318 geometry.fStrokeWidth = stroke.isFillStyle() ? -1.0f : stroke.getWidth();
319 geometry.fJoin = stroke.isFillStyle() ? SkPaint::Join::kMiter_Join : stroke. getJoin();
320 geometry.fMiterLimit = stroke.getMiter();
300 321
301 SkAutoTUnref<GrBatch> batch(AAFlatteningConvexPathBatch::Create(geometry)); 322 SkAutoTUnref<GrBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
302 target->drawBatch(pipelineBuilder, batch); 323 target->drawBatch(pipelineBuilder, batch);
303 324
304 return true; 325 return true;
305 } 326 }
306 327
307 //////////////////////////////////////////////////////////////////////////////// /////////////////// 328 //////////////////////////////////////////////////////////////////////////////// ///////////////////
308 329
309 #ifdef GR_TEST_UTILS 330 #ifdef GR_TEST_UTILS
310 331
311 BATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) { 332 BATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) {
312 AAFlatteningConvexPathBatch::Geometry geometry; 333 AAFlatteningConvexPathBatch::Geometry geometry;
313 geometry.fColor = GrRandomColor(random); 334 geometry.fColor = GrRandomColor(random);
314 geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); 335 geometry.fViewMatrix = GrTest::TestMatrixInvertible(random);
315 geometry.fPath = GrTest::TestPathConvex(random); 336 geometry.fPath = GrTest::TestPathConvex(random);
316 337
317 return AAFlatteningConvexPathBatch::Create(geometry); 338 return AAFlatteningConvexPathBatch::Create(geometry);
318 } 339 }
319 340
320 #endif 341 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698