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

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

Powered by Google App Engine
This is Rietveld 408576698