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

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: Make stride part of the VertexAllocator. 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/GrDefaultGeoProcFactory.h ('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 uint8_t* 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 = static_cast<uint8_t*>(fVertexBuffer->map());
81 } else { 85 } else {
82 fVertices = new SkPoint[vertexCount]; 86 fVertices = new uint8_t[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 delete[] 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 uint8_t* 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 uint8_t* lock(int vertexCount) override {
116 fVertexCount = vertexCount;
117 fVertices = static_cast<uint8_t*>(fTarget->makeVertexSpace(stride(), ver texCount,
118 &fVertexBuffe r, &fFirstVertex));
119 return fVertices;
120 }
121 void unlock(int actualCount) override {
122 fTarget->putBackVertices(fVertexCount - actualCount, stride());
123 fVertices = nullptr;
124 }
125 const GrBuffer* vertexBuffer() const { return fVertexBuffer; }
126 int firstVertex() const { return fFirstVertex; }
127 private:
128 GrVertexBatch::Target* fTarget;
129 const GrBuffer* fVertexBuffer;
130 int fVertexCount;
131 int fFirstVertex;
132 uint8_t* fVertices;
101 }; 133 };
102 134
103 } // namespace 135 } // namespace
104 136
105 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { 137 GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
106 } 138 }
107 139
108 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { 140 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 141 // 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 142 // 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 143 // 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 144 // 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. 145 // the non-AA case, We skip paths thta don't have a key since the real advan tage of this path
146 // renderer comes from caching the tessellated geometry. In the AA case, we do not cache, so we
147 // accept paths without keys.
148 if (args.fAntiAlias) {
149 #ifdef SK_DISABLE_SCREENSPACE_TESS_AA_PATH_RENDERER
150 return false;
151 #else
152 SkPath path;
153 args.fShape->asPath(&path);
154 if (path.countVerbs() > 10) {
155 return false;
156 }
157 #endif
158 } else if (!args.fShape->hasUnstyledKey()) {
159 return false;
160 }
114 return !args.fShape->style().applies() && args.fShape->style().isSimpleFill( ) && 161 return !args.fShape->style().applies() && args.fShape->style().isSimpleFill( ) &&
115 !args.fAntiAlias && args.fShape->hasUnstyledKey() && !args.fShape->kn ownToBeConvex(); 162 !args.fShape->knownToBeConvex();
116 } 163 }
117 164
118 class TessellatingPathBatch : public GrVertexBatch { 165 class TessellatingPathBatch : public GrVertexBatch {
119 public: 166 public:
120 DEFINE_BATCH_CLASS_ID 167 DEFINE_BATCH_CLASS_ID
121 168
122 static GrDrawBatch* Create(const GrColor& color, 169 static GrDrawBatch* Create(const GrColor& color,
123 const GrShape& shape, 170 const GrShape& shape,
124 const SkMatrix& viewMatrix, 171 const SkMatrix& viewMatrix,
125 SkRect clipBounds) { 172 SkIRect devClipBounds,
126 return new TessellatingPathBatch(color, shape, viewMatrix, clipBounds); 173 bool antiAlias) {
174 return new TessellatingPathBatch(color, shape, viewMatrix, devClipBounds , antiAlias);
127 } 175 }
128 176
129 const char* name() const override { return "TessellatingPathBatch"; } 177 const char* name() const override { return "TessellatingPathBatch"; }
130 178
131 void computePipelineOptimizations(GrInitInvariantOutput* color, 179 void computePipelineOptimizations(GrInitInvariantOutput* color,
132 GrInitInvariantOutput* coverage, 180 GrInitInvariantOutput* coverage,
133 GrBatchToXPOverrides* overrides) const ove rride { 181 GrBatchToXPOverrides* overrides) const ove rride {
134 color->setKnownFourComponents(fColor); 182 color->setKnownFourComponents(fColor);
135 coverage->setUnknownSingleComponent(); 183 coverage->setUnknownSingleComponent();
136 } 184 }
137 185
138 private: 186 private:
139 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 187 void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
140 // Handle any color overrides 188 // Handle any color overrides
141 if (!overrides.readsColor()) { 189 if (!overrides.readsColor()) {
142 fColor = GrColor_ILLEGAL; 190 fColor = GrColor_ILLEGAL;
143 } 191 }
144 overrides.getOverrideColorIfSet(&fColor); 192 overrides.getOverrideColorIfSet(&fColor);
145 fPipelineInfo = overrides; 193 fPipelineInfo = overrides;
146 } 194 }
147 195
196 SkPath getPath() const {
197 SkPath path;
198 fShape.asPath(&path);
199 if (fShape.style().applies()) {
200 SkScalar styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix);
201 SkStrokeRec::InitStyle fill;
202 SkAssertResult(fShape.style().applyToPath(&path, &fill, path, styleS cale));
203 SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
204 }
205 return path;
206 }
207
148 void draw(Target* target, const GrGeometryProcessor* gp) const { 208 void draw(Target* target, const GrGeometryProcessor* gp) const {
149 GrResourceProvider* rp = target->resourceProvider(); 209 GrResourceProvider* rp = target->resourceProvider();
150 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; 210 bool inverseFill = fShape.inverseFilled();
151 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix,
152 fShape.bounds());
153
154 SkPath path;
155 fShape.asPath(&path);
156 bool inverseFill = path.isInverseFillType();
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 if (!fAntiAlias) {
230 tol = GrPathUtils::scaleToleranceToSrc(tol, fViewMatrix, fShape.boun ds());
231 }
174 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { 232 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
175 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo unt); 233 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo unt);
176 return; 234 return;
177 } 235 }
178 236
237 SkRect clipBounds = SkRect::Make(fDevClipBounds);
238
239 SkMatrix vmi;
240 if (!fViewMatrix.invert(&vmi)) {
241 return;
242 }
243 vmi.mapRect(&clipBounds);
179 bool isLinear; 244 bool isLinear;
180 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( ); 245 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( );
181 StaticVertexAllocator allocator(rp, canMapVB); 246 StaticVertexAllocator allocator(gp->getVertexStride(), rp, canMapVB);
182 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo cator, &isLinear); 247 int count = GrTessellator::PathToTriangles(getPath(), tol, clipBounds, & allocator,
248 fColor, fPipelineInfo.canTwea kAlphaForCoverage(),
249 fAntiAlias, &isLinear);
183 if (count == 0) { 250 if (count == 0) {
184 return; 251 return;
185 } 252 }
186 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count); 253 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count);
187 TessInfo info; 254 TessInfo info;
188 info.fTolerance = isLinear ? 0 : tol; 255 info.fTolerance = isLinear ? 0 : tol;
189 info.fCount = count; 256 info.fCount = count;
190 key.setCustomData(SkData::MakeWithCopy(&info, sizeof(info))); 257 key.setCustomData(SkData::MakeWithCopy(&info, sizeof(info)));
191 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer()); 258 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer());
192 } 259 }
193 260
261 void drawAA(Target* target, const GrGeometryProcessor* gp) const {
262 SkPath path = getPath();
263 if (path.isEmpty()) {
264 return;
265 }
266 SkRect clipBounds = SkRect::Make(fDevClipBounds);
267 path.transform(fViewMatrix);
268 SkScalar tol = GrPathUtils::kDefaultTolerance;
269 bool isLinear;
270 DynamicVertexAllocator allocator(gp->getVertexStride(), target);
271 int count = GrTessellator::PathToTriangles(path, tol, clipBounds, &alloc ator,
272 fColor, fPipelineInfo.canTwea kAlphaForCoverage(),
273 fAntiAlias, &isLinear);
274 if (count == 0) {
275 return;
276 }
277 drawVertices(target, gp, allocator.vertexBuffer(), allocator.firstVertex (), count);
278 }
279
194 void onPrepareDraws(Target* target) const override { 280 void onPrepareDraws(Target* target) const override {
195 sk_sp<GrGeometryProcessor> gp; 281 sk_sp<GrGeometryProcessor> gp;
196 { 282 {
197 using namespace GrDefaultGeoProcFactory; 283 using namespace GrDefaultGeoProcFactory;
198 284
199 Color color(fColor); 285 Color color(fColor);
200 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ? 286 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ?
201 LocalCoords::kUsePosition_Type : 287 LocalCoords::kUsePosition_Type :
202 LocalCoords::kUnused_Type); 288 LocalCoords::kUnused_Type);
203 Coverage::Type coverageType; 289 Coverage::Type coverageType;
204 if (fPipelineInfo.readsCoverage()) { 290 if (fAntiAlias) {
291 color = Color(Color::kAttribute_Type);
292 if (fPipelineInfo.canTweakAlphaForCoverage()) {
293 coverageType = Coverage::kSolid_Type;
294 } else {
295 coverageType = Coverage::kAttribute_Type;
296 }
297 } else if (fPipelineInfo.readsCoverage()) {
205 coverageType = Coverage::kSolid_Type; 298 coverageType = Coverage::kSolid_Type;
206 } else { 299 } else {
207 coverageType = Coverage::kNone_Type; 300 coverageType = Coverage::kNone_Type;
208 } 301 }
209 Coverage coverage(coverageType); 302 Coverage coverage(coverageType);
210 gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, fVi ewMatrix); 303 if (fAntiAlias) {
304 gp = GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverage , localCoords,
305 fViewMatrix);
306 } else {
307 gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, fViewMatrix);
308 }
211 } 309 }
212 this->draw(target, gp.get()); 310 if (fAntiAlias) {
311 this->drawAA(target, gp.get());
312 } else {
313 this->draw(target, gp.get());
314 }
213 } 315 }
214 316
215 void drawVertices(Target* target, const GrGeometryProcessor* gp, const GrBuf fer* vb, 317 void drawVertices(Target* target, const GrGeometryProcessor* gp, const GrBuf fer* vb,
216 int firstVertex, int count) const { 318 int firstVertex, int count) const {
217 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
218
219 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType 319 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType
220 : kTriangles_GrPri mitiveType; 320 : kTriangles_GrPri mitiveType;
221 GrMesh mesh; 321 GrMesh mesh;
222 mesh.init(primitiveType, vb, firstVertex, count); 322 mesh.init(primitiveType, vb, firstVertex, count);
223 target->draw(gp, mesh); 323 target->draw(gp, mesh);
224 } 324 }
225 325
226 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; } 326 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; }
227 327
228 TessellatingPathBatch(const GrColor& color, 328 TessellatingPathBatch(const GrColor& color,
229 const GrShape& shape, 329 const GrShape& shape,
230 const SkMatrix& viewMatrix, 330 const SkMatrix& viewMatrix,
231 const SkRect& clipBounds) 331 const SkIRect& devClipBounds,
332 bool antiAlias)
232 : INHERITED(ClassID()) 333 : INHERITED(ClassID())
233 , fColor(color) 334 , fColor(color)
234 , fShape(shape) 335 , fShape(shape)
235 , fViewMatrix(viewMatrix) { 336 , fViewMatrix(viewMatrix)
236 const SkRect& pathBounds = shape.bounds(); 337 , fDevClipBounds(devClipBounds)
237 fClipBounds = clipBounds; 338 , fAntiAlias(antiAlias) {
238 // Because the clip bounds are used to add a contour for inverse fills, they must also 339 SkRect devBounds;
239 // include the path bounds. 340 viewMatrix.mapRect(&devBounds, shape.bounds());
240 fClipBounds.join(pathBounds); 341 if (shape.inverseFilled()) {
241 const SkRect& srcBounds = shape.inverseFilled() ? fClipBounds : pathBoun ds; 342 // 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); 343 // include the path bounds.
344 devBounds.join(SkRect::Make(fDevClipBounds));
345 }
346 this->setBounds(devBounds, HasAABloat::kNo, IsZeroArea::kNo);
243 } 347 }
244 348
245 GrColor fColor; 349 GrColor fColor;
246 GrShape fShape; 350 GrShape fShape;
247 SkMatrix fViewMatrix; 351 SkMatrix fViewMatrix;
248 SkRect fClipBounds; // in source space 352 SkIRect fDevClipBounds;
353 bool fAntiAlias;
249 GrXPOverridesForBatch fPipelineInfo; 354 GrXPOverridesForBatch fPipelineInfo;
250 355
251 typedef GrVertexBatch INHERITED; 356 typedef GrVertexBatch INHERITED;
252 }; 357 };
253 358
254 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) { 359 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
255 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), 360 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
256 "GrTessellatingPathRenderer::onDrawPath"); 361 "GrTessellatingPathRenderer::onDrawPath");
257 SkASSERT(!args.fAntiAlias);
258
259 SkIRect clipBoundsI; 362 SkIRect clipBoundsI;
260 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont ext->height(), 363 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont ext->height(),
261 &clipBoundsI); 364 &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(), 365 SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fPaint->g etColor(),
271 *args.fShape, 366 *args.fShape,
272 *args.fViewMat rix, clipBounds)); 367 *args.fViewMat rix,
368 clipBoundsI,
369 args.fAntiAlia s));
273 370
274 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHW AA(*args.fPaint)); 371 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHW AA(*args.fPaint));
275 pipelineBuilder.setUserStencil(args.fUserStencilSettings); 372 pipelineBuilder.setUserStencil(args.fUserStencilSettings);
276 373
277 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); 374 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
278 375
279 return true; 376 return true;
280 } 377 }
281 378
282 //////////////////////////////////////////////////////////////////////////////// /////////////////// 379 //////////////////////////////////////////////////////////////////////////////// ///////////////////
283 380
284 #ifdef GR_TEST_UTILS 381 #ifdef GR_TEST_UTILS
285 382
286 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) { 383 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) {
287 GrColor color = GrRandomColor(random); 384 GrColor color = GrRandomColor(random);
288 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); 385 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
289 SkPath path = GrTest::TestPath(random); 386 SkPath path = GrTest::TestPath(random);
290 SkRect clipBounds = GrTest::TestRect(random); 387 SkIRect devClipBounds = SkIRect::MakeXYWH(
291 SkMatrix vmi; 388 random->nextU(), random->nextU(), random->nextU(), random->nextU());
292 bool result = viewMatrix.invert(&vmi); 389 bool antiAlias = random->nextBool();
293 if (!result) {
294 SkFAIL("Cannot invert matrix\n");
295 }
296 vmi.mapRect(&clipBounds);
297 GrStyle style; 390 GrStyle style;
298 do { 391 do {
299 GrTest::TestStyle(random, &style); 392 GrTest::TestStyle(random, &style);
300 } while (style.strokeRec().isHairlineStyle()); 393 } while (style.strokeRec().isHairlineStyle());
301 GrShape shape(path, style); 394 GrShape shape(path, style);
302 return TessellatingPathBatch::Create(color, shape, viewMatrix, clipBounds); 395 return TessellatingPathBatch::Create(color, shape, viewMatrix, devClipBounds , antiAlias);
303 } 396 }
304 397
305 #endif 398 #endif
OLDNEW
« src/gpu/GrDefaultGeoProcFactory.h ('K') | « src/gpu/GrTessellator.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698