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

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

Issue 2064753003: Remove style application from GrPathRenderer subclasses (Closed) Base URL: https://chromium.googlesource.com/skia.git@pathshape
Patch Set: Remove random style from DF batch test create, since it now only allows simple fill Created 4 years, 5 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/batches/GrStencilAndCoverPathRenderer.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"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 bool fCanMapVB; 98 bool fCanMapVB;
99 SkPoint* fVertices; 99 SkPoint* fVertices;
100 }; 100 };
101 101
102 } // namespace 102 } // namespace
103 103
104 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { 104 GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
105 } 105 }
106 106
107 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { 107 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t {
108 // This path renderer can draw all fill styles, all stroke styles except hai rlines, but does 108 // This path renderer can draw fill styles but does not do antialiasing. It can do convex and
109 // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to 109 // concave paths, but we'll leave the convex ones to simpler algorithms. We pass on paths that
110 // simpler algorithms. Similary, we skip the non-hairlines that can be treat ed as hairline. 110 // have styles, though they may come back around after applying the styling information to the
111 // An arbitrary path effect could produce a hairline result so we pass on th ose. 111 // geometry to create a filled path. We also skip paths that don't have a ke y since the real
112 return !IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix , nullptr) && 112 // advantage of this path renderer comes from caching the tessellated geomet ry.
113 !args.fShape->style().strokeRec().isHairlineStyle() && 113 return !args.fShape->style().applies() && args.fShape->style().isSimpleFill( ) &&
114 !args.fShape->style().hasNonDashPathEffect() && !args.fAntiAlias && 114 !args.fAntiAlias && args.fShape->hasUnstyledKey() && !args.fShape->kn ownToBeConvex();
115 !args.fShape->knownToBeConvex();
116 } 115 }
117 116
118 class TessellatingPathBatch : public GrVertexBatch { 117 class TessellatingPathBatch : public GrVertexBatch {
119 public: 118 public:
120 DEFINE_BATCH_CLASS_ID 119 DEFINE_BATCH_CLASS_ID
121 120
122 static GrDrawBatch* Create(const GrColor& color, 121 static GrDrawBatch* Create(const GrColor& color,
123 const SkPath& path, 122 const GrShape& shape,
124 const GrStyle& style,
125 const SkMatrix& viewMatrix, 123 const SkMatrix& viewMatrix,
126 SkRect clipBounds) { 124 SkRect clipBounds) {
127 return new TessellatingPathBatch(color, path, style, viewMatrix, clipBou nds); 125 return new TessellatingPathBatch(color, shape, viewMatrix, clipBounds);
128 } 126 }
129 127
130 const char* name() const override { return "TessellatingPathBatch"; } 128 const char* name() const override { return "TessellatingPathBatch"; }
131 129
132 void computePipelineOptimizations(GrInitInvariantOutput* color, 130 void computePipelineOptimizations(GrInitInvariantOutput* color,
133 GrInitInvariantOutput* coverage, 131 GrInitInvariantOutput* coverage,
134 GrBatchToXPOverrides* overrides) const ove rride { 132 GrBatchToXPOverrides* overrides) const ove rride {
135 color->setKnownFourComponents(fColor); 133 color->setKnownFourComponents(fColor);
136 coverage->setUnknownSingleComponent(); 134 coverage->setUnknownSingleComponent();
137 } 135 }
138 136
139 private: 137 private:
140 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 138 void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
141 // Handle any color overrides 139 // Handle any color overrides
142 if (!overrides.readsColor()) { 140 if (!overrides.readsColor()) {
143 fColor = GrColor_ILLEGAL; 141 fColor = GrColor_ILLEGAL;
144 } 142 }
145 overrides.getOverrideColorIfSet(&fColor); 143 overrides.getOverrideColorIfSet(&fColor);
146 fPipelineInfo = overrides; 144 fPipelineInfo = overrides;
147 } 145 }
148 146
149 void draw(Target* target, const GrGeometryProcessor* gp) const { 147 void draw(Target* target, const GrGeometryProcessor* gp) const {
150 GrResourceProvider* rp = target->resourceProvider(); 148 GrResourceProvider* rp = target->resourceProvider();
151 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; 149 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
152 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix, 150 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix,
153 fPath.getBounds()); 151 fShape.bounds());
154 152
155 SkScalar styleScale = SK_Scalar1; 153 SkPath path;
156 if (fStyle.applies()) { 154 fShape.asPath(&path);
157 styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix); 155 bool inverseFill = path.isInverseFillType();
158 }
159
160 // construct a cache key from the path's genID and the view matrix 156 // construct a cache key from the path's genID and the view matrix
161 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 157 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
162 GrUniqueKey key; 158 GrUniqueKey key;
163 int clipBoundsCnt = 159 static constexpr int kClipBoundsCnt = sizeof(fClipBounds) / sizeof(uint3 2_t);
164 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0; 160 int shapeKeyDataCnt = fShape.unstyledKeySize();
165 int styleDataCnt = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffectA ndStrokeRec); 161 SkASSERT(shapeKeyDataCnt >= 0);
166 if (styleDataCnt >= 0) { 162 GrUniqueKey::Builder builder(&key, kDomain, shapeKeyDataCnt + kClipBound sCnt);
167 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsCnt + styl eDataCnt); 163 fShape.writeUnstyledKey(&builder[0]);
168 builder[0] = fPath.getGenerationID(); 164 // For inverse fills, the tessellation is dependent on clip bounds.
169 builder[1] = fPath.getFillType(); 165 if (inverseFill) {
170 // For inverse fills, the tessellation is dependent on clip bounds. 166 memcpy(&builder[shapeKeyDataCnt], &fClipBounds, sizeof(fClipBounds)) ;
171 if (fPath.isInverseFillType()) { 167 } else {
172 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); 168 memset(&builder[shapeKeyDataCnt], 0, sizeof(fClipBounds));
173 } 169 }
174 if (styleDataCnt) { 170 builder.finish();
175 GrStyle::WriteKey(&builder[2 + clipBoundsCnt], fStyle, 171 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrB uffer>(key));
176 GrStyle::Apply::kPathEffectAndStrokeRec, style Scale); 172 int actualCount;
177 } 173 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
178 builder.finish(); 174 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo unt);
179 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey <GrBuffer>(key)); 175 return;
180 int actualCount;
181 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
182 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actu alCount);
183 return;
184 }
185 } 176 }
186 177
187 SkPath path;
188 if (fStyle.applies()) {
189 SkStrokeRec::InitStyle fill;
190 SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale));
191 SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
192 } else {
193 path = fPath;
194 }
195 bool isLinear; 178 bool isLinear;
196 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( ); 179 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( );
197 StaticVertexAllocator allocator(rp, canMapVB); 180 StaticVertexAllocator allocator(rp, canMapVB);
198 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo cator, &isLinear); 181 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo cator, &isLinear);
199 if (count == 0) { 182 if (count == 0) {
200 return; 183 return;
201 } 184 }
202 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count); 185 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count);
203 if (!fPath.isVolatile() && styleDataCnt >= 0) { 186 TessInfo info;
204 TessInfo info; 187 info.fTolerance = isLinear ? 0 : tol;
205 info.fTolerance = isLinear ? 0 : tol; 188 info.fCount = count;
206 info.fCount = count; 189 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info)));
207 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info))); 190 key.setCustomData(data.get());
208 key.setCustomData(data.get()); 191 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer());
209 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer());
210 SkPathPriv::AddGenIDChangeListener(fPath, new PathInvalidator(key));
211 }
212 } 192 }
213 193
214 void onPrepareDraws(Target* target) const override { 194 void onPrepareDraws(Target* target) const override {
215 sk_sp<GrGeometryProcessor> gp; 195 sk_sp<GrGeometryProcessor> gp;
216 { 196 {
217 using namespace GrDefaultGeoProcFactory; 197 using namespace GrDefaultGeoProcFactory;
218 198
219 Color color(fColor); 199 Color color(fColor);
220 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ? 200 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ?
221 LocalCoords::kUsePosition_Type : 201 LocalCoords::kUsePosition_Type :
(...skipping 17 matching lines...) Expand all
239 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType 219 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType
240 : kTriangles_GrPri mitiveType; 220 : kTriangles_GrPri mitiveType;
241 GrMesh mesh; 221 GrMesh mesh;
242 mesh.init(primitiveType, vb, firstVertex, count); 222 mesh.init(primitiveType, vb, firstVertex, count);
243 target->draw(gp, mesh); 223 target->draw(gp, mesh);
244 } 224 }
245 225
246 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; } 226 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; }
247 227
248 TessellatingPathBatch(const GrColor& color, 228 TessellatingPathBatch(const GrColor& color,
249 const SkPath& path, 229 const GrShape& shape,
250 const GrStyle& style,
251 const SkMatrix& viewMatrix, 230 const SkMatrix& viewMatrix,
252 const SkRect& clipBounds) 231 const SkRect& clipBounds)
253 : INHERITED(ClassID()) 232 : INHERITED(ClassID())
254 , fColor(color) 233 , fColor(color)
255 , fPath(path) 234 , fShape(shape)
256 , fStyle(style)
257 , fViewMatrix(viewMatrix) { 235 , fViewMatrix(viewMatrix) {
258 const SkRect& pathBounds = path.getBounds(); 236 const SkRect& pathBounds = shape.bounds();
259 fClipBounds = clipBounds; 237 fClipBounds = clipBounds;
260 // Because the clip bounds are used to add a contour for inverse fills, they must also 238 // Because the clip bounds are used to add a contour for inverse fills, they must also
261 // include the path bounds. 239 // include the path bounds.
262 fClipBounds.join(pathBounds); 240 fClipBounds.join(pathBounds);
263 if (path.isInverseFillType()) { 241 if (shape.inverseFilled()) {
264 fBounds = fClipBounds; 242 fBounds = fClipBounds;
265 } else { 243 } else {
266 fBounds = path.getBounds(); 244 fBounds = pathBounds;
267 } 245 }
268 style.adjustBounds(&fBounds, fBounds);
269 viewMatrix.mapRect(&fBounds); 246 viewMatrix.mapRect(&fBounds);
270 } 247 }
271 248
272 GrColor fColor; 249 GrColor fColor;
273 SkPath fPath; 250 GrShape fShape;
274 GrStyle fStyle;
275 SkMatrix fViewMatrix; 251 SkMatrix fViewMatrix;
276 SkRect fClipBounds; // in source space 252 SkRect fClipBounds; // in source space
277 GrXPOverridesForBatch fPipelineInfo; 253 GrXPOverridesForBatch fPipelineInfo;
278 254
279 typedef GrVertexBatch INHERITED; 255 typedef GrVertexBatch INHERITED;
280 }; 256 };
281 257
282 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) { 258 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
283 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), 259 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
284 "GrTessellatingPathRenderer::onDrawPath"); 260 "GrTessellatingPathRenderer::onDrawPath");
285 SkASSERT(!args.fAntiAlias); 261 SkASSERT(!args.fAntiAlias);
286 262
287 SkIRect clipBoundsI; 263 SkIRect clipBoundsI;
288 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont ext->height(), 264 args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawCont ext->height(),
289 &clipBoundsI); 265 &clipBoundsI);
290 SkRect clipBounds = SkRect::Make(clipBoundsI); 266 SkRect clipBounds = SkRect::Make(clipBoundsI);
291 SkMatrix vmi; 267 SkMatrix vmi;
292 if (!args.fViewMatrix->invert(&vmi)) { 268 if (!args.fViewMatrix->invert(&vmi)) {
293 return false; 269 return false;
294 } 270 }
295 vmi.mapRect(&clipBounds); 271 vmi.mapRect(&clipBounds);
296 SkPath path; 272 SkPath path;
297 args.fShape->asPath(&path); 273 args.fShape->asPath(&path);
298 SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, p ath, 274 SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, * args.fShape,
299 args.fShape->s tyle(), 275 *args.fViewMat rix, clipBounds));
300 *args.fViewMat rix,
301 clipBounds));
302 276
303 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHW AA(*args.fPaint)); 277 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHW AA(*args.fPaint));
304 pipelineBuilder.setUserStencil(args.fUserStencilSettings); 278 pipelineBuilder.setUserStencil(args.fUserStencilSettings);
305 279
306 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); 280 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
307 281
308 return true; 282 return true;
309 } 283 }
310 284
311 //////////////////////////////////////////////////////////////////////////////// /////////////////// 285 //////////////////////////////////////////////////////////////////////////////// ///////////////////
312 286
313 #ifdef GR_TEST_UTILS 287 #ifdef GR_TEST_UTILS
314 288
315 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) { 289 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) {
316 GrColor color = GrRandomColor(random); 290 GrColor color = GrRandomColor(random);
317 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); 291 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
318 SkPath path = GrTest::TestPath(random); 292 SkPath path = GrTest::TestPath(random);
319 SkRect clipBounds = GrTest::TestRect(random); 293 SkRect clipBounds = GrTest::TestRect(random);
320 SkMatrix vmi; 294 SkMatrix vmi;
321 bool result = viewMatrix.invert(&vmi); 295 bool result = viewMatrix.invert(&vmi);
322 if (!result) { 296 if (!result) {
323 SkFAIL("Cannot invert matrix\n"); 297 SkFAIL("Cannot invert matrix\n");
324 } 298 }
325 vmi.mapRect(&clipBounds); 299 vmi.mapRect(&clipBounds);
326 GrStyle style; 300 GrStyle style;
327 do { 301 do {
328 GrTest::TestStyle(random, &style); 302 GrTest::TestStyle(random, &style);
329 } while (style.strokeRec().isHairlineStyle()); 303 } while (style.strokeRec().isHairlineStyle());
330 return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBou nds); 304 GrShape shape(path, style);
305 return TessellatingPathBatch::Create(color, shape, viewMatrix, clipBounds);
331 } 306 }
332 307
333 #endif 308 #endif
OLDNEW
« no previous file with comments | « src/gpu/batches/GrStencilAndCoverPathRenderer.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698