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

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

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

Powered by Google App Engine
This is Rietveld 408576698