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

Unified Diff: src/gpu/GrDefaultPathRenderer.cpp

Issue 1311673014: Remove GrAddPathRenderers_default (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrDefaultPathRenderer.h ('k') | src/gpu/GrPathRenderer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrDefaultPathRenderer.cpp
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
deleted file mode 100644
index f4ce7c85a52bfc9ca818dad8f87e477e35033f2e..0000000000000000000000000000000000000000
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ /dev/null
@@ -1,761 +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.
- */
-
-#include "GrDefaultPathRenderer.h"
-
-#include "GrBatchFlushState.h"
-#include "GrBatchTest.h"
-#include "GrContext.h"
-#include "GrDefaultGeoProcFactory.h"
-#include "GrPathUtils.h"
-#include "GrPipelineBuilder.h"
-#include "GrVertices.h"
-#include "SkGeometry.h"
-#include "SkString.h"
-#include "SkStrokeRec.h"
-#include "SkTLazy.h"
-#include "SkTraceEvent.h"
-
-#include "batches/GrVertexBatch.h"
-
-GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport,
- bool stencilWrapOpsSupport)
- : fSeparateStencil(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
-
-#define STENCIL_OFF 0 // Always disable stencil (even when needed)
-
-static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& stroke) {
-#if STENCIL_OFF
- return true;
-#else
- if (!stroke.isHairlineStyle() && !path.isInverseFillType()) {
- return path.isConvex();
- }
- return false;
-#endif
-}
-
-GrPathRenderer::StencilSupport
-GrDefaultPathRenderer::onGetStencilSupport(const SkPath& path, const GrStrokeInfo& stroke) const {
- if (single_pass_path(path, stroke)) {
- return GrPathRenderer::kNoRestriction_StencilSupport;
- } else {
- return GrPathRenderer::kStencilOnly_StencilSupport;
- }
-}
-
-static inline void append_countour_edge_indices(bool hairLine,
- uint16_t fanCenterIdx,
- uint16_t edgeV0Idx,
- uint16_t** indices) {
- // when drawing lines we're appending line segments along
- // the contour. When applying the other fill rules we're
- // drawing triangle fans around fanCenterIdx.
- if (!hairLine) {
- *((*indices)++) = fanCenterIdx;
- }
- *((*indices)++) = edgeV0Idx;
- *((*indices)++) = edgeV0Idx + 1;
-}
-
-static inline void add_quad(SkPoint** vert, const SkPoint* base, const SkPoint pts[],
- SkScalar srcSpaceTolSqd, SkScalar srcSpaceTol, bool indexed,
- bool isHairline, uint16_t subpathIdxStart, int offset, uint16_t** idx) {
- // first pt of quad is the pt we ended on in previous step
- uint16_t firstQPtIdx = (uint16_t)(*vert - base) - 1 + offset;
- uint16_t numPts = (uint16_t)
- GrPathUtils::generateQuadraticPoints(
- pts[0], pts[1], pts[2],
- srcSpaceTolSqd, vert,
- GrPathUtils::quadraticPointCount(pts, srcSpaceTol));
- if (indexed) {
- for (uint16_t i = 0; i < numPts; ++i) {
- append_countour_edge_indices(isHairline, subpathIdxStart,
- firstQPtIdx + i, idx);
- }
- }
-}
-
-class DefaultPathBatch : public GrVertexBatch {
-public:
- struct Geometry {
- GrColor fColor;
- SkPath fPath;
- SkScalar fTolerance;
- };
-
- static GrDrawBatch* Create(const Geometry& geometry, uint8_t coverage,
- const SkMatrix& viewMatrix, bool isHairline,
- const SkRect& devBounds) {
- return new DefaultPathBatch(geometry, coverage, viewMatrix, isHairline, devBounds);
- }
-
- const char* name() const override { return "DefaultPathBatch"; }
-
- void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
- // When this is called on a batch, there is only one geometry bundle
- out->setKnownFourComponents(fGeoData[0].fColor);
- }
- void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
- out->setKnownSingleComponent(this->coverage());
- }
-
-private:
- void initBatchTracker(const GrPipelineOptimizations& opt) override {
- // Handle any color overrides
- if (!opt.readsColor()) {
- fGeoData[0].fColor = GrColor_ILLEGAL;
- }
- opt.getOverrideColorIfSet(&fGeoData[0].fColor);
-
- // setup batch properties
- fBatch.fColorIgnored = !opt.readsColor();
- fBatch.fColor = fGeoData[0].fColor;
- fBatch.fUsesLocalCoords = opt.readsLocalCoords();
- fBatch.fCoverageIgnored = !opt.readsCoverage();
- }
-
- void onPrepareDraws(Target* target) override {
- SkAutoTUnref<const GrGeometryProcessor> gp;
- {
- using namespace GrDefaultGeoProcFactory;
- Color color(this->color());
- Coverage coverage(this->coverage());
- if (this->coverageIgnored()) {
- coverage.fType = Coverage::kNone_Type;
- }
- LocalCoords localCoords(this->usesLocalCoords() ? LocalCoords::kUsePosition_Type :
- LocalCoords::kUnused_Type);
- gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoords,
- this->viewMatrix()));
- }
-
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(SkPoint));
-
- target->initDraw(gp, this->pipeline());
-
- int instanceCount = fGeoData.count();
-
- // compute number of vertices
- int maxVertices = 0;
-
- // We will use index buffers if we have multiple paths or one path with multiple contours
- bool isIndexed = instanceCount > 1;
- for (int i = 0; i < instanceCount; i++) {
- Geometry& args = fGeoData[i];
-
- int contourCount;
- maxVertices += GrPathUtils::worstCasePointCount(args.fPath, &contourCount,
- args.fTolerance);
-
- isIndexed = isIndexed || contourCount > 1;
- }
-
- if (maxVertices == 0 || maxVertices > ((int)SK_MaxU16 + 1)) {
- SkDebugf("Cannot render path (%d)\n", maxVertices);
- return;
- }
-
- // determine primitiveType
- int maxIndices = 0;
- GrPrimitiveType primitiveType;
- if (this->isHairline()) {
- if (isIndexed) {
- maxIndices = 2 * maxVertices;
- primitiveType = kLines_GrPrimitiveType;
- } else {
- primitiveType = kLineStrip_GrPrimitiveType;
- }
- } else {
- if (isIndexed) {
- maxIndices = 3 * maxVertices;
- primitiveType = kTriangles_GrPrimitiveType;
- } else {
- primitiveType = kTriangleFan_GrPrimitiveType;
- }
- }
-
- // allocate vertex / index buffers
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void* verts = target->makeVertexSpace(vertexStride, maxVertices,
- &vertexBuffer, &firstVertex);
-
- if (!verts) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
-
- const GrIndexBuffer* indexBuffer = nullptr;
- int firstIndex = 0;
-
- void* indices = nullptr;
- if (isIndexed) {
- indices = target->makeIndexSpace(maxIndices, &indexBuffer, &firstIndex);
-
- if (!indices) {
- SkDebugf("Could not allocate indices\n");
- return;
- }
- }
-
- // fill buffers
- int vertexOffset = 0;
- int indexOffset = 0;
- for (int i = 0; i < instanceCount; i++) {
- Geometry& args = fGeoData[i];
-
- int vertexCnt = 0;
- int indexCnt = 0;
- if (!this->createGeom(verts,
- vertexOffset,
- indices,
- indexOffset,
- &vertexCnt,
- &indexCnt,
- args.fPath,
- args.fTolerance,
- isIndexed)) {
- return;
- }
-
- vertexOffset += vertexCnt;
- indexOffset += indexCnt;
- SkASSERT(vertexOffset <= maxVertices && indexOffset <= maxIndices);
- }
-
- GrVertices vertices;
- if (isIndexed) {
- vertices.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
- vertexOffset, indexOffset);
- } else {
- vertices.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
- }
- target->draw(vertices);
-
- // put back reserves
- target->putBackIndices((size_t)(maxIndices - indexOffset));
- target->putBackVertices((size_t)(maxVertices - vertexOffset), (size_t)vertexStride);
- }
-
- SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
-
- DefaultPathBatch(const Geometry& geometry, uint8_t coverage, const SkMatrix& viewMatrix,
- bool isHairline, const SkRect& devBounds) {
- this->initClassID<DefaultPathBatch>();
- fBatch.fCoverage = coverage;
- fBatch.fIsHairline = isHairline;
- fBatch.fViewMatrix = viewMatrix;
- fGeoData.push_back(geometry);
-
- this->setBounds(devBounds);
- }
-
- bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
- DefaultPathBatch* that = t->cast<DefaultPathBatch>();
- if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
- that->bounds(), caps)) {
- return false;
- }
-
- if (this->color() != that->color()) {
- return false;
- }
-
- if (this->coverage() != that->coverage()) {
- return false;
- }
-
- if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
- return false;
- }
-
- if (this->isHairline() != that->isHairline()) {
- return false;
- }
-
- fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
- this->joinBounds(that->bounds());
- return true;
- }
-
- bool createGeom(void* vertices,
- size_t vertexOffset,
- void* indices,
- size_t indexOffset,
- int* vertexCnt,
- int* indexCnt,
- const SkPath& path,
- SkScalar srcSpaceTol,
- bool isIndexed) {
- {
- SkScalar srcSpaceTolSqd = SkScalarMul(srcSpaceTol, srcSpaceTol);
-
- uint16_t indexOffsetU16 = (uint16_t)indexOffset;
- uint16_t vertexOffsetU16 = (uint16_t)vertexOffset;
-
- uint16_t* idxBase = reinterpret_cast<uint16_t*>(indices) + indexOffsetU16;
- uint16_t* idx = idxBase;
- uint16_t subpathIdxStart = vertexOffsetU16;
-
- SkPoint* base = reinterpret_cast<SkPoint*>(vertices) + vertexOffset;
- SkPoint* vert = base;
-
- SkPoint pts[4];
-
- bool first = true;
- int subpath = 0;
-
- 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) (vert - base) + vertexOffsetU16;
- subpathIdxStart = currIdx;
- ++subpath;
- }
- *vert = pts[0];
- vert++;
- break;
- case SkPath::kLine_Verb:
- if (isIndexed) {
- uint16_t prevIdx = (uint16_t)(vert - base) - 1 + vertexOffsetU16;
- append_countour_edge_indices(this->isHairline(), subpathIdxStart,
- prevIdx, &idx);
- }
- *(vert++) = pts[1];
- break;
- case SkPath::kConic_Verb: {
- SkScalar weight = iter.conicWeight();
- SkAutoConicToQuads converter;
- // Converting in src-space, hance the finer tolerance (0.25)
- // TODO: find a way to do this in dev-space so the tolerance means something
- const SkPoint* quadPts = converter.computeQuads(pts, weight, 0.25f);
- for (int i = 0; i < converter.countQuads(); ++i) {
- add_quad(&vert, base, quadPts + i*2, srcSpaceTolSqd, srcSpaceTol,
- isIndexed, this->isHairline(), subpathIdxStart,
- (int)vertexOffset, &idx);
- }
- break;
- }
- case SkPath::kQuad_Verb:
- add_quad(&vert, base, pts, srcSpaceTolSqd, srcSpaceTol, isIndexed,
- this->isHairline(), subpathIdxStart, (int)vertexOffset, &idx);
- break;
- case SkPath::kCubic_Verb: {
- // first pt of cubic is the pt we ended on in previous step
- uint16_t firstCPtIdx = (uint16_t)(vert - base) - 1 + vertexOffsetU16;
- uint16_t numPts = (uint16_t) GrPathUtils::generateCubicPoints(
- pts[0], pts[1], pts[2], pts[3],
- srcSpaceTolSqd, &vert,
- GrPathUtils::cubicPointCount(pts, srcSpaceTol));
- if (isIndexed) {
- for (uint16_t i = 0; i < numPts; ++i) {
- append_countour_edge_indices(this->isHairline(), subpathIdxStart,
- firstCPtIdx + i, &idx);
- }
- }
- break;
- }
- case SkPath::kClose_Verb:
- break;
- case SkPath::kDone_Verb:
- done = true;
- }
- first = false;
- }
-
- *vertexCnt = static_cast<int>(vert - base);
- *indexCnt = static_cast<int>(idx - idxBase);
-
- }
- return true;
- }
-
- GrColor color() const { return fBatch.fColor; }
- uint8_t coverage() const { return fBatch.fCoverage; }
- bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
- const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
- bool isHairline() const { return fBatch.fIsHairline; }
- bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
-
- struct BatchTracker {
- GrColor fColor;
- uint8_t fCoverage;
- SkMatrix fViewMatrix;
- bool fUsesLocalCoords;
- bool fColorIgnored;
- bool fCoverageIgnored;
- bool fIsHairline;
- };
-
- BatchTracker fBatch;
- SkSTArray<1, Geometry, true> fGeoData;
-};
-
-bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
- GrPipelineBuilder* pipelineBuilder,
- GrColor color,
- const SkMatrix& viewMatrix,
- const SkPath& path,
- const GrStrokeInfo& origStroke,
- bool stencilOnly) {
- SkTCopyOnFirstWrite<GrStrokeInfo> stroke(origStroke);
-
- SkScalar hairlineCoverage;
- uint8_t newCoverage = 0xff;
- if (IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, &hairlineCoverage)) {
- newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
-
- if (!stroke->isHairlineStyle()) {
- stroke.writable()->setHairlineStyle();
- }
- }
-
- const bool isHairline = stroke->isHairlineStyle();
-
- // Save the current xp on the draw state so we can reset it if needed
- SkAutoTUnref<const GrXPFactory> backupXPFactory(SkRef(pipelineBuilder->getXPFactory()));
- // 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 (isHairline) {
- passCount = 1;
- if (stencilOnly) {
- passes[0] = &gDirectToStencil;
- } else {
- passes[0] = nullptr;
- }
- lastPassIsBounds = false;
- drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
- } else {
- 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:
- if (fSeparateStencil) {
- if (fStencilWrapOps) {
- passes[0] = &gWindStencilSeparateWithWrap;
- } else {
- passes[0] = &gWindStencilSeparateNoWrap;
- }
- passCount = 2;
- drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
- } else {
- if (fStencilWrapOps) {
- passes[0] = &gWindSingleStencilWithWrapInc;
- passes[1] = &gWindSingleStencilWithWrapDec;
- } else {
- passes[0] = &gWindSingleStencilNoWrapInc;
- passes[1] = &gWindSingleStencilNoWrapDec;
- }
- // which is cw and which is ccw is arbitrary.
- drawFace[0] = GrPipelineBuilder::kCW_DrawFace;
- drawFace[1] = GrPipelineBuilder::kCCW_DrawFace;
- passCount = 3;
- }
- 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;
- }
- }
- }
-
- SkScalar tol = GrPathUtils::kDefaultTolerance;
- SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds());
-
- 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;
- target->drawNonAARect(*pipelineBuilder, color, viewM, bounds, localMatrix);
- } else {
- if (passCount > 1) {
- pipelineBuilder->setDisableColorXPFactory();
- }
-
- DefaultPathBatch::Geometry geometry;
- geometry.fColor = color;
- geometry.fPath = path;
- geometry.fTolerance = srcSpaceTol;
-
- SkAutoTUnref<GrDrawBatch> batch(DefaultPathBatch::Create(geometry, newCoverage,
- viewMatrix, isHairline,
- devBounds));
-
- target->drawBatch(*pipelineBuilder, batch);
- }
- }
- return true;
-}
-
-bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- // this class can draw any path with any fill but doesn't do any anti-aliasing.
- return !args.fAntiAlias && (args.fStroke->isFillStyle() ||
- IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix,
- nullptr));
-}
-
-bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
- return this->internalDrawPath(args.fTarget,
- args.fPipelineBuilder,
- args.fColor,
- *args.fViewMatrix,
- *args.fPath,
- *args.fStroke,
- false);
-}
-
-void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
- 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);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#ifdef GR_TEST_UTILS
-
-DRAW_BATCH_TEST_DEFINE(DefaultPathBatch) {
- GrColor color = GrRandomColor(random);
- SkMatrix viewMatrix = GrTest::TestMatrix(random);
-
- // For now just hairlines because the other types of draws require two batches.
- // TODO we should figure out a way to combine the stencil and cover steps into one batch
- GrStrokeInfo stroke(SkStrokeRec::kHairline_InitStyle);
- SkPath path = GrTest::TestPath(random);
-
- // Compute srcSpaceTol
- SkRect bounds = path.getBounds();
- SkScalar tol = GrPathUtils::kDefaultTolerance;
- SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, bounds);
-
- DefaultPathBatch::Geometry geometry;
- geometry.fColor = color;
- geometry.fPath = path;
- geometry.fTolerance = srcSpaceTol;
-
- viewMatrix.mapRect(&bounds);
- uint8_t coverage = GrRandomCoverage(random);
- return DefaultPathBatch::Create(geometry, coverage, viewMatrix, true, bounds);
-}
-
-#endif
« no previous file with comments | « src/gpu/GrDefaultPathRenderer.h ('k') | src/gpu/GrPathRenderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698