| 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);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|