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

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

Issue 1860563002: Revert of added GrMSAAPathRenderer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 8 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/GrMSAAPathRenderer.h ('k') | src/gpu/batches/GrPathStencilSettings.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "GrMSAAPathRenderer.h"
9
10 #include "GrBatchFlushState.h"
11 #include "GrDefaultGeoProcFactory.h"
12 #include "GrPathStencilSettings.h"
13 #include "GrPathUtils.h"
14 #include "GrPipelineBuilder.h"
15 #include "GrMesh.h"
16 #include "SkGeometry.h"
17 #include "SkTraceEvent.h"
18 #include "glsl/GrGLSLGeometryProcessor.h"
19 #include "glsl/GrGLSLFragmentShaderBuilder.h"
20 #include "glsl/GrGLSLVertexShaderBuilder.h"
21 #include "glsl/GrGLSLProgramDataManager.h"
22 #include "glsl/GrGLSLUtil.h"
23 #include "gl/GrGLVaryingHandler.h"
24 #include "batches/GrRectBatchFactory.h"
25 #include "batches/GrVertexBatch.h"
26
27 static const float kTolerance = 0.5f;
28
29 ////////////////////////////////////////////////////////////////////////////////
30 // Helpers for drawPath
31
32 static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& strok e) {
33 if (!path.isInverseFillType()) {
34 return path.isConvex();
35 }
36 return false;
37 }
38
39 GrPathRenderer::StencilSupport
40 GrMSAAPathRenderer::onGetStencilSupport(const SkPath& path, const GrStrokeInfo& stroke) const {
41 if (single_pass_path(path, stroke)) {
42 return GrPathRenderer::kNoRestriction_StencilSupport;
43 } else {
44 return GrPathRenderer::kStencilOnly_StencilSupport;
45 }
46 }
47
48 struct MSAALineVertices {
49 struct Vertex {
50 SkPoint fPosition;
51 SkColor fColor;
52 };
53 Vertex* vertices;
54 Vertex* nextVertex;
55 #ifdef SK_DEBUG
56 Vertex* verticesEnd;
57 #endif
58 uint16_t* indices;
59 uint16_t* nextIndex;
60 };
61
62 struct MSAAQuadVertices {
63 struct Vertex {
64 SkPoint fPosition;
65 SkPoint fUV;
66 SkColor fColor;
67 };
68 Vertex* vertices;
69 Vertex* nextVertex;
70 #ifdef SK_DEBUG
71 Vertex* verticesEnd;
72 #endif
73 uint16_t* indices;
74 uint16_t* nextIndex;
75 };
76
77 static inline void append_contour_edge_indices(uint16_t fanCenterIdx,
78 uint16_t edgeV0Idx,
79 MSAALineVertices& lines) {
80 *(lines.nextIndex++) = fanCenterIdx;
81 *(lines.nextIndex++) = edgeV0Idx;
82 *(lines.nextIndex++) = edgeV0Idx + 1;
83 }
84
85 static inline void add_quad(MSAALineVertices& lines, MSAAQuadVertices& quads, co nst SkPoint pts[],
86 SkColor color, bool indexed, uint16_t subpathLineIdx Start) {
87 SkASSERT(lines.nextVertex < lines.verticesEnd);
88 *lines.nextVertex = { pts[2], color };
89 if (indexed) {
90 int prevIdx = (uint16_t) (lines.nextVertex - lines.vertices - 1);
91 if (prevIdx > subpathLineIdxStart) {
92 append_contour_edge_indices(subpathLineIdxStart, prevIdx, lines);
93 }
94 }
95 lines.nextVertex++;
96
97 SkASSERT(quads.nextVertex + 2 < quads.verticesEnd);
98 // the texture coordinates are drawn from the Loop-Blinn rendering algorithm
99 *(quads.nextVertex++) = { pts[0], SkPoint::Make(0.0, 0.0), color };
100 *(quads.nextVertex++) = { pts[1], SkPoint::Make(0.5, 0.0), color };
101 *(quads.nextVertex++) = { pts[2], SkPoint::Make(1.0, 1.0), color };
102 if (indexed) {
103 uint16_t offset = (uint16_t) (quads.nextVertex - quads.vertices) - 3;
104 *(quads.nextIndex++) = offset++;
105 *(quads.nextIndex++) = offset++;
106 *(quads.nextIndex++) = offset++;
107 }
108 }
109
110 class MSAAQuadProcessor : public GrGeometryProcessor {
111 public:
112 static GrGeometryProcessor* Create(const SkMatrix& viewMatrix) {
113 return new MSAAQuadProcessor(viewMatrix);
114 }
115
116 virtual ~MSAAQuadProcessor() {}
117
118 const char* name() const override { return "MSAAQuadProcessor"; }
119
120 const Attribute* inPosition() const { return fInPosition; }
121 const Attribute* inUV() const { return fInUV; }
122 const Attribute* inColor() const { return fInColor; }
123 const SkMatrix& viewMatrix() const { return fViewMatrix; }
124 const SkMatrix& localMatrix() const { return SkMatrix::I(); }
125
126 class GLSLProcessor : public GrGLSLGeometryProcessor {
127 public:
128 GLSLProcessor(const GrGeometryProcessor& qpr) {}
129
130 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
131 const MSAAQuadProcessor& qp = args.fGP.cast<MSAAQuadProcessor>();
132 GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
133 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
134 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
135
136 // emit attributes
137 varyingHandler->emitAttributes(qp);
138 varyingHandler->addPassThroughAttribute(qp.inColor(), args.fOutputCo lor);
139
140 GrGLSLVertToFrag uv(kVec2f_GrSLType);
141 varyingHandler->addVarying("uv", &uv, kHigh_GrSLPrecision);
142 vsBuilder->codeAppendf("%s = %s;", uv.vsOut(), qp.inUV()->fName);
143
144 // Setup position
145 this->setupPosition(vsBuilder, uniformHandler, gpArgs, qp.inPosition ()->fName,
146 qp.viewMatrix(), &fViewMatrixUniform);
147
148 // emit transforms
149 this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpAr gs->fPositionVar,
150 qp.inPosition()->fName, SkMatrix::I(), args.fTr ansformsIn,
151 args.fTransformsOut);
152
153 GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
154 fsBuilder->codeAppendf("if (%s.x * %s.x >= %s.y) discard;", uv.fsIn( ), uv.fsIn(),
155 uv.fsIn( ));
156 fsBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputCoverage);
157 }
158
159 static inline void GenKey(const GrGeometryProcessor& gp,
160 const GrGLSLCaps&,
161 GrProcessorKeyBuilder* b) {
162 const MSAAQuadProcessor& qp = gp.cast<MSAAQuadProcessor>();
163 uint32_t key = 0;
164 key |= qp.viewMatrix().hasPerspective() ? 0x1 : 0x0;
165 key |= qp.viewMatrix().isIdentity() ? 0x2: 0x0;
166 b->add32(key);
167 }
168
169 virtual void setData(const GrGLSLProgramDataManager& pdman,
170 const GrPrimitiveProcessor& gp) override {
171 const MSAAQuadProcessor& qp = gp.cast<MSAAQuadProcessor>();
172 if (!qp.viewMatrix().isIdentity()) {
173 float viewMatrix[3 * 3];
174 GrGLSLGetMatrix<3>(viewMatrix, qp.viewMatrix());
175 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
176 }
177 }
178
179 void setTransformData(const GrPrimitiveProcessor& primProc,
180 const GrGLSLProgramDataManager& pdman,
181 int index,
182 const SkTArray<const GrCoordTransform*, true>& tra nsforms) override {
183 this->setTransformDataHelper<MSAAQuadProcessor>(primProc, pdman, ind ex, transforms);
184 }
185
186 private:
187 typedef GrGLSLGeometryProcessor INHERITED;
188
189 UniformHandle fViewMatrixUniform;
190 };
191
192 virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
193 GrProcessorKeyBuilder* b) const override {
194 GLSLProcessor::GenKey(*this, caps, b);
195 }
196
197 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) cons t override {
198 return new GLSLProcessor(*this);
199 }
200
201 private:
202 MSAAQuadProcessor(const SkMatrix& viewMatrix)
203 : fViewMatrix(viewMatrix) {
204 this->initClassID<MSAAQuadProcessor>();
205 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVe rtexAttribType,
206 kHigh_GrSLPrecision));
207 fInUV = &this->addVertexAttrib(Attribute("inUV", kVec2f_GrVertexAttribTy pe,
208 kHigh_GrSLPrecision));
209 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexA ttribType));
210 this->setSampleShading(1.0f);
211 }
212
213 const Attribute* fInPosition;
214 const Attribute* fInUV;
215 const Attribute* fInColor;
216 SkMatrix fViewMatrix;
217
218 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
219
220 typedef GrGeometryProcessor INHERITED;
221 };
222
223 class MSAAPathBatch : public GrVertexBatch {
224 public:
225 DEFINE_BATCH_CLASS_ID
226
227 struct Geometry {
228 GrColor fColor;
229 SkPath fPath;
230 SkScalar fTolerance;
231 };
232
233 static MSAAPathBatch* Create(const Geometry& geometry, const SkMatrix& viewM atrix,
234 const SkRect& devBounds) {
235 return new MSAAPathBatch(geometry, viewMatrix, devBounds);
236 }
237
238 const char* name() const override { return "MSAAPathBatch"; }
239
240 void computePipelineOptimizations(GrInitInvariantOutput* color,
241 GrInitInvariantOutput* coverage,
242 GrBatchToXPOverrides* overrides) const ove rride {
243 // When this is called on a batch, there is only one geometry bundle
244 color->setKnownFourComponents(fGeoData[0].fColor);
245 coverage->setKnownSingleComponent(0xff);
246 }
247
248 bool isValid() const {
249 return !fIsIndexed || fMaxLineIndices <= SK_MaxU16;
250 }
251
252 private:
253 void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
254 // Handle any color overrides
255 if (!overrides.readsColor()) {
256 fGeoData[0].fColor = GrColor_ILLEGAL;
257 }
258 overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
259 }
260
261 void computeWorstCasePointCount(const SkPath& path, int* subpaths, SkScalar tol,
262 int* outLinePointCount, int* outQuadPointCou nt) const {
263 int linePointCount = 0;
264 int quadPointCount = 0;
265 *subpaths = 1;
266
267 bool first = true;
268
269 SkPath::Iter iter(path, false);
270 SkPath::Verb verb;
271
272 SkPoint pts[4];
273 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
274 switch (verb) {
275 case SkPath::kLine_Verb:
276 linePointCount += 1;
277 break;
278 case SkPath::kConic_Verb: {
279 SkScalar weight = iter.conicWeight();
280 SkAutoConicToQuads converter;
281 converter.computeQuads(pts, weight, kTolerance);
282 int quadPts = converter.countQuads();
283 linePointCount += quadPts;
284 quadPointCount += 3 * quadPts;
285 }
286 case SkPath::kQuad_Verb:
287 linePointCount += 1;
288 quadPointCount += 3;
289 break;
290 case SkPath::kCubic_Verb: {
291 SkSTArray<15, SkPoint, true> quadPts;
292 GrPathUtils::convertCubicToQuads(pts, kTolerance, &quadPts);
293 int count = quadPts.count();
294 linePointCount += count / 3;
295 quadPointCount += count;
296 break;
297 }
298 case SkPath::kMove_Verb:
299 linePointCount += 1;
300 if (!first) {
301 ++(*subpaths);
302 }
303 break;
304 default:
305 break;
306 }
307 first = false;
308 }
309 *outLinePointCount = linePointCount;
310 *outQuadPointCount = quadPointCount;
311 }
312
313 void onPrepareDraws(Target* target) const override {
314 SkASSERT(this->isValid());
315 if (fMaxLineVertices == 0) {
316 SkASSERT(fMaxQuadVertices == 0);
317 return;
318 }
319
320 GrPrimitiveType primitiveType = fIsIndexed ? kTriangles_GrPrimitiveType
321 : kTriangleFan_GrPrimitiveTyp e;
322
323 // allocate vertex / index buffers
324 const GrBuffer* lineVertexBuffer;
325 int firstLineVertex;
326 MSAALineVertices lines;
327 size_t lineVertexStride = sizeof(MSAALineVertices::Vertex);
328 lines.vertices = (MSAALineVertices::Vertex*) target->makeVertexSpace(lin eVertexStride,
329 fMa xLineVertices,
330 &li neVertexBuffer,
331 &fi rstLineVertex);
332 if (!lines.vertices) {
333 SkDebugf("Could not allocate vertices\n");
334 return;
335 }
336 lines.nextVertex = lines.vertices;
337 SkDEBUGCODE(lines.verticesEnd = lines.vertices + fMaxLineVertices;)
338
339 MSAAQuadVertices quads;
340 size_t quadVertexStride = sizeof(MSAAQuadVertices::Vertex);
341 SkAutoFree quadVertexPtr(sk_malloc_throw(fMaxQuadVertices * quadVertexSt ride));
342 quads.vertices = (MSAAQuadVertices::Vertex*) quadVertexPtr.get();
343 quads.nextVertex = quads.vertices;
344 SkDEBUGCODE(quads.verticesEnd = quads.vertices + fMaxQuadVertices;)
345
346 const GrBuffer* lineIndexBuffer = nullptr;
347 int firstLineIndex;
348 if (fIsIndexed) {
349 lines.indices = target->makeIndexSpace(fMaxLineIndices, &lineIndexBu ffer,
350 &firstLineIndex);
351 if (!lines.indices) {
352 SkDebugf("Could not allocate indices\n");
353 return;
354 }
355 lines.nextIndex = lines.indices;
356 } else {
357 lines.indices = nullptr;
358 lines.nextIndex = nullptr;
359 }
360
361 SkAutoFree quadIndexPtr;
362 if (fIsIndexed) {
363 quads.indices = (uint16_t*) sk_malloc_throw(fMaxQuadIndices * sizeof (uint16_t));
364 quadIndexPtr.set(quads.indices);
365 quads.nextIndex = quads.indices;
366 } else {
367 quads.indices = nullptr;
368 quads.nextIndex = nullptr;
369 }
370
371 // fill buffers
372 for (int i = 0; i < fGeoData.count(); i++) {
373 const Geometry& args = fGeoData[i];
374
375 if (!this->createGeom(lines,
376 quads,
377 args.fPath,
378 args.fTolerance,
379 fViewMatrix,
380 args.fColor,
381 fIsIndexed)) {
382 return;
383 }
384 }
385 int lineVertexOffset = (int) (lines.nextVertex - lines.vertices);
386 int lineIndexOffset = (int) (lines.nextIndex - lines.indices);
387 SkASSERT(lineVertexOffset <= fMaxLineVertices && lineIndexOffset <= fMax LineIndices);
388 int quadVertexOffset = (int) (quads.nextVertex - quads.vertices);
389 int quadIndexOffset = (int) (quads.nextIndex - quads.indices);
390 SkASSERT(quadVertexOffset <= fMaxQuadVertices && quadIndexOffset <= fMax QuadIndices);
391
392 if (lineVertexOffset) {
393 SkAutoTUnref<const GrGeometryProcessor> lineGP;
394 {
395 using namespace GrDefaultGeoProcFactory;
396 lineGP.reset(GrDefaultGeoProcFactory::Create(Color(Color::kAttri bute_Type),
397 Coverage(255),
398 LocalCoords(LocalCo ords::kUnused_Type),
399 fViewMatrix));
400 }
401 SkASSERT(lineVertexStride == lineGP->getVertexStride());
402
403 GrMesh lineMeshes;
404 if (fIsIndexed) {
405 lineMeshes.initIndexed(primitiveType, lineVertexBuffer, lineInde xBuffer,
406 firstLineVertex, firstLineIndex, lineVe rtexOffset,
407 lineIndexOffset);
408 } else {
409 lineMeshes.init(primitiveType, lineVertexBuffer, firstLineVertex ,
410 lineVertexOffset);
411 }
412 target->draw(lineGP, lineMeshes);
413 }
414
415 if (quadVertexOffset) {
416 SkAutoTUnref<const GrGeometryProcessor> quadGP(MSAAQuadProcessor::Cr eate(fViewMatrix));
417 SkASSERT(quadVertexStride == quadGP->getVertexStride());
418
419 const GrBuffer* quadVertexBuffer;
420 int firstQuadVertex;
421 MSAAQuadVertices::Vertex* quadVertices = (MSAAQuadVertices::Vertex*)
422 target->makeVertexSpace(quadVertexStride, quadVertexOffset, &quadVertexBuffer,
423 &firstQuadVertex);
424 memcpy(quadVertices, quads.vertices, quadVertexStride * quadVertexOf fset);
425 GrMesh quadMeshes;
426 if (fIsIndexed) {
427 const GrBuffer* quadIndexBuffer;
428 int firstQuadIndex;
429 uint16_t* quadIndices = (uint16_t*) target->makeIndexSpace(quadI ndexOffset,
430 &quad IndexBuffer,
431 &firs tQuadIndex);
432 memcpy(quadIndices, quads.indices, sizeof(uint16_t) * quadIndexO ffset);
433 quadMeshes.initIndexed(kTriangles_GrPrimitiveType, quadVertexBuf fer,
434 quadIndexBuffer, firstQuadVertex, firstQu adIndex,
435 quadVertexOffset, quadIndexOffset);
436 } else {
437 quadMeshes.init(kTriangles_GrPrimitiveType, quadVertexBuffer, fi rstQuadVertex,
438 quadVertexOffset);
439 }
440 target->draw(quadGP, quadMeshes);
441 }
442 }
443
444 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
445
446 MSAAPathBatch(const Geometry& geometry, const SkMatrix& viewMatrix, const Sk Rect& devBounds)
447 : INHERITED(ClassID())
448 , fViewMatrix(viewMatrix) {
449 fGeoData.push_back(geometry);
450 this->setBounds(devBounds);
451 int contourCount;
452 this->computeWorstCasePointCount(geometry.fPath, &contourCount, kToleran ce,
453 &fMaxLineVertices, &fMaxQuadVertices);
454 fMaxLineIndices = fMaxLineVertices * 3;
455 fMaxQuadIndices = fMaxQuadVertices * 3;
456 fIsIndexed = contourCount > 1;
457 }
458
459 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
460 MSAAPathBatch* that = t->cast<MSAAPathBatch>();
461 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(),
462 that->bounds(), caps)) {
463 return false;
464 }
465
466 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
467 return false;
468 }
469
470 if (fMaxLineIndices + that->fMaxLineIndices > SK_MaxU16) {
471 return false;
472 }
473 SkASSERT(fMaxQuadIndices + that->fMaxQuadIndices <= SK_MaxU16);
474
475 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
476 this->joinBounds(that->bounds());
477 fIsIndexed = true;
478 fMaxLineVertices += that->fMaxLineVertices;
479 fMaxQuadVertices += that->fMaxQuadVertices;
480 fMaxLineIndices += that->fMaxLineIndices;
481 fMaxQuadIndices += that->fMaxQuadIndices;
482 return true;
483 }
484
485 bool createGeom(MSAALineVertices& lines,
486 MSAAQuadVertices& quads,
487 const SkPath& path,
488 SkScalar srcSpaceTol,
489 const SkMatrix& m,
490 SkColor color,
491 bool isIndexed) const {
492 {
493 uint16_t subpathIdxStart = (uint16_t) (lines.nextVertex - lines.vert ices);
494
495 SkPoint pts[4];
496
497 bool first = true;
498 SkPath::Iter iter(path, false);
499
500 bool done = false;
501 while (!done) {
502 SkPath::Verb verb = iter.next(pts);
503 switch (verb) {
504 case SkPath::kMove_Verb:
505 if (!first) {
506 uint16_t currIdx = (uint16_t) (lines.nextVertex - li nes.vertices);
507 subpathIdxStart = currIdx;
508 }
509 SkASSERT(lines.nextVertex < lines.verticesEnd);
510 *(lines.nextVertex++) = { pts[0], color };
511 break;
512 case SkPath::kLine_Verb:
513 if (isIndexed) {
514 uint16_t prevIdx = (uint16_t) (lines.nextVertex - li nes.vertices - 1);
515 if (prevIdx > subpathIdxStart) {
516 append_contour_edge_indices(subpathIdxStart, pre vIdx, lines);
517 }
518 }
519 SkASSERT(lines.nextVertex < lines.verticesEnd);
520 *(lines.nextVertex++) = { pts[1], color };
521 break;
522 case SkPath::kConic_Verb: {
523 SkScalar weight = iter.conicWeight();
524 SkAutoConicToQuads converter;
525 const SkPoint* quadPts = converter.computeQuads(pts, wei ght,
526 kToleran ce);
527 for (int i = 0; i < converter.countQuads(); ++i) {
528 add_quad(lines, quads, quadPts + i * 2, color, isInd exed,
529 subpathIdxStart);
530 }
531 break;
532 }
533 case SkPath::kQuad_Verb: {
534 add_quad(lines, quads, pts, color, isIndexed, subpathIdx Start);
535 break;
536 }
537 case SkPath::kCubic_Verb: {
538 SkSTArray<15, SkPoint, true> quadPts;
539 GrPathUtils::convertCubicToQuads(pts, kTolerance, &quadP ts);
540 int count = quadPts.count();
541 for (int i = 0; i < count; i += 3) {
542 add_quad(lines, quads, &quadPts[i], color, isIndexed , subpathIdxStart);
543 }
544 break;
545 }
546 case SkPath::kClose_Verb:
547 break;
548 case SkPath::kDone_Verb:
549 done = true;
550 }
551 first = false;
552 }
553 }
554 return true;
555 }
556
557 SkSTArray<1, Geometry, true> fGeoData;
558
559 SkMatrix fViewMatrix;
560 int fMaxLineVertices;
561 int fMaxQuadVertices;
562 int fMaxLineIndices;
563 int fMaxQuadIndices;
564 bool fIsIndexed;
565
566 typedef GrVertexBatch INHERITED;
567 };
568
569 bool GrMSAAPathRenderer::internalDrawPath(GrDrawTarget* target,
570 GrPipelineBuilder* pipelineBuilder,
571 GrColor color,
572 const SkMatrix& viewMatrix,
573 const SkPath& path,
574 const GrStrokeInfo& origStroke,
575 bool stencilOnly) {
576 SkTCopyOnFirstWrite<GrStrokeInfo> stroke(origStroke);
577
578 const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory();
579 SkAutoTUnref<const GrXPFactory> backupXPFactory(SkSafeRef(xpFactory));
580 // face culling doesn't make sense here
581 SkASSERT(GrPipelineBuilder::kBoth_DrawFace == pipelineBuilder->getDrawFace() );
582
583 int passCount = 0;
584 const GrStencilSettings* passes[3];
585 GrPipelineBuilder::DrawFace drawFace[3];
586 bool reverse = false;
587 bool lastPassIsBounds;
588
589 if (single_pass_path(path, *stroke)) {
590 passCount = 1;
591 if (stencilOnly) {
592 passes[0] = &gDirectToStencil;
593 } else {
594 passes[0] = nullptr;
595 }
596 drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
597 lastPassIsBounds = false;
598 } else {
599 switch (path.getFillType()) {
600 case SkPath::kInverseEvenOdd_FillType:
601 reverse = true;
602 // fallthrough
603 case SkPath::kEvenOdd_FillType:
604 passes[0] = &gEOStencilPass;
605 if (stencilOnly) {
606 passCount = 1;
607 lastPassIsBounds = false;
608 } else {
609 passCount = 2;
610 lastPassIsBounds = true;
611 if (reverse) {
612 passes[1] = &gInvEOColorPass;
613 } else {
614 passes[1] = &gEOColorPass;
615 }
616 }
617 drawFace[0] = drawFace[1] = GrPipelineBuilder::kBoth_DrawFace;
618 break;
619
620 case SkPath::kInverseWinding_FillType:
621 reverse = true;
622 // fallthrough
623 case SkPath::kWinding_FillType:
624 passes[0] = &gWindStencilSeparateWithWrap;
625 passCount = 2;
626 drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
627 if (stencilOnly) {
628 lastPassIsBounds = false;
629 --passCount;
630 } else {
631 lastPassIsBounds = true;
632 drawFace[passCount-1] = GrPipelineBuilder::kBoth_DrawFace;
633 if (reverse) {
634 passes[passCount-1] = &gInvWindColorPass;
635 } else {
636 passes[passCount-1] = &gWindColorPass;
637 }
638 }
639 break;
640 default:
641 SkDEBUGFAIL("Unknown path fFill!");
642 return false;
643 }
644 }
645
646 SkRect devBounds;
647 GetPathDevBounds(path, pipelineBuilder->getRenderTarget(), viewMatrix, &devB ounds);
648
649 for (int p = 0; p < passCount; ++p) {
650 pipelineBuilder->setDrawFace(drawFace[p]);
651 if (passes[p]) {
652 *pipelineBuilder->stencil() = *passes[p];
653 }
654
655 if (lastPassIsBounds && (p == passCount-1)) {
656 // Reset the XP Factory on pipelineBuilder
657 pipelineBuilder->setXPFactory(backupXPFactory);
658 SkRect bounds;
659 SkMatrix localMatrix = SkMatrix::I();
660 if (reverse) {
661 SkASSERT(pipelineBuilder->getRenderTarget());
662 // draw over the dev bounds (which will be the whole dst surface for inv fill).
663 bounds = devBounds;
664 SkMatrix vmi;
665 // mapRect through persp matrix may not be correct
666 if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
667 vmi.mapRect(&bounds);
668 } else {
669 if (!viewMatrix.invert(&localMatrix)) {
670 return false;
671 }
672 }
673 } else {
674 bounds = path.getBounds();
675 }
676 const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? S kMatrix::I() :
677 v iewMatrix;
678 SkAutoTUnref<GrDrawBatch> batch(
679 GrRectBatchFactory::CreateNonAAFill(color, viewM, bounds, nu llptr,
680 &localMatrix));
681 target->drawBatch(*pipelineBuilder, batch);
682 } else {
683 if (passCount > 1) {
684 pipelineBuilder->setDisableColorXPFactory();
685 }
686
687 MSAAPathBatch::Geometry geometry;
688 geometry.fColor = color;
689 geometry.fPath = path;
690 geometry.fTolerance = kTolerance;
691
692 SkAutoTUnref<MSAAPathBatch> batch(MSAAPathBatch::Create(geometry, vi ewMatrix,
693 devBounds));
694 if (batch->isValid()) {
695 target->drawBatch(*pipelineBuilder, batch);
696 }
697 else {
698 return false;
699 }
700 }
701 }
702 return true;
703 }
704
705 bool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
706 return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullp tr) &&
707 !args.fAntiAlias;
708 }
709
710 bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
711 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrMSAAPathRenderer ::onDrawPath");
712 SkPath path;
713 GrStrokeInfo stroke(*args.fStroke);
714 if (stroke.isDashed()) {
715 if (!stroke.applyDashToPath(&path, &stroke, *args.fPath)) {
716 return false;
717 }
718 } else {
719 path = *args.fPath;
720 }
721 if (!stroke.isFillStyle()) {
722 stroke.setResScale(SkScalarAbs(args.fViewMatrix->getMaxScale()));
723 if (!stroke.applyToPath(&path, path)) {
724 return false;
725 }
726 stroke.setFillStyle();
727 }
728 return this->internalDrawPath(args.fTarget,
729 args.fPipelineBuilder,
730 args.fColor,
731 *args.fViewMatrix,
732 path,
733 stroke,
734 false);
735 }
736
737 void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) {
738 GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrMSAAPathRenderer: :onStencilPath");
739 SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
740 SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
741 this->internalDrawPath(args.fTarget, args.fPipelineBuilder, GrColor_WHITE, * args.fViewMatrix,
742 *args.fPath, *args.fStroke, true);
743 }
744
745 //////////////////////////////////////////////////////////////////////////////// ///////////////////
OLDNEW
« no previous file with comments | « src/gpu/batches/GrMSAAPathRenderer.h ('k') | src/gpu/batches/GrPathStencilSettings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698