Index: src/gpu/batches/GrMSAAPathRenderer.cpp |
diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp |
deleted file mode 100644 |
index 988952822abc591c5020324762839266d73a5333..0000000000000000000000000000000000000000 |
--- a/src/gpu/batches/GrMSAAPathRenderer.cpp |
+++ /dev/null |
@@ -1,745 +0,0 @@ |
-/* |
- * Copyright 2016 Google Inc. |
- * |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-#include "GrMSAAPathRenderer.h" |
- |
-#include "GrBatchFlushState.h" |
-#include "GrDefaultGeoProcFactory.h" |
-#include "GrPathStencilSettings.h" |
-#include "GrPathUtils.h" |
-#include "GrPipelineBuilder.h" |
-#include "GrMesh.h" |
-#include "SkGeometry.h" |
-#include "SkTraceEvent.h" |
-#include "glsl/GrGLSLGeometryProcessor.h" |
-#include "glsl/GrGLSLFragmentShaderBuilder.h" |
-#include "glsl/GrGLSLVertexShaderBuilder.h" |
-#include "glsl/GrGLSLProgramDataManager.h" |
-#include "glsl/GrGLSLUtil.h" |
-#include "gl/GrGLVaryingHandler.h" |
-#include "batches/GrRectBatchFactory.h" |
-#include "batches/GrVertexBatch.h" |
- |
-static const float kTolerance = 0.5f; |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// Helpers for drawPath |
- |
-static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& stroke) { |
- if (!path.isInverseFillType()) { |
- return path.isConvex(); |
- } |
- return false; |
-} |
- |
-GrPathRenderer::StencilSupport |
-GrMSAAPathRenderer::onGetStencilSupport(const SkPath& path, const GrStrokeInfo& stroke) const { |
- if (single_pass_path(path, stroke)) { |
- return GrPathRenderer::kNoRestriction_StencilSupport; |
- } else { |
- return GrPathRenderer::kStencilOnly_StencilSupport; |
- } |
-} |
- |
-struct MSAALineVertices { |
- struct Vertex { |
- SkPoint fPosition; |
- SkColor fColor; |
- }; |
- Vertex* vertices; |
- Vertex* nextVertex; |
-#ifdef SK_DEBUG |
- Vertex* verticesEnd; |
-#endif |
- uint16_t* indices; |
- uint16_t* nextIndex; |
-}; |
- |
-struct MSAAQuadVertices { |
- struct Vertex { |
- SkPoint fPosition; |
- SkPoint fUV; |
- SkColor fColor; |
- }; |
- Vertex* vertices; |
- Vertex* nextVertex; |
-#ifdef SK_DEBUG |
- Vertex* verticesEnd; |
-#endif |
- uint16_t* indices; |
- uint16_t* nextIndex; |
-}; |
- |
-static inline void append_contour_edge_indices(uint16_t fanCenterIdx, |
- uint16_t edgeV0Idx, |
- MSAALineVertices& lines) { |
- *(lines.nextIndex++) = fanCenterIdx; |
- *(lines.nextIndex++) = edgeV0Idx; |
- *(lines.nextIndex++) = edgeV0Idx + 1; |
-} |
- |
-static inline void add_quad(MSAALineVertices& lines, MSAAQuadVertices& quads, const SkPoint pts[], |
- SkColor color, bool indexed, uint16_t subpathLineIdxStart) { |
- SkASSERT(lines.nextVertex < lines.verticesEnd); |
- *lines.nextVertex = { pts[2], color }; |
- if (indexed) { |
- int prevIdx = (uint16_t) (lines.nextVertex - lines.vertices - 1); |
- if (prevIdx > subpathLineIdxStart) { |
- append_contour_edge_indices(subpathLineIdxStart, prevIdx, lines); |
- } |
- } |
- lines.nextVertex++; |
- |
- SkASSERT(quads.nextVertex + 2 < quads.verticesEnd); |
- // the texture coordinates are drawn from the Loop-Blinn rendering algorithm |
- *(quads.nextVertex++) = { pts[0], SkPoint::Make(0.0, 0.0), color }; |
- *(quads.nextVertex++) = { pts[1], SkPoint::Make(0.5, 0.0), color }; |
- *(quads.nextVertex++) = { pts[2], SkPoint::Make(1.0, 1.0), color }; |
- if (indexed) { |
- uint16_t offset = (uint16_t) (quads.nextVertex - quads.vertices) - 3; |
- *(quads.nextIndex++) = offset++; |
- *(quads.nextIndex++) = offset++; |
- *(quads.nextIndex++) = offset++; |
- } |
-} |
- |
-class MSAAQuadProcessor : public GrGeometryProcessor { |
-public: |
- static GrGeometryProcessor* Create(const SkMatrix& viewMatrix) { |
- return new MSAAQuadProcessor(viewMatrix); |
- } |
- |
- virtual ~MSAAQuadProcessor() {} |
- |
- const char* name() const override { return "MSAAQuadProcessor"; } |
- |
- const Attribute* inPosition() const { return fInPosition; } |
- const Attribute* inUV() const { return fInUV; } |
- const Attribute* inColor() const { return fInColor; } |
- const SkMatrix& viewMatrix() const { return fViewMatrix; } |
- const SkMatrix& localMatrix() const { return SkMatrix::I(); } |
- |
- class GLSLProcessor : public GrGLSLGeometryProcessor { |
- public: |
- GLSLProcessor(const GrGeometryProcessor& qpr) {} |
- |
- void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { |
- const MSAAQuadProcessor& qp = args.fGP.cast<MSAAQuadProcessor>(); |
- GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder; |
- GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
- |
- // emit attributes |
- varyingHandler->emitAttributes(qp); |
- varyingHandler->addPassThroughAttribute(qp.inColor(), args.fOutputColor); |
- |
- GrGLSLVertToFrag uv(kVec2f_GrSLType); |
- varyingHandler->addVarying("uv", &uv, kHigh_GrSLPrecision); |
- vsBuilder->codeAppendf("%s = %s;", uv.vsOut(), qp.inUV()->fName); |
- |
- // Setup position |
- this->setupPosition(vsBuilder, uniformHandler, gpArgs, qp.inPosition()->fName, |
- qp.viewMatrix(), &fViewMatrixUniform); |
- |
- // emit transforms |
- this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, |
- qp.inPosition()->fName, SkMatrix::I(), args.fTransformsIn, |
- args.fTransformsOut); |
- |
- GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder; |
- fsBuilder->codeAppendf("if (%s.x * %s.x >= %s.y) discard;", uv.fsIn(), uv.fsIn(), |
- uv.fsIn()); |
- fsBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputCoverage); |
- } |
- |
- static inline void GenKey(const GrGeometryProcessor& gp, |
- const GrGLSLCaps&, |
- GrProcessorKeyBuilder* b) { |
- const MSAAQuadProcessor& qp = gp.cast<MSAAQuadProcessor>(); |
- uint32_t key = 0; |
- key |= qp.viewMatrix().hasPerspective() ? 0x1 : 0x0; |
- key |= qp.viewMatrix().isIdentity() ? 0x2: 0x0; |
- b->add32(key); |
- } |
- |
- virtual void setData(const GrGLSLProgramDataManager& pdman, |
- const GrPrimitiveProcessor& gp) override { |
- const MSAAQuadProcessor& qp = gp.cast<MSAAQuadProcessor>(); |
- if (!qp.viewMatrix().isIdentity()) { |
- float viewMatrix[3 * 3]; |
- GrGLSLGetMatrix<3>(viewMatrix, qp.viewMatrix()); |
- pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); |
- } |
- } |
- |
- void setTransformData(const GrPrimitiveProcessor& primProc, |
- const GrGLSLProgramDataManager& pdman, |
- int index, |
- const SkTArray<const GrCoordTransform*, true>& transforms) override { |
- this->setTransformDataHelper<MSAAQuadProcessor>(primProc, pdman, index, transforms); |
- } |
- |
- private: |
- typedef GrGLSLGeometryProcessor INHERITED; |
- |
- UniformHandle fViewMatrixUniform; |
- }; |
- |
- virtual void getGLSLProcessorKey(const GrGLSLCaps& caps, |
- GrProcessorKeyBuilder* b) const override { |
- GLSLProcessor::GenKey(*this, caps, b); |
- } |
- |
- virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override { |
- return new GLSLProcessor(*this); |
- } |
- |
-private: |
- MSAAQuadProcessor(const SkMatrix& viewMatrix) |
- : fViewMatrix(viewMatrix) { |
- this->initClassID<MSAAQuadProcessor>(); |
- fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, |
- kHigh_GrSLPrecision)); |
- fInUV = &this->addVertexAttrib(Attribute("inUV", kVec2f_GrVertexAttribType, |
- kHigh_GrSLPrecision)); |
- fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); |
- this->setSampleShading(1.0f); |
- } |
- |
- const Attribute* fInPosition; |
- const Attribute* fInUV; |
- const Attribute* fInColor; |
- SkMatrix fViewMatrix; |
- |
- GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
- |
- typedef GrGeometryProcessor INHERITED; |
-}; |
- |
-class MSAAPathBatch : public GrVertexBatch { |
-public: |
- DEFINE_BATCH_CLASS_ID |
- |
- struct Geometry { |
- GrColor fColor; |
- SkPath fPath; |
- SkScalar fTolerance; |
- }; |
- |
- static MSAAPathBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix, |
- const SkRect& devBounds) { |
- return new MSAAPathBatch(geometry, viewMatrix, devBounds); |
- } |
- |
- const char* name() const override { return "MSAAPathBatch"; } |
- |
- void computePipelineOptimizations(GrInitInvariantOutput* color, |
- GrInitInvariantOutput* coverage, |
- GrBatchToXPOverrides* overrides) const override { |
- // When this is called on a batch, there is only one geometry bundle |
- color->setKnownFourComponents(fGeoData[0].fColor); |
- coverage->setKnownSingleComponent(0xff); |
- } |
- |
- bool isValid() const { |
- return !fIsIndexed || fMaxLineIndices <= SK_MaxU16; |
- } |
- |
-private: |
- void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
- // Handle any color overrides |
- if (!overrides.readsColor()) { |
- fGeoData[0].fColor = GrColor_ILLEGAL; |
- } |
- overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
- } |
- |
- void computeWorstCasePointCount(const SkPath& path, int* subpaths, SkScalar tol, |
- int* outLinePointCount, int* outQuadPointCount) const { |
- int linePointCount = 0; |
- int quadPointCount = 0; |
- *subpaths = 1; |
- |
- bool first = true; |
- |
- SkPath::Iter iter(path, false); |
- SkPath::Verb verb; |
- |
- SkPoint pts[4]; |
- while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
- switch (verb) { |
- case SkPath::kLine_Verb: |
- linePointCount += 1; |
- break; |
- case SkPath::kConic_Verb: { |
- SkScalar weight = iter.conicWeight(); |
- SkAutoConicToQuads converter; |
- converter.computeQuads(pts, weight, kTolerance); |
- int quadPts = converter.countQuads(); |
- linePointCount += quadPts; |
- quadPointCount += 3 * quadPts; |
- } |
- case SkPath::kQuad_Verb: |
- linePointCount += 1; |
- quadPointCount += 3; |
- break; |
- case SkPath::kCubic_Verb: { |
- SkSTArray<15, SkPoint, true> quadPts; |
- GrPathUtils::convertCubicToQuads(pts, kTolerance, &quadPts); |
- int count = quadPts.count(); |
- linePointCount += count / 3; |
- quadPointCount += count; |
- break; |
- } |
- case SkPath::kMove_Verb: |
- linePointCount += 1; |
- if (!first) { |
- ++(*subpaths); |
- } |
- break; |
- default: |
- break; |
- } |
- first = false; |
- } |
- *outLinePointCount = linePointCount; |
- *outQuadPointCount = quadPointCount; |
- } |
- |
- void onPrepareDraws(Target* target) const override { |
- SkASSERT(this->isValid()); |
- if (fMaxLineVertices == 0) { |
- SkASSERT(fMaxQuadVertices == 0); |
- return; |
- } |
- |
- GrPrimitiveType primitiveType = fIsIndexed ? kTriangles_GrPrimitiveType |
- : kTriangleFan_GrPrimitiveType; |
- |
- // allocate vertex / index buffers |
- const GrBuffer* lineVertexBuffer; |
- int firstLineVertex; |
- MSAALineVertices lines; |
- size_t lineVertexStride = sizeof(MSAALineVertices::Vertex); |
- lines.vertices = (MSAALineVertices::Vertex*) target->makeVertexSpace(lineVertexStride, |
- fMaxLineVertices, |
- &lineVertexBuffer, |
- &firstLineVertex); |
- if (!lines.vertices) { |
- SkDebugf("Could not allocate vertices\n"); |
- return; |
- } |
- lines.nextVertex = lines.vertices; |
- SkDEBUGCODE(lines.verticesEnd = lines.vertices + fMaxLineVertices;) |
- |
- MSAAQuadVertices quads; |
- size_t quadVertexStride = sizeof(MSAAQuadVertices::Vertex); |
- SkAutoFree quadVertexPtr(sk_malloc_throw(fMaxQuadVertices * quadVertexStride)); |
- quads.vertices = (MSAAQuadVertices::Vertex*) quadVertexPtr.get(); |
- quads.nextVertex = quads.vertices; |
- SkDEBUGCODE(quads.verticesEnd = quads.vertices + fMaxQuadVertices;) |
- |
- const GrBuffer* lineIndexBuffer = nullptr; |
- int firstLineIndex; |
- if (fIsIndexed) { |
- lines.indices = target->makeIndexSpace(fMaxLineIndices, &lineIndexBuffer, |
- &firstLineIndex); |
- if (!lines.indices) { |
- SkDebugf("Could not allocate indices\n"); |
- return; |
- } |
- lines.nextIndex = lines.indices; |
- } else { |
- lines.indices = nullptr; |
- lines.nextIndex = nullptr; |
- } |
- |
- SkAutoFree quadIndexPtr; |
- if (fIsIndexed) { |
- quads.indices = (uint16_t*) sk_malloc_throw(fMaxQuadIndices * sizeof(uint16_t)); |
- quadIndexPtr.set(quads.indices); |
- quads.nextIndex = quads.indices; |
- } else { |
- quads.indices = nullptr; |
- quads.nextIndex = nullptr; |
- } |
- |
- // fill buffers |
- for (int i = 0; i < fGeoData.count(); i++) { |
- const Geometry& args = fGeoData[i]; |
- |
- if (!this->createGeom(lines, |
- quads, |
- args.fPath, |
- args.fTolerance, |
- fViewMatrix, |
- args.fColor, |
- fIsIndexed)) { |
- return; |
- } |
- } |
- int lineVertexOffset = (int) (lines.nextVertex - lines.vertices); |
- int lineIndexOffset = (int) (lines.nextIndex - lines.indices); |
- SkASSERT(lineVertexOffset <= fMaxLineVertices && lineIndexOffset <= fMaxLineIndices); |
- int quadVertexOffset = (int) (quads.nextVertex - quads.vertices); |
- int quadIndexOffset = (int) (quads.nextIndex - quads.indices); |
- SkASSERT(quadVertexOffset <= fMaxQuadVertices && quadIndexOffset <= fMaxQuadIndices); |
- |
- if (lineVertexOffset) { |
- SkAutoTUnref<const GrGeometryProcessor> lineGP; |
- { |
- using namespace GrDefaultGeoProcFactory; |
- lineGP.reset(GrDefaultGeoProcFactory::Create(Color(Color::kAttribute_Type), |
- Coverage(255), |
- LocalCoords(LocalCoords::kUnused_Type), |
- fViewMatrix)); |
- } |
- SkASSERT(lineVertexStride == lineGP->getVertexStride()); |
- |
- GrMesh lineMeshes; |
- if (fIsIndexed) { |
- lineMeshes.initIndexed(primitiveType, lineVertexBuffer, lineIndexBuffer, |
- firstLineVertex, firstLineIndex, lineVertexOffset, |
- lineIndexOffset); |
- } else { |
- lineMeshes.init(primitiveType, lineVertexBuffer, firstLineVertex, |
- lineVertexOffset); |
- } |
- target->draw(lineGP, lineMeshes); |
- } |
- |
- if (quadVertexOffset) { |
- SkAutoTUnref<const GrGeometryProcessor> quadGP(MSAAQuadProcessor::Create(fViewMatrix)); |
- SkASSERT(quadVertexStride == quadGP->getVertexStride()); |
- |
- const GrBuffer* quadVertexBuffer; |
- int firstQuadVertex; |
- MSAAQuadVertices::Vertex* quadVertices = (MSAAQuadVertices::Vertex*) |
- target->makeVertexSpace(quadVertexStride, quadVertexOffset, &quadVertexBuffer, |
- &firstQuadVertex); |
- memcpy(quadVertices, quads.vertices, quadVertexStride * quadVertexOffset); |
- GrMesh quadMeshes; |
- if (fIsIndexed) { |
- const GrBuffer* quadIndexBuffer; |
- int firstQuadIndex; |
- uint16_t* quadIndices = (uint16_t*) target->makeIndexSpace(quadIndexOffset, |
- &quadIndexBuffer, |
- &firstQuadIndex); |
- memcpy(quadIndices, quads.indices, sizeof(uint16_t) * quadIndexOffset); |
- quadMeshes.initIndexed(kTriangles_GrPrimitiveType, quadVertexBuffer, |
- quadIndexBuffer, firstQuadVertex, firstQuadIndex, |
- quadVertexOffset, quadIndexOffset); |
- } else { |
- quadMeshes.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex, |
- quadVertexOffset); |
- } |
- target->draw(quadGP, quadMeshes); |
- } |
- } |
- |
- SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
- |
- MSAAPathBatch(const Geometry& geometry, const SkMatrix& viewMatrix, const SkRect& devBounds) |
- : INHERITED(ClassID()) |
- , fViewMatrix(viewMatrix) { |
- fGeoData.push_back(geometry); |
- this->setBounds(devBounds); |
- int contourCount; |
- this->computeWorstCasePointCount(geometry.fPath, &contourCount, kTolerance, |
- &fMaxLineVertices, &fMaxQuadVertices); |
- fMaxLineIndices = fMaxLineVertices * 3; |
- fMaxQuadIndices = fMaxQuadVertices * 3; |
- fIsIndexed = contourCount > 1; |
- } |
- |
- bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
- MSAAPathBatch* that = t->cast<MSAAPathBatch>(); |
- if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), |
- that->bounds(), caps)) { |
- return false; |
- } |
- |
- if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) { |
- return false; |
- } |
- |
- if ((fMaxLineIndices + that->fMaxLineIndices > SK_MaxU16) || |
- (fMaxQuadIndices + that->fMaxQuadIndices > SK_MaxU16)) { |
- return false; |
- } |
- |
- fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); |
- this->joinBounds(that->bounds()); |
- fIsIndexed = true; |
- fMaxLineVertices += that->fMaxLineVertices; |
- fMaxQuadVertices += that->fMaxQuadVertices; |
- fMaxLineIndices += that->fMaxLineIndices; |
- fMaxQuadIndices += that->fMaxQuadIndices; |
- return true; |
- } |
- |
- bool createGeom(MSAALineVertices& lines, |
- MSAAQuadVertices& quads, |
- const SkPath& path, |
- SkScalar srcSpaceTol, |
- const SkMatrix& m, |
- SkColor color, |
- bool isIndexed) const { |
- { |
- uint16_t subpathIdxStart = (uint16_t) (lines.nextVertex - lines.vertices); |
- |
- SkPoint pts[4]; |
- |
- bool first = true; |
- SkPath::Iter iter(path, false); |
- |
- bool done = false; |
- while (!done) { |
- SkPath::Verb verb = iter.next(pts); |
- switch (verb) { |
- case SkPath::kMove_Verb: |
- if (!first) { |
- uint16_t currIdx = (uint16_t) (lines.nextVertex - lines.vertices); |
- subpathIdxStart = currIdx; |
- } |
- SkASSERT(lines.nextVertex < lines.verticesEnd); |
- *(lines.nextVertex++) = { pts[0], color }; |
- break; |
- case SkPath::kLine_Verb: |
- if (isIndexed) { |
- uint16_t prevIdx = (uint16_t) (lines.nextVertex - lines.vertices - 1); |
- if (prevIdx > subpathIdxStart) { |
- append_contour_edge_indices(subpathIdxStart, prevIdx, lines); |
- } |
- } |
- SkASSERT(lines.nextVertex < lines.verticesEnd); |
- *(lines.nextVertex++) = { pts[1], color }; |
- break; |
- case SkPath::kConic_Verb: { |
- SkScalar weight = iter.conicWeight(); |
- SkAutoConicToQuads converter; |
- const SkPoint* quadPts = converter.computeQuads(pts, weight, |
- kTolerance); |
- for (int i = 0; i < converter.countQuads(); ++i) { |
- add_quad(lines, quads, quadPts + i * 2, color, isIndexed, |
- subpathIdxStart); |
- } |
- break; |
- } |
- case SkPath::kQuad_Verb: { |
- add_quad(lines, quads, pts, color, isIndexed, subpathIdxStart); |
- break; |
- } |
- case SkPath::kCubic_Verb: { |
- SkSTArray<15, SkPoint, true> quadPts; |
- GrPathUtils::convertCubicToQuads(pts, kTolerance, &quadPts); |
- int count = quadPts.count(); |
- for (int i = 0; i < count; i += 3) { |
- add_quad(lines, quads, &quadPts[i], color, isIndexed, subpathIdxStart); |
- } |
- break; |
- } |
- case SkPath::kClose_Verb: |
- break; |
- case SkPath::kDone_Verb: |
- done = true; |
- } |
- first = false; |
- } |
- } |
- return true; |
- } |
- |
- SkSTArray<1, Geometry, true> fGeoData; |
- |
- SkMatrix fViewMatrix; |
- int fMaxLineVertices; |
- int fMaxQuadVertices; |
- int fMaxLineIndices; |
- int fMaxQuadIndices; |
- bool fIsIndexed; |
- |
- typedef GrVertexBatch INHERITED; |
-}; |
- |
-bool GrMSAAPathRenderer::internalDrawPath(GrDrawTarget* target, |
- GrPipelineBuilder* pipelineBuilder, |
- GrColor color, |
- const SkMatrix& viewMatrix, |
- const SkPath& path, |
- const GrStrokeInfo& origStroke, |
- bool stencilOnly) { |
- SkTCopyOnFirstWrite<GrStrokeInfo> stroke(origStroke); |
- |
- const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory(); |
- SkAutoTUnref<const GrXPFactory> backupXPFactory(SkSafeRef(xpFactory)); |
- // face culling doesn't make sense here |
- SkASSERT(GrPipelineBuilder::kBoth_DrawFace == pipelineBuilder->getDrawFace()); |
- |
- int passCount = 0; |
- const GrStencilSettings* passes[3]; |
- GrPipelineBuilder::DrawFace drawFace[3]; |
- bool reverse = false; |
- bool lastPassIsBounds; |
- |
- if (single_pass_path(path, *stroke)) { |
- passCount = 1; |
- if (stencilOnly) { |
- passes[0] = &gDirectToStencil; |
- } else { |
- passes[0] = nullptr; |
- } |
- drawFace[0] = GrPipelineBuilder::kBoth_DrawFace; |
- lastPassIsBounds = false; |
- } else { |
- switch (path.getFillType()) { |
- case SkPath::kInverseEvenOdd_FillType: |
- reverse = true; |
- // fallthrough |
- case SkPath::kEvenOdd_FillType: |
- passes[0] = &gEOStencilPass; |
- if (stencilOnly) { |
- passCount = 1; |
- lastPassIsBounds = false; |
- } else { |
- passCount = 2; |
- lastPassIsBounds = true; |
- if (reverse) { |
- passes[1] = &gInvEOColorPass; |
- } else { |
- passes[1] = &gEOColorPass; |
- } |
- } |
- drawFace[0] = drawFace[1] = GrPipelineBuilder::kBoth_DrawFace; |
- break; |
- |
- case SkPath::kInverseWinding_FillType: |
- reverse = true; |
- // fallthrough |
- case SkPath::kWinding_FillType: |
- passes[0] = &gWindStencilSeparateWithWrap; |
- passCount = 2; |
- drawFace[0] = GrPipelineBuilder::kBoth_DrawFace; |
- if (stencilOnly) { |
- lastPassIsBounds = false; |
- --passCount; |
- } else { |
- lastPassIsBounds = true; |
- drawFace[passCount-1] = GrPipelineBuilder::kBoth_DrawFace; |
- if (reverse) { |
- passes[passCount-1] = &gInvWindColorPass; |
- } else { |
- passes[passCount-1] = &gWindColorPass; |
- } |
- } |
- break; |
- default: |
- SkDEBUGFAIL("Unknown path fFill!"); |
- return false; |
- } |
- } |
- |
- SkRect devBounds; |
- GetPathDevBounds(path, pipelineBuilder->getRenderTarget(), viewMatrix, &devBounds); |
- |
- for (int p = 0; p < passCount; ++p) { |
- pipelineBuilder->setDrawFace(drawFace[p]); |
- if (passes[p]) { |
- *pipelineBuilder->stencil() = *passes[p]; |
- } |
- |
- if (lastPassIsBounds && (p == passCount-1)) { |
- // Reset the XP Factory on pipelineBuilder |
- pipelineBuilder->setXPFactory(backupXPFactory); |
- SkRect bounds; |
- SkMatrix localMatrix = SkMatrix::I(); |
- if (reverse) { |
- SkASSERT(pipelineBuilder->getRenderTarget()); |
- // draw over the dev bounds (which will be the whole dst surface for inv fill). |
- bounds = devBounds; |
- SkMatrix vmi; |
- // mapRect through persp matrix may not be correct |
- if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { |
- vmi.mapRect(&bounds); |
- } else { |
- if (!viewMatrix.invert(&localMatrix)) { |
- return false; |
- } |
- } |
- } else { |
- bounds = path.getBounds(); |
- } |
- const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() : |
- viewMatrix; |
- SkAutoTUnref<GrDrawBatch> batch( |
- GrRectBatchFactory::CreateNonAAFill(color, viewM, bounds, nullptr, |
- &localMatrix)); |
- target->drawBatch(*pipelineBuilder, batch); |
- } else { |
- if (passCount > 1) { |
- pipelineBuilder->setDisableColorXPFactory(); |
- } |
- |
- MSAAPathBatch::Geometry geometry; |
- geometry.fColor = color; |
- geometry.fPath = path; |
- geometry.fTolerance = kTolerance; |
- |
- SkAutoTUnref<MSAAPathBatch> batch(MSAAPathBatch::Create(geometry, viewMatrix, |
- devBounds)); |
- if (batch->isValid()) { |
- target->drawBatch(*pipelineBuilder, batch); |
- } |
- else { |
- return false; |
- } |
- } |
- } |
- return true; |
-} |
- |
-bool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { |
- return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullptr) && |
- !args.fAntiAlias; |
-} |
- |
-bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) { |
- GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrMSAAPathRenderer::onDrawPath"); |
- SkPath path; |
- GrStrokeInfo stroke(*args.fStroke); |
- if (stroke.isDashed()) { |
- if (!stroke.applyDashToPath(&path, &stroke, *args.fPath)) { |
- return false; |
- } |
- } else { |
- path = *args.fPath; |
- } |
- if (!stroke.isFillStyle()) { |
- stroke.setResScale(SkScalarAbs(args.fViewMatrix->getMaxScale())); |
- if (!stroke.applyToPath(&path, path)) { |
- return false; |
- } |
- stroke.setFillStyle(); |
- } |
- return this->internalDrawPath(args.fTarget, |
- args.fPipelineBuilder, |
- args.fColor, |
- *args.fViewMatrix, |
- path, |
- stroke, |
- false); |
-} |
- |
-void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) { |
- GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrMSAAPathRenderer::onStencilPath"); |
- SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType()); |
- SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType()); |
- this->internalDrawPath(args.fTarget, args.fPipelineBuilder, GrColor_WHITE, *args.fViewMatrix, |
- *args.fPath, *args.fStroke, true); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////////// |