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

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

Issue 1957363002: Replace GrStrokeInfo with GrStyle. (Closed) Base URL: https://chromium.googlesource.com/skia.git@resscale
Patch Set: Remove dependency on SkDashPathEffect from GrDashingEffect.cpp Created 4 years, 7 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
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 "GrBatchFlushState.h" 10 #include "GrBatchFlushState.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 }; 98 };
99 99
100 } // namespace 100 } // namespace
101 101
102 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { 102 GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
103 } 103 }
104 104
105 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { 105 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t {
106 // This path renderer can draw all fill styles, all stroke styles except hai rlines, but does 106 // This path renderer can draw all fill styles, all stroke styles except hai rlines, but does
107 // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to 107 // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to
108 // simpler algorithms. 108 // simpler algorithms. Similary, we skip the non-hairlines that can be treat ed as hairline.
109 return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullp tr) && 109 // An arbitrary path effect could produce a hairline result so we pass on th ose.
110 !args.fAntiAlias && !args.fPath->isConvex(); 110 return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullpt r) &&
111 !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPa th->isConvex();
111 } 112 }
112 113
113 class TessellatingPathBatch : public GrVertexBatch { 114 class TessellatingPathBatch : public GrVertexBatch {
114 public: 115 public:
115 DEFINE_BATCH_CLASS_ID 116 DEFINE_BATCH_CLASS_ID
116 117
117 static GrDrawBatch* Create(const GrColor& color, 118 static GrDrawBatch* Create(const GrColor& color,
118 const SkPath& path, 119 const SkPath& path,
119 const GrStrokeInfo& stroke, 120 const GrStyle& style,
120 const SkMatrix& viewMatrix, 121 const SkMatrix& viewMatrix,
121 SkRect clipBounds) { 122 SkRect clipBounds) {
122 return new TessellatingPathBatch(color, path, stroke, viewMatrix, clipBo unds); 123 return new TessellatingPathBatch(color, path, style, viewMatrix, clipBou nds);
123 } 124 }
124 125
125 const char* name() const override { return "TessellatingPathBatch"; } 126 const char* name() const override { return "TessellatingPathBatch"; }
126 127
127 void computePipelineOptimizations(GrInitInvariantOutput* color, 128 void computePipelineOptimizations(GrInitInvariantOutput* color,
128 GrInitInvariantOutput* coverage, 129 GrInitInvariantOutput* coverage,
129 GrBatchToXPOverrides* overrides) const ove rride { 130 GrBatchToXPOverrides* overrides) const ove rride {
130 color->setKnownFourComponents(fColor); 131 color->setKnownFourComponents(fColor);
131 coverage->setUnknownSingleComponent(); 132 coverage->setUnknownSingleComponent();
132 } 133 }
133 134
134 private: 135 private:
135 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 136 void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
136 // Handle any color overrides 137 // Handle any color overrides
137 if (!overrides.readsColor()) { 138 if (!overrides.readsColor()) {
138 fColor = GrColor_ILLEGAL; 139 fColor = GrColor_ILLEGAL;
139 } 140 }
140 overrides.getOverrideColorIfSet(&fColor); 141 overrides.getOverrideColorIfSet(&fColor);
141 fPipelineInfo = overrides; 142 fPipelineInfo = overrides;
142 } 143 }
143 144
144 void draw(Target* target, const GrGeometryProcessor* gp) const { 145 void draw(Target* target, const GrGeometryProcessor* gp) const {
146 GrResourceProvider* rp = target->resourceProvider();
147 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
148 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix,
149 fPath.getBounds());
150
151 SkScalar styleScale = SK_Scalar1;
152 if (fStyle.applies()) {
153 styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix);
robertphillips 2016/05/09 20:05:28 stray ';' ?
bsalomon 2016/05/09 20:38:55 Done.
154 };
155
145 // 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
146 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 157 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
147 GrUniqueKey key; 158 GrUniqueKey key;
148 int clipBoundsSize32 = 159 int clipBoundsSize32 =
149 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0; 160 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0;
robertphillips 2016/05/09 20:05:28 can we rm the 32 suffix ?
bsalomon 2016/05/09 20:38:55 Done.
150 int strokeDataSize32 = fStroke.computeUniqueKeyFragmentData32Cnt(); 161 int styleDataSize32 = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffe ctAndStrokeRec);
151 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strok eDataSize32); 162 if (styleDataSize32 >= 0) {
152 builder[0] = fPath.getGenerationID(); 163 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + s tyleDataSize32);
153 builder[1] = fPath.getFillType(); 164 builder[0] = fPath.getGenerationID();
154 // For inverse fills, the tessellation is dependent on clip bounds. 165 builder[1] = fPath.getFillType();
155 if (fPath.isInverseFillType()) { 166 // For inverse fills, the tessellation is dependent on clip bounds.
156 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); 167 if (fPath.isInverseFillType()) {
157 } 168 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds));
158 fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]); 169 }
159 builder.finish(); 170 if (styleDataSize32) {
160 GrResourceProvider* rp = target->resourceProvider(); 171 GrStyle::WriteKey(&builder[2 + clipBoundsSize32], fStyle,
161 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrB uffer>(key)); 172 GrStyle::Apply::kPathEffectAndStrokeRec, style Scale);
162 int actualCount; 173 }
163 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; 174 builder.finish();
164 SkScalar tol = GrPathUtils::scaleToleranceToSrc( 175 SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey <GrBuffer>(key));
165 screenSpaceTol, fViewMatrix, fPath.getBounds()); 176 int actualCount;
166 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { 177 if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) {
167 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCo unt); 178 this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actu alCount);
168 return; 179 return;
180 }
169 } 181 }
170 182
171 SkPath path; 183 SkPath path;
172 GrStrokeInfo stroke(fStroke); 184 if (fStyle.applies()) {
173 if (stroke.isDashed()) { 185 SkStrokeRec::InitStyle fill;
174 if (!stroke.applyDashToPath(&path, &stroke, fPath)) { 186 SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale));
175 return; 187 SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
176 }
177 } else { 188 } else {
178 path = fPath; 189 path = fPath;
179 } 190 }
180 if (!stroke.isFillStyle()) {
181 stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale()));
182 if (!stroke.applyToPath(&path, path)) {
183 return;
184 }
185 stroke.setFillStyle();
186 }
187 bool isLinear; 191 bool isLinear;
188 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( ); 192 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( );
189 StaticVertexAllocator allocator(rp, canMapVB); 193 StaticVertexAllocator allocator(rp, canMapVB);
190 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo cator, &isLinear); 194 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo cator, &isLinear);
191 if (count == 0) { 195 if (count == 0) {
192 return; 196 return;
193 } 197 }
194 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count); 198 this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count);
195 if (!fPath.isVolatile()) { 199 if (!fPath.isVolatile() && styleDataSize32 >= 0) {
196 TessInfo info; 200 TessInfo info;
197 info.fTolerance = isLinear ? 0 : tol; 201 info.fTolerance = isLinear ? 0 : tol;
198 info.fCount = count; 202 info.fCount = count;
199 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info))); 203 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info)));
200 key.setCustomData(data.get()); 204 key.setCustomData(data.get());
201 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer()); 205 rp->assignUniqueKeyToResource(key, allocator.vertexBuffer());
202 SkPathPriv::AddGenIDChangeListener(fPath, new PathInvalidator(key)); 206 SkPathPriv::AddGenIDChangeListener(fPath, new PathInvalidator(key));
203 } 207 }
204 } 208 }
205 209
(...skipping 27 matching lines...) Expand all
233 : kTriangles_GrPri mitiveType; 237 : kTriangles_GrPri mitiveType;
234 GrMesh mesh; 238 GrMesh mesh;
235 mesh.init(primitiveType, vb, firstVertex, count); 239 mesh.init(primitiveType, vb, firstVertex, count);
236 target->draw(gp, mesh); 240 target->draw(gp, mesh);
237 } 241 }
238 242
239 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; } 243 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; }
240 244
241 TessellatingPathBatch(const GrColor& color, 245 TessellatingPathBatch(const GrColor& color,
242 const SkPath& path, 246 const SkPath& path,
243 const GrStrokeInfo& stroke, 247 const GrStyle& style,
244 const SkMatrix& viewMatrix, 248 const SkMatrix& viewMatrix,
245 const SkRect& clipBounds) 249 const SkRect& clipBounds)
246 : INHERITED(ClassID()) 250 : INHERITED(ClassID())
247 , fColor(color) 251 , fColor(color)
248 , fPath(path) 252 , fPath(path)
249 , fStroke(stroke) 253 , fStyle(style)
250 , fViewMatrix(viewMatrix) { 254 , fViewMatrix(viewMatrix) {
251 const SkRect& pathBounds = path.getBounds(); 255 const SkRect& pathBounds = path.getBounds();
252 fClipBounds = clipBounds; 256 fClipBounds = clipBounds;
253 // Because the clip bounds are used to add a contour for inverse fills, they must also 257 // Because the clip bounds are used to add a contour for inverse fills, they must also
254 // include the path bounds. 258 // include the path bounds.
255 fClipBounds.join(pathBounds); 259 fClipBounds.join(pathBounds);
256 if (path.isInverseFillType()) { 260 if (path.isInverseFillType()) {
257 fBounds = fClipBounds; 261 fBounds = fClipBounds;
258 } else { 262 } else {
259 fBounds = path.getBounds(); 263 fBounds = path.getBounds();
260 } 264 }
261 SkScalar radius = stroke.getInflationRadius(); 265 style.adjustBounds(&fBounds, fBounds);
262 fBounds.outset(radius, radius);
263 viewMatrix.mapRect(&fBounds); 266 viewMatrix.mapRect(&fBounds);
264 } 267 }
265 268
266 GrColor fColor; 269 GrColor fColor;
267 SkPath fPath; 270 SkPath fPath;
268 GrStrokeInfo fStroke; 271 GrStyle fStyle;
269 SkMatrix fViewMatrix; 272 SkMatrix fViewMatrix;
270 SkRect fClipBounds; // in source space 273 SkRect fClipBounds; // in source space
271 GrXPOverridesForBatch fPipelineInfo; 274 GrXPOverridesForBatch fPipelineInfo;
272 275
273 typedef GrVertexBatch INHERITED; 276 typedef GrVertexBatch INHERITED;
274 }; 277 };
275 278
276 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) { 279 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
277 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), 280 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
278 "GrTessellatingPathRenderer::onDrawPath"); 281 "GrTessellatingPathRenderer::onDrawPath");
279 SkASSERT(!args.fAntiAlias); 282 SkASSERT(!args.fAntiAlias);
280 const GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget(); 283 const GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
281 if (nullptr == rt) { 284 if (nullptr == rt) {
282 return false; 285 return false;
283 } 286 }
284 287
285 SkIRect clipBoundsI; 288 SkIRect clipBoundsI;
286 args.fPipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height( ), &clipBoundsI); 289 args.fPipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height( ), &clipBoundsI);
287 SkRect clipBounds = SkRect::Make(clipBoundsI); 290 SkRect clipBounds = SkRect::Make(clipBoundsI);
288 SkMatrix vmi; 291 SkMatrix vmi;
289 if (!args.fViewMatrix->invert(&vmi)) { 292 if (!args.fViewMatrix->invert(&vmi)) {
290 return false; 293 return false;
291 } 294 }
292 vmi.mapRect(&clipBounds); 295 vmi.mapRect(&clipBounds);
293 SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, * args.fPath, 296 SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, * args.fPath,
294 *args.fStroke, *args.fViewMatrix, 297 *args.fStyle, *args.fViewMatrix,
295 clipBounds)); 298 clipBounds));
296 args.fTarget->drawBatch(*args.fPipelineBuilder, batch); 299 args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
297 300
298 return true; 301 return true;
299 } 302 }
300 303
301 //////////////////////////////////////////////////////////////////////////////// /////////////////// 304 //////////////////////////////////////////////////////////////////////////////// ///////////////////
302 305
303 #ifdef GR_TEST_UTILS 306 #ifdef GR_TEST_UTILS
304 307
305 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) { 308 DRAW_BATCH_TEST_DEFINE(TesselatingPathBatch) {
306 GrColor color = GrRandomColor(random); 309 GrColor color = GrRandomColor(random);
307 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); 310 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
308 SkPath path = GrTest::TestPath(random); 311 SkPath path = GrTest::TestPath(random);
309 SkRect clipBounds = GrTest::TestRect(random); 312 SkRect clipBounds = GrTest::TestRect(random);
310 SkMatrix vmi; 313 SkMatrix vmi;
311 bool result = viewMatrix.invert(&vmi); 314 bool result = viewMatrix.invert(&vmi);
312 if (!result) { 315 if (!result) {
313 SkFAIL("Cannot invert matrix\n"); 316 SkFAIL("Cannot invert matrix\n");
314 } 317 }
315 vmi.mapRect(&clipBounds); 318 vmi.mapRect(&clipBounds);
316 GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random); 319 GrStyle style;
317 return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, cl ipBounds); 320 do {
321 GrTest::TestStyle(random, &style);
322 } while (style.strokeRec().isHairlineStyle());
323 return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBou nds);
318 } 324 }
319 325
320 #endif 326 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698