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

Side by Side Diff: src/gpu/batches/GrTessellatingPathRenderer.cpp

Issue 1152733009: Screenspace AA tessellated path rendering. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Cleanup, and fix call to PathToTriangles(). Created 4 years, 3 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
« src/gpu/GrTessellator.cpp ('K') | « src/gpu/GrTessellator.cpp ('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
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrTessellatingPathRenderer.h" 8 #include "GrTessellatingPathRenderer.h"
9 9
10 #include "GrAuditTrail.h" 10 #include "GrAuditTrail.h"
11 #include "GrBatchFlushState.h" 11 #include "GrBatchFlushState.h"
12 #include "GrBatchTest.h" 12 #include "GrBatchTest.h"
13 #include "GrClip.h" 13 #include "GrClip.h"
14 #include "GrDefaultGeoProcFactory.h" 14 #include "GrDefaultGeoProcFactory.h"
15 #include "GrDrawTarget.h"
15 #include "GrMesh.h" 16 #include "GrMesh.h"
16 #include "GrPathUtils.h" 17 #include "GrPathUtils.h"
17 #include "GrPipelineBuilder.h" 18 #include "GrPipelineBuilder.h"
18 #include "GrResourceCache.h" 19 #include "GrResourceCache.h"
19 #include "GrResourceProvider.h" 20 #include "GrResourceProvider.h"
20 #include "GrTessellator.h" 21 #include "GrTessellator.h"
21 #include "SkGeometry.h" 22 #include "SkGeometry.h"
22 23
23 #include "batches/GrVertexBatch.h" 24 #include "batches/GrVertexBatch.h"
24 25
25 #include <stdio.h> 26 #include <stdio.h>
26 27
28 #define SK_DISABLE_SCREENSPACE_TESS_AA_PATH_RENDERER
29
27 /* 30 /*
28 * This path renderer tessellates the path into triangles using GrTessellator, u ploads the triangles 31 * This path renderer tessellates the path into triangles using GrTessellator, u ploads the
29 * to a vertex buffer, and renders them with a single draw call. It does not cur rently do 32 * triangles to a vertex buffer, and renders them with a single draw call. It ca n do screenspace
30 * antialiasing, so it must be used in conjunction with multisampling. 33 * antialiasing with a one-pixel coverage ramp.
31 */ 34 */
32 namespace { 35 namespace {
33 36
34 struct TessInfo { 37 struct TessInfo {
35 SkScalar fTolerance; 38 SkScalar fTolerance;
36 int fCount; 39 int fCount;
37 }; 40 };
38 41
39 // When the SkPathRef genID changes, invalidate a corresponding GrResource descr ibed by key. 42 // When the SkPathRef genID changes, invalidate a corresponding GrResource descr ibed by key.
40 class PathInvalidator : public SkPathRef::GenIDChangeListener { 43 class PathInvalidator : public SkPathRef::GenIDChangeListener {
(...skipping 16 matching lines...) Expand all
57 const TessInfo* info = static_cast<const TessInfo*>(data->data()); 60 const TessInfo* info = static_cast<const TessInfo*>(data->data());
58 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) { 61 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) {
59 *actualCount = info->fCount; 62 *actualCount = info->fCount;
60 return true; 63 return true;
61 } 64 }
62 return false; 65 return false;
63 } 66 }
64 67
65 class StaticVertexAllocator : public GrTessellator::VertexAllocator { 68 class StaticVertexAllocator : public GrTessellator::VertexAllocator {
66 public: 69 public:
67 StaticVertexAllocator(GrResourceProvider* resourceProvider, bool canMapVB) 70 StaticVertexAllocator(size_t stride, GrResourceProvider* resourceProvider, b ool canMapVB)
68 : fResourceProvider(resourceProvider) 71 : VertexAllocator(stride)
72 , fResourceProvider(resourceProvider)
69 , fCanMapVB(canMapVB) 73 , fCanMapVB(canMapVB)
70 , fVertices(nullptr) { 74 , fVertices(nullptr) {
71 } 75 }
72 SkPoint* lock(int vertexCount) override { 76 void* lock(int vertexCount) override {
73 size_t size = vertexCount * sizeof(SkPoint); 77 size_t size = vertexCount * stride();
74 fVertexBuffer.reset(fResourceProvider->createBuffer( 78 fVertexBuffer.reset(fResourceProvider->createBuffer(
75 size, kVertex_GrBufferType, kStatic_GrAccessPattern, 0)); 79 size, kVertex_GrBufferType, kStatic_GrAccessPattern, 0));
76 if (!fVertexBuffer.get()) { 80 if (!fVertexBuffer.get()) {
77 return nullptr; 81 return nullptr;
78 } 82 }
79 if (fCanMapVB) { 83 if (fCanMapVB) {
80 fVertices = static_cast<SkPoint*>(fVertexBuffer->map()); 84 fVertices = fVertexBuffer->map();
81 } else { 85 } else {
82 fVertices = new SkPoint[vertexCount]; 86 fVertices = sk_malloc_throw(vertexCount * stride());
83 } 87 }
84 return fVertices; 88 return fVertices;
85 } 89 }
86 void unlock(int actualCount) override { 90 void unlock(int actualCount) override {
87 if (fCanMapVB) { 91 if (fCanMapVB) {
88 fVertexBuffer->unmap(); 92 fVertexBuffer->unmap();
89 } else { 93 } else {
90 fVertexBuffer->updateData(fVertices, actualCount * sizeof(SkPoint)); 94 fVertexBuffer->updateData(fVertices, actualCount * stride());
91 delete[] fVertices; 95 sk_free(fVertices);
92 } 96 }
93 fVertices = nullptr; 97 fVertices = nullptr;
94 } 98 }
95 GrBuffer* vertexBuffer() { return fVertexBuffer.get(); } 99 GrBuffer* vertexBuffer() { return fVertexBuffer.get(); }
96 private: 100 private:
97 SkAutoTUnref<GrBuffer> fVertexBuffer; 101 SkAutoTUnref<GrBuffer> fVertexBuffer;
98 GrResourceProvider* fResourceProvider; 102 GrResourceProvider* fResourceProvider;
99 bool fCanMapVB; 103 bool fCanMapVB;
100 SkPoint* fVertices; 104 void* fVertices;
105 };
106
107 class DynamicVertexAllocator : public GrTessellator::VertexAllocator {
108 public:
109 DynamicVertexAllocator(size_t stride, GrVertexBatch::Target* target)
110 : VertexAllocator(stride)
111 , fTarget(target)
112 , fVertexBuffer(nullptr)
113 , fVertices(nullptr) {
114 }
115 void* lock(int vertexCount) override {
116 fVertexCount = vertexCount;
117 fVertices = fTarget->makeVertexSpace(stride(), vertexCount, &fVertexBuff er, &fFirstVertex);
118 return fVertices;
119 }
120 void unlock(int actualCount) override {
121 fTarget->putBackVertices(fVertexCount - actualCount, stride());
122 fVertices = nullptr;
123 }
124 const GrBuffer* vertexBuffer() const { return fVertexBuffer; }
125 int firstVertex() const { return fFirstVertex; }
126 private:
127 GrVertexBatch::Target* fTarget;
128 const GrBuffer* fVertexBuffer;
129 int fVertexCount;
130 int fFirstVertex;
131 void* fVertices;
101 }; 132 };
102 133
103 } // namespace 134 } // namespace
104 135
105 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { 136 GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
106 } 137 }
107 138
108 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { 139 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t {
109 // This path renderer can draw fill styles but does not do antialiasing. It can do convex and 140 // This path renderer can draw fill styles, and can do screenspace antialias ing via a
110 // concave paths, but we'll leave the convex ones to simpler algorithms. We pass on paths that 141 // one-pixel coverage ramp. It can do convex and concave paths, but we'll le ave the convex
111 // have styles, though they may come back around after applying the styling information to the 142 // ones to simpler algorithms. We pass on paths that have styles, though the y may come back
112 // geometry to create a filled path. We also skip paths that don't have a ke y since the real 143 // around after applying the styling information to the geometry to create a filled path. In
113 // advantage of this path renderer comes from caching the tessellated geomet ry. 144 // the non-AA case, We skip paths thta don't have a key since the real advan tage of this path
145 // renderer comes from caching the tessellated geometry. In the AA case, we do not cache, so we
146 // accept paths without keys.
147 if (args.fAntiAlias) {
148 #ifdef SK_DISABLE_SCREENSPACE_TESS_AA_PATH_RENDERER
149 return false;
150 #else
151 SkPath path;
152 args.fShape->asPath(&path);
bsalomon 2016/08/31 14:19:19 If the path has a path effect or is stroked this o
Stephen White 2016/08/31 15:16:38 Good idea; done.
153 if (path.countVerbs() > 10) {
154 return false;
155 }
156 #endif
157 } else if (!args.fShape->hasUnstyledKey()) {
158 return false;
159 }
114 return !args.fShape->style().applies() && args.fShape->style().isSimpleFill( ) && 160 return !args.fShape->style().applies() && args.fShape->style().isSimpleFill( ) &&
bsalomon 2016/08/31 14:19:19 I realize that this is pre-existing (probably done
Stephen White 2016/08/31 15:16:38 Done.
115 !args.fAntiAlias && args.fShape->hasUnstyledKey() && !args.fShape->kn ownToBeConvex(); 161 !args.fShape->knownToBeConvex();
116 } 162 }
117 163
118 class TessellatingPathBatch : public GrVertexBatch { 164 class TessellatingPathBatch : public GrVertexBatch {
119 public: 165 public:
120 DEFINE_BATCH_CLASS_ID 166 DEFINE_BATCH_CLASS_ID
121 167
122 static GrDrawBatch* Create(const GrColor& color, 168 static GrDrawBatch* Create(const GrColor& color,
123 const GrShape& shape, 169 const GrShape& shape,
124 const SkMatrix& viewMatrix, 170 const SkMatrix& viewMatrix,
125 SkRect clipBounds) { 171 SkIRect devClipBounds,
126 return new TessellatingPathBatch(color, shape, viewMatrix, clipBounds); 172 bool antiAlias) {
173 return new TessellatingPathBatch(color, shape, viewMatrix, devClipBounds , antiAlias);
127 } 174 }
128 175
129 const char* name() const override { return "TessellatingPathBatch"; } 176 const char* name() const override { return "TessellatingPathBatch"; }
130 177
131 void computePipelineOptimizations(GrInitInvariantOutput* color, 178 void computePipelineOptimizations(GrInitInvariantOutput* color,
132 GrInitInvariantOutput* coverage, 179 GrInitInvariantOutput* coverage,
133 GrBatchToXPOverrides* overrides) const ove rride { 180 GrBatchToXPOverrides* overrides) const ove rride {
134 color->setKnownFourComponents(fColor); 181 color->setKnownFourComponents(fColor);
135 coverage->setUnknownSingleComponent(); 182 coverage->setUnknownSingleComponent();
136 } 183 }
137 184
138 private: 185 private:
139 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 186 void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
140 // Handle any color overrides 187 // Handle any color overrides
141 if (!overrides.readsColor()) { 188 if (!overrides.readsColor()) {
142 fColor = GrColor_ILLEGAL; 189 fColor = GrColor_ILLEGAL;
143 } 190 }
144 overrides.getOverrideColorIfSet(&fColor); 191 overrides.getOverrideColorIfSet(&fColor);
145 fPipelineInfo = overrides; 192 fPipelineInfo = overrides;
146 } 193 }
147 194
148 void draw(Target* target, const GrGeometryProcessor* gp) const { 195 SkPath getPath() const {
149 GrResourceProvider* rp = target->resourceProvider();
150 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
151 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix,
152 fShape.bounds());
153
154 SkPath path; 196 SkPath path;
bsalomon 2016/08/31 14:19:19 I think this can be: fShape.applyStyle(GrStyle::Ap
Stephen White 2016/08/31 15:16:38 Actually, given that onCanDrawPath() checks that !
bsalomon 2016/08/31 15:29:48 Agreed.
155 fShape.asPath(&path); 197 fShape.asPath(&path);
156 bool inverseFill = path.isInverseFillType(); 198 if (fShape.style().applies()) {
199 SkScalar styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix);
200 SkStrokeRec::InitStyle fill;
201 SkAssertResult(fShape.style().applyToPath(&path, &fill, path, styleS cale));
202 SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
203 }
204 return path;
205 }
206
207 void draw(Target* target, const GrGeometryProcessor* gp) const {
208 SkASSERT(!fAntiAlias);
209 GrResourceProvider* rp = target->resourceProvider();
210 bool inverseFill = fShape.inverseFilled();
157 // construct a cache key from the path's genID and the view matrix 211 // construct a cache key from the path's genID and the view matrix
158 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 212 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
159 GrUniqueKey key; 213 GrUniqueKey key;
160 static constexpr int kClipBoundsCnt = sizeof(fClipBounds) / sizeof(uint3 2_t); 214 static constexpr int kClipBoundsCnt = sizeof(fDevClipBounds) / sizeof(ui nt32_t);
161 int shapeKeyDataCnt = fShape.unstyledKeySize(); 215 int shapeKeyDataCnt = fShape.unstyledKeySize();
162 SkASSERT(shapeKeyDataCnt >= 0); 216 SkASSERT(shapeKeyDataCnt >= 0);
163 GrUniqueKey::Builder builder(&key, kDomain, shapeKeyDataCnt + kClipBound sCnt); 217 GrUniqueKey::Builder builder(&key, kDomain, shapeKeyDataCnt + kClipBound sCnt);
164 fShape.writeUnstyledKey(&builder[0]); 218 fShape.writeUnstyledKey(&builder[0]);
165 // For inverse fills, the tessellation is dependent on clip bounds. 219 // For inverse fills, the tessellation is dependent on clip bounds.
166 if (inverseFill) { 220 if (inverseFill) {
167 memcpy(&builder[shapeKeyDataCnt], &fClipBounds, sizeof(fClipBounds)) ; 221 memcpy(&builder[shapeKeyDataCnt], &fDevClipBounds, sizeof(fDevClipBo unds));
168 } else { 222 } else {
169 memset(&builder[shapeKeyDataCnt], 0, sizeof(fClipBounds)); 223 memset(&builder[shapeKeyDataCnt], 0, sizeof(fDevClipBounds));
170 } 224 }
171 builder.finish(); 225 builder.finish();
172 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrB uffer>(key)); 226 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrB uffer>(key));
173 int actualCount; 227 int actualCount;
228 SkScalar tol = GrPathUtils::kDefaultTolerance;
229 tol = GrPathUtils::scaleToleranceToSrc(tol, fViewMatrix, fShape.bounds() );
174 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { 230 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
175 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo unt); 231 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo unt);
176 return; 232 return;
177 } 233 }
178 234
235 SkRect clipBounds = SkRect::Make(fDevClipBounds);
236
237 SkMatrix vmi;
238 if (!fViewMatrix.invert(&vmi)) {
239 return;
240 }
241 vmi.mapRect(&clipBounds);
179 bool isLinear; 242 bool isLinear;
180 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( ); 243 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( );
181 StaticVertexAllocator allocator(rp, canMapVB); 244 StaticVertexAllocator allocator(gp->getVertexStride(), rp, canMapVB);
182 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo cator, &isLinear); 245 int count = GrTessellator::PathToTriangles(getPath(), tol, clipBounds, & allocator,
246 false, GrColor(), false, &isL inear);
183 if (count == 0) { 247 if (count == 0) {
184 return; 248 return;
185 } 249 }
186 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count); 250 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count);
187 TessInfo info; 251 TessInfo info;
188 info.fTolerance = isLinear ? 0 : tol; 252 info.fTolerance = isLinear ? 0 : tol;
189 info.fCount = count; 253 info.fCount = count;
190 key.setCustomData(SkData::MakeWithCopy(&info, sizeof(info))); 254 key.setCustomData(SkData::MakeWithCopy(&info, sizeof(info)));
191 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer()); 255 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer());
192 } 256 }
193 257
258 void drawAA(Target* target, const GrGeometryProcessor* gp) const {
259 SkASSERT(fAntiAlias);
260 SkPath path = getPath();
261 if (path.isEmpty()) {
262 return;
263 }
264 SkRect clipBounds = SkRect::Make(fDevClipBounds);
265 path.transform(fViewMatrix);
266 SkScalar tol = GrPathUtils::kDefaultTolerance;
267 bool isLinear;
268 DynamicVertexAllocator allocator(gp->getVertexStride(), target);
269 bool canTweakAlphaForCoverage = fPipelineInfo.canTweakAlphaForCoverage() ;
270 int count = GrTessellator::PathToTriangles(path, tol, clipBounds, &alloc ator,
271 true, fColor, canTweakAlphaFo rCoverage,
272 &isLinear);
273 if (count == 0) {
274 return;
275 }
276 drawVertices(target, gp, allocator.vertexBuffer(), allocator.firstVertex (), count);
277 }
278
194 void onPrepareDraws(Target* target) const override { 279 void onPrepareDraws(Target* target) const override {
195 sk_sp<GrGeometryProcessor> gp; 280 sk_sp<GrGeometryProcessor> gp;
196 { 281 {
197 using namespace GrDefaultGeoProcFactory; 282 using namespace GrDefaultGeoProcFactory;
198 283
199 Color color(fColor); 284 Color color(fColor);
200 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ? 285 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ?
201 LocalCoords::kUsePosition_Type : 286 LocalCoords::kUsePosition_Type :
202 LocalCoords::kUnused_Type); 287 LocalCoords::kUnused_Type);
203 Coverage::Type coverageType; 288 Coverage::Type coverageType;
204 if (fPipelineInfo.readsCoverage()) { 289 if (fAntiAlias) {
290 color = Color(Color::kAttribute_Type);
291 if (fPipelineInfo.canTweakAlphaForCoverage()) {
292 coverageType = Coverage::kSolid_Type;
293 } else {
294 coverageType = Coverage::kAttribute_Type;
295 }
296 } else if (fPipelineInfo.readsCoverage()) {
205 coverageType = Coverage::kSolid_Type; 297 coverageType = Coverage::kSolid_Type;
206 } else { 298 } else {
207 coverageType = Coverage::kNone_Type; 299 coverageType = Coverage::kNone_Type;
208 } 300 }
209 Coverage coverage(coverageType); 301 Coverage coverage(coverageType);
210 gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, fVi ewMatrix); 302 if (fAntiAlias) {
303 gp = GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverage , localCoords,
304 fViewMatrix);
305 } else {
306 gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, fViewMatrix);
307 }
211 } 308 }
212 this->draw(target, gp.get()); 309 if (fAntiAlias) {
310 this->drawAA(target, gp.get());
311 } else {
312 this->draw(target, gp.get());
313 }
213 } 314 }
214 315
215 void drawVertices(Target* target, const GrGeometryProcessor* gp, const GrBuf fer* vb, 316 void drawVertices(Target* target, const GrGeometryProcessor* gp, const GrBuf fer* vb,
216 int firstVertex, int count) const { 317 int firstVertex, int count) const {
217 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
218
219 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType 318 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType
220 : kTriangles_GrPri mitiveType; 319 : kTriangles_GrPri mitiveType;
221 GrMesh mesh; 320 GrMesh mesh;
222 mesh.init(primitiveType, vb, firstVertex, count); 321 mesh.init(primitiveType, vb, firstVertex, count);
223 target->draw(gp, mesh); 322 target->draw(gp, mesh);
224 } 323 }
225 324
226 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; } 325 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; }
227 326
228 TessellatingPathBatch(const GrColor& color, 327 TessellatingPathBatch(const GrColor& color,
229 const GrShape& shape, 328 const GrShape& shape,
230 const SkMatrix& viewMatrix, 329 const SkMatrix& viewMatrix,
231 const SkRect& clipBounds) 330 const SkIRect& devClipBounds,
331 bool antiAlias)
232 : INHERITED(ClassID()) 332 : INHERITED(ClassID())
233 , fColor(color) 333 , fColor(color)
234 , fShape(shape) 334 , fShape(shape)
235 , fViewMatrix(viewMatrix) { 335 , fViewMatrix(viewMatrix)
236 const SkRect& pathBounds = shape.bounds(); 336 , fDevClipBounds(devClipBounds)
237 fClipBounds = clipBounds; 337 , fAntiAlias(antiAlias) {
238 // Because the clip bounds are used to add a contour for inverse fills, they must also 338 SkRect devBounds;
239 // include the path bounds. 339 viewMatrix.mapRect(&devBounds, shape.bounds());
240 fClipBounds.join(pathBounds); 340 if (shape.inverseFilled()) {
241 const SkRect& srcBounds = shape.inverseFilled() ? fClipBounds : pathBoun ds; 341 // Because the clip bounds are used to add a contour for inverse fil ls, they must also
242 this->setTransformedBounds(srcBounds, viewMatrix, HasAABloat::kNo, IsZer oArea::kNo); 342 // include the path bounds.
343 devBounds.join(SkRect::Make(fDevClipBounds));
344 }
345 this->setBounds(devBounds, HasAABloat::kNo, IsZeroArea::kNo);
243 } 346 }
244 347
245 GrColor fColor; 348 GrColor fColor;
246 GrShape fShape; 349 GrShape fShape;
247 SkMatrix fViewMatrix; 350 SkMatrix fViewMatrix;
248 SkRect fClipBounds; // in source space 351 SkIRect fDevClipBounds;
352 bool fAntiAlias;
249 GrXPOverridesForBatch fPipelineInfo; 353 GrXPOverridesForBatch fPipelineInfo;
250 354
251 typedef GrVertexBatch INHERITED; 355 typedef GrVertexBatch INHERITED;
252 }; 356 };
253 357
254 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) { 358 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
255 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), 359 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
256 "GrTessellatingPathRenderer::onDrawPath"); 360 "GrTessellatingPathRenderer::onDrawPath");
257 SkASSERT(!args.fAntiAlias);
258
259 SkIRect clipBoundsI; 361 SkIRect clipBoundsI;
260 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont ext->height(), 362 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont ext->height(),
261 &clipBoundsI); 363 &clipBoundsI);
262 SkRect clipBounds = SkRect::Make(clipBoundsI);
263 SkMatrix vmi;
264 if (!args.fViewMatrix->invert(&vmi)) {
265 return false;
266 }
267 vmi.mapRect(&clipBounds);
268 SkPath path;
269 args.fShape->asPath(&path);
270 SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fPaint->g etColor(), 364 SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fPaint->g etColor(),
271 *args.fShape, 365 *args.fShape,
272 *args.fViewMat rix, clipBounds)); 366 *args.fViewMat rix,
367 clipBoundsI,
368 args.fAntiAlia s));
273 369
274 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHW AA(*args.fPaint)); 370 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHW AA(*args.fPaint));
275 pipelineBuilder.setUserStencil(args.fUserStencilSettings); 371 pipelineBuilder.setUserStencil(args.fUserStencilSettings);
276 372
277 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); 373 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
278 374
279 return true; 375 return true;
280 } 376 }
281 377
282 //////////////////////////////////////////////////////////////////////////////// /////////////////// 378 //////////////////////////////////////////////////////////////////////////////// ///////////////////
283 379
284 #ifdef GR_TEST_UTILS 380 #ifdef GR_TEST_UTILS
285 381
286 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) { 382 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) {
287 GrColor color = GrRandomColor(random); 383 GrColor color = GrRandomColor(random);
288 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); 384 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
289 SkPath path = GrTest::TestPath(random); 385 SkPath path = GrTest::TestPath(random);
290 SkRect clipBounds = GrTest::TestRect(random); 386 SkIRect devClipBounds = SkIRect::MakeXYWH(
291 SkMatrix vmi; 387 random->nextU(), random->nextU(), random->nextU(), random->nextU());
292 bool result = viewMatrix.invert(&vmi); 388 bool antiAlias = random->nextBool();
293 if (!result) {
294 SkFAIL("Cannot invert matrix\n");
295 }
296 vmi.mapRect(&clipBounds);
297 GrStyle style; 389 GrStyle style;
298 do { 390 do {
299 GrTest::TestStyle(random, &style); 391 GrTest::TestStyle(random, &style);
300 } while (style.strokeRec().isHairlineStyle()); 392 } while (style.strokeRec().isHairlineStyle());
301 GrShape shape(path, style); 393 GrShape shape(path, style);
302 return TessellatingPathBatch::Create(color, shape, viewMatrix, clipBounds); 394 return TessellatingPathBatch::Create(color, shape, viewMatrix, devClipBounds , antiAlias);
303 } 395 }
304 396
305 #endif 397 #endif
OLDNEW
« src/gpu/GrTessellator.cpp ('K') | « src/gpu/GrTessellator.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698