From 8ef9108066567cdbb6c743a68a0738a84af54008 Mon Sep 17 00:00:00 2001 From: ethannicholas Date: Mon, 4 Apr 2016 11:41:30 -0700 Subject: Revert of added GrMSAAPathRenderer (patchset #9 id:160001 of https://codereview.chromium.org/1834133003/ ) Reason for revert: driver crash on Windows Original issue's description: > added GrMSAAPathRenderer > GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1834133003 > > Committed: https://skia.googlesource.com/skia/+/47a2dc8e229e93e1bcf7405747320920da1ab742 > > Committed: https://skia.googlesource.com/skia/+/b0fabd4ed55abcb6f5ed2f331c96c783f42bd37c TBR=bsalomon@google.com,egdaniel@google.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review URL: https://codereview.chromium.org/1853223003 --- gyp/gpu.gypi | 2 - src/gpu/GrPathRendererChain.cpp | 6 +- src/gpu/batches/GrDefaultPathRenderer.cpp | 124 +++++ src/gpu/batches/GrDefaultPathRenderer.h | 1 - src/gpu/batches/GrMSAAPathRenderer.cpp | 745 ------------------------------ src/gpu/batches/GrMSAAPathRenderer.h | 35 -- src/gpu/batches/GrPathStencilSettings.h | 131 ------ 7 files changed, 125 insertions(+), 919 deletions(-) delete mode 100644 src/gpu/batches/GrMSAAPathRenderer.cpp delete mode 100644 src/gpu/batches/GrMSAAPathRenderer.h delete mode 100644 src/gpu/batches/GrPathStencilSettings.h diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 2b0b72f2c1..94215c1304 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -229,8 +229,6 @@ '<(skia_src_path)/gpu/batches/GrDrawPathBatch.h', '<(skia_src_path)/gpu/batches/GrDrawVerticesBatch.cpp', '<(skia_src_path)/gpu/batches/GrDrawVerticesBatch.h', - '<(skia_src_path)/gpu/batches/GrMSAAPathRenderer.cpp', - '<(skia_src_path)/gpu/batches/GrMSAAPathRenderer.h', '<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.h', '<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.cpp', '<(skia_src_path)/gpu/batches/GrNonAAStrokeRectBatch.cpp', diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index e19a134467..098d8fb2d9 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -20,10 +20,9 @@ #include "batches/GrAALinearizingConvexPathRenderer.h" #include "batches/GrDashLinePathRenderer.h" #include "batches/GrDefaultPathRenderer.h" -#include "batches/GrMSAAPathRenderer.h" -#include "batches/GrPLSPathRenderer.h" #include "batches/GrStencilAndCoverPathRenderer.h" #include "batches/GrTessellatingPathRenderer.h" +#include "batches/GrPLSPathRenderer.h" GrPathRendererChain::GrPathRendererChain(GrContext* context) { const GrCaps& caps = *context->caps(); @@ -33,9 +32,6 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context) { caps)) { this->addPathRenderer(pr)->unref(); } - if (caps.sampleShadingSupport()) { - this->addPathRenderer(new GrMSAAPathRenderer)->unref(); - } this->addPathRenderer(new GrTessellatingPathRenderer)->unref(); this->addPathRenderer(new GrAAHairLinePathRenderer)->unref(); this->addPathRenderer(new GrAAConvexPathRenderer)->unref(); diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp index 708bcd7234..94508b130b 100644 --- a/src/gpu/batches/GrDefaultPathRenderer.cpp +++ b/src/gpu/batches/GrDefaultPathRenderer.cpp @@ -29,6 +29,130 @@ GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport, , fStencilWrapOps(stencilWrapOpsSupport) { } + +//////////////////////////////////////////////////////////////////////////////// +// Stencil rules for paths + +////// Even/Odd + +GR_STATIC_CONST_SAME_STENCIL(gEOStencilPass, + kInvert_StencilOp, + kKeep_StencilOp, + kAlwaysIfInClip_StencilFunc, + 0xffff, + 0xffff, + 0xffff); + +// ok not to check clip b/c stencil pass only wrote inside clip +GR_STATIC_CONST_SAME_STENCIL(gEOColorPass, + kZero_StencilOp, + kZero_StencilOp, + kNotEqual_StencilFunc, + 0xffff, + 0x0000, + 0xffff); + +// have to check clip b/c outside clip will always be zero. +GR_STATIC_CONST_SAME_STENCIL(gInvEOColorPass, + kZero_StencilOp, + kZero_StencilOp, + kEqualIfInClip_StencilFunc, + 0xffff, + 0x0000, + 0xffff); + +////// Winding + +// when we have separate stencil we increment front faces / decrement back faces +// when we don't have wrap incr and decr we use the stencil test to simulate +// them. + +GR_STATIC_CONST_STENCIL(gWindStencilSeparateWithWrap, + kIncWrap_StencilOp, kDecWrap_StencilOp, + kKeep_StencilOp, kKeep_StencilOp, + kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc, + 0xffff, 0xffff, + 0xffff, 0xffff, + 0xffff, 0xffff); + +// if inc'ing the max value, invert to make 0 +// if dec'ing zero invert to make all ones. +// we can't avoid touching the stencil on both passing and +// failing, so we can't resctrict ourselves to the clip. +GR_STATIC_CONST_STENCIL(gWindStencilSeparateNoWrap, + kInvert_StencilOp, kInvert_StencilOp, + kIncClamp_StencilOp, kDecClamp_StencilOp, + kEqual_StencilFunc, kEqual_StencilFunc, + 0xffff, 0xffff, + 0xffff, 0x0000, + 0xffff, 0xffff); + +// When there are no separate faces we do two passes to setup the winding rule +// stencil. First we draw the front faces and inc, then we draw the back faces +// and dec. These are same as the above two split into the incrementing and +// decrementing passes. +GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapInc, + kIncWrap_StencilOp, + kKeep_StencilOp, + kAlwaysIfInClip_StencilFunc, + 0xffff, + 0xffff, + 0xffff); + +GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapDec, + kDecWrap_StencilOp, + kKeep_StencilOp, + kAlwaysIfInClip_StencilFunc, + 0xffff, + 0xffff, + 0xffff); + +GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilNoWrapInc, + kInvert_StencilOp, + kIncClamp_StencilOp, + kEqual_StencilFunc, + 0xffff, + 0xffff, + 0xffff); + +GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilNoWrapDec, + kInvert_StencilOp, + kDecClamp_StencilOp, + kEqual_StencilFunc, + 0xffff, + 0x0000, + 0xffff); + +// Color passes are the same whether we use the two-sided stencil or two passes + +GR_STATIC_CONST_SAME_STENCIL(gWindColorPass, + kZero_StencilOp, + kZero_StencilOp, + kNonZeroIfInClip_StencilFunc, + 0xffff, + 0x0000, + 0xffff); + +GR_STATIC_CONST_SAME_STENCIL(gInvWindColorPass, + kZero_StencilOp, + kZero_StencilOp, + kEqualIfInClip_StencilFunc, + 0xffff, + 0x0000, + 0xffff); + +////// Normal render to stencil + +// Sometimes the default path renderer can draw a path directly to the stencil +// buffer without having to first resolve the interior / exterior. +GR_STATIC_CONST_SAME_STENCIL(gDirectToStencil, + kZero_StencilOp, + kIncClamp_StencilOp, + kAlwaysIfInClip_StencilFunc, + 0xffff, + 0x0000, + 0xffff); + //////////////////////////////////////////////////////////////////////////////// // Helpers for drawPath diff --git a/src/gpu/batches/GrDefaultPathRenderer.h b/src/gpu/batches/GrDefaultPathRenderer.h index 9973c2be5e..8a2ce7b9c4 100644 --- a/src/gpu/batches/GrDefaultPathRenderer.h +++ b/src/gpu/batches/GrDefaultPathRenderer.h @@ -9,7 +9,6 @@ #define GrDefaultPathRenderer_DEFINED #include "GrPathRenderer.h" -#include "GrPathStencilSettings.h" #include "SkTypes.h" /** diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp deleted file mode 100644 index 988952822a..0000000000 --- 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(); - 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(); - 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(); - 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& transforms) override { - this->setTransformDataHelper(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(); - 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 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 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(); - 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 stroke(origStroke); - - const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory(); - SkAutoTUnref 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 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 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); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/batches/GrMSAAPathRenderer.h b/src/gpu/batches/GrMSAAPathRenderer.h deleted file mode 100644 index 0ffd280291..0000000000 --- a/src/gpu/batches/GrMSAAPathRenderer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrMSAAPathRenderer_DEFINED -#define GrMSAAPathRenderer_DEFINED - -#include "GrPathRenderer.h" -#include "SkTypes.h" - -class SK_API GrMSAAPathRenderer : public GrPathRenderer { -private: - StencilSupport onGetStencilSupport(const SkPath&, const GrStrokeInfo&) const override; - - bool onCanDrawPath(const CanDrawPathArgs&) const override; - - bool onDrawPath(const DrawPathArgs&) override; - - void onStencilPath(const StencilPathArgs&) override; - - bool internalDrawPath(GrDrawTarget*, - GrPipelineBuilder*, - GrColor, - const SkMatrix& viewMatrix, - const SkPath&, - const GrStrokeInfo&, - bool stencilOnly); - - typedef GrPathRenderer INHERITED; -}; - -#endif diff --git a/src/gpu/batches/GrPathStencilSettings.h b/src/gpu/batches/GrPathStencilSettings.h deleted file mode 100644 index a04f77a200..0000000000 --- a/src/gpu/batches/GrPathStencilSettings.h +++ /dev/null @@ -1,131 +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. - */ - -#ifndef GrPathStencilSettings_DEFINED -#define GrPathStencilSettings_DEFINED - -////// Even/Odd - -GR_STATIC_CONST_SAME_STENCIL(gEOStencilPass, - kInvert_StencilOp, - kKeep_StencilOp, - kAlwaysIfInClip_StencilFunc, - 0xffff, - 0xffff, - 0xffff); - -// ok not to check clip b/c stencil pass only wrote inside clip -GR_STATIC_CONST_SAME_STENCIL(gEOColorPass, - kZero_StencilOp, - kZero_StencilOp, - kNotEqual_StencilFunc, - 0xffff, - 0x0000, - 0xffff); - -// have to check clip b/c outside clip will always be zero. -GR_STATIC_CONST_SAME_STENCIL(gInvEOColorPass, - kZero_StencilOp, - kZero_StencilOp, - kEqualIfInClip_StencilFunc, - 0xffff, - 0x0000, - 0xffff); - -////// Winding - -// when we have separate stencil we increment front faces / decrement back faces -// when we don't have wrap incr and decr we use the stencil test to simulate -// them. - -GR_STATIC_CONST_STENCIL(gWindStencilSeparateWithWrap, - kIncWrap_StencilOp, kDecWrap_StencilOp, - kKeep_StencilOp, kKeep_StencilOp, - kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc, - 0xffff, 0xffff, - 0xffff, 0xffff, - 0xffff, 0xffff); - -// if inc'ing the max value, invert to make 0 -// if dec'ing zero invert to make all ones. -// we can't avoid touching the stencil on both passing and -// failing, so we can't resctrict ourselves to the clip. -GR_STATIC_CONST_STENCIL(gWindStencilSeparateNoWrap, - kInvert_StencilOp, kInvert_StencilOp, - kIncClamp_StencilOp, kDecClamp_StencilOp, - kEqual_StencilFunc, kEqual_StencilFunc, - 0xffff, 0xffff, - 0xffff, 0x0000, - 0xffff, 0xffff); - -// When there are no separate faces we do two passes to setup the winding rule -// stencil. First we draw the front faces and inc, then we draw the back faces -// and dec. These are same as the above two split into the incrementing and -// decrementing passes. -GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapInc, - kIncWrap_StencilOp, - kKeep_StencilOp, - kAlwaysIfInClip_StencilFunc, - 0xffff, - 0xffff, - 0xffff); - -GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapDec, - kDecWrap_StencilOp, - kKeep_StencilOp, - kAlwaysIfInClip_StencilFunc, - 0xffff, - 0xffff, - 0xffff); - -GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilNoWrapInc, - kInvert_StencilOp, - kIncClamp_StencilOp, - kEqual_StencilFunc, - 0xffff, - 0xffff, - 0xffff); - -GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilNoWrapDec, - kInvert_StencilOp, - kDecClamp_StencilOp, - kEqual_StencilFunc, - 0xffff, - 0x0000, - 0xffff); - -// Color passes are the same whether we use the two-sided stencil or two passes - -GR_STATIC_CONST_SAME_STENCIL(gWindColorPass, - kZero_StencilOp, - kZero_StencilOp, - kNonZeroIfInClip_StencilFunc, - 0xffff, - 0x0000, - 0xffff); - -GR_STATIC_CONST_SAME_STENCIL(gInvWindColorPass, - kZero_StencilOp, - kZero_StencilOp, - kEqualIfInClip_StencilFunc, - 0xffff, - 0x0000, - 0xffff); - -////// Normal render to stencil - -// Sometimes the default path renderer can draw a path directly to the stencil -// buffer without having to first resolve the interior / exterior. -GR_STATIC_CONST_SAME_STENCIL(gDirectToStencil, - kZero_StencilOp, - kIncClamp_StencilOp, - kAlwaysIfInClip_StencilFunc, - 0xffff, - 0x0000, - 0xffff); - -#endif -- cgit v1.2.3