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

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

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

Powered by Google App Engine
This is Rietveld 408576698