diff options
Diffstat (limited to 'src/gpu/ops')
-rw-r--r-- | src/gpu/ops/GrAAFillRectOp.cpp | 182 | ||||
-rw-r--r-- | src/gpu/ops/GrAAFillRectOp.h | 41 | ||||
-rw-r--r-- | src/gpu/ops/GrAAStrokeRectOp.cpp | 147 | ||||
-rw-r--r-- | src/gpu/ops/GrAAStrokeRectOp.h | 32 | ||||
-rw-r--r-- | src/gpu/ops/GrDefaultPathRenderer.cpp | 8 | ||||
-rw-r--r-- | src/gpu/ops/GrMSAAPathRenderer.cpp | 7 | ||||
-rw-r--r-- | src/gpu/ops/GrNonAAFillRectOp.cpp | 63 | ||||
-rw-r--r-- | src/gpu/ops/GrNonAAFillRectOp.h | 31 | ||||
-rw-r--r-- | src/gpu/ops/GrNonAAStrokeRectOp.cpp | 116 | ||||
-rw-r--r-- | src/gpu/ops/GrNonAAStrokeRectOp.h | 28 | ||||
-rw-r--r-- | src/gpu/ops/GrRectOpFactory.cpp | 34 | ||||
-rw-r--r-- | src/gpu/ops/GrRectOpFactory.h | 100 | ||||
-rw-r--r-- | src/gpu/ops/GrSimpleMeshDrawOpHelper.h | 22 | ||||
-rw-r--r-- | src/gpu/ops/GrStencilAndCoverPathRenderer.cpp | 10 |
14 files changed, 365 insertions, 456 deletions
diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp index af5885c34f..ec190c786c 100644 --- a/src/gpu/ops/GrAAFillRectOp.cpp +++ b/src/gpu/ops/GrAAFillRectOp.cpp @@ -5,21 +5,26 @@ * found in the LICENSE file. */ -#include "GrAAFillRectOp.h" - #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" #include "GrMeshDrawOp.h" #include "GrOpFlushState.h" +#include "GrRectOpFactory.h" #include "GrResourceKey.h" #include "GrResourceProvider.h" #include "GrTypes.h" #include "SkMatrix.h" #include "SkRect.h" +#include "ops/GrSimpleMeshDrawOpHelper.h" GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); -static void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx, SkScalar dy) { +static inline bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { + return viewMatrix.preservesRightAngles(); +} + +static inline void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx, + SkScalar dy) { pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); } @@ -153,16 +158,34 @@ static void generate_aa_fill_rect_geometry(intptr_t verts, } } -class AAFillRectOp final : public GrLegacyMeshDrawOp { +namespace { + +class AAFillRectOp final : public GrMeshDrawOp { +private: + using Helper = GrSimpleMeshDrawOpHelperWithStencil; + public: DEFINE_OP_CLASS_ID - AAFillRectOp(GrColor color, + static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect& devRect, + const SkMatrix* localMatrix, + const GrUserStencilSettings* stencil) { + SkASSERT(view_matrix_ok_for_aa_fill_rect(viewMatrix)); + return Helper::FactoryHelper<AAFillRectOp>(std::move(paint), viewMatrix, rect, devRect, + localMatrix, stencil); + } + + AAFillRectOp(const Helper::MakeArgs& helperArgs, + GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect& devRect, - const SkMatrix* localMatrix) - : INHERITED(ClassID()) { + const SkMatrix* localMatrix, + const GrUserStencilSettings* stencil) + : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage, stencil) { if (localMatrix) { void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo)); new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix); @@ -189,38 +212,29 @@ public: info->color(), rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); info = this->next(info); } - str.append(DumpPipelineInfo(*this->pipeline())); return str; } - void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override { - GrColor color; - if (optimizations.getOverrideColorIfSet(&color)) { - this->first()->setColor(color); - } - fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage(); - fNeedsLocalCoords = optimizations.readsLocalCoords(); - } + FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); } -private: - void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color, - GrProcessorAnalysisCoverage* coverage) const override { - color->setToConstant(this->first()->color()); - *coverage = GrProcessorAnalysisCoverage::kSingleChannel; + bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { + GrColor color = this->first()->color(); + bool result = fHelper.xpRequiresDstTexture( + caps, clip, GrProcessorAnalysisCoverage::kSingleChannel, &color); + this->first()->setColor(color); + return result; } +private: void onPrepareDraws(Target* target) const override { using namespace GrDefaultGeoProcFactory; Color color(Color::kPremulGrColorAttribute_Type); - Coverage::Type coverageType; - if (fCanTweakAlphaForCoverage) { - coverageType = Coverage::kSolid_Type; - } else { - coverageType = Coverage::kAttribute_Type; - } - LocalCoords lc = - fNeedsLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUnused_Type; + Coverage::Type coverageType = fHelper.compatibleWithAlphaAsCoverage() + ? Coverage::kSolid_Type + : Coverage::kAttribute_Type; + LocalCoords lc = fHelper.usesLocalCoords() ? LocalCoords::kHasExplicit_Type + : LocalCoords::kUnused_Type; sk_sp<GrGeometryProcessor> gp = GrDefaultGeoProcFactory::Make(color, coverageType, lc, SkMatrix::I()); if (!gp) { @@ -245,7 +259,7 @@ private: for (int i = 0; i < fRectCnt; i++) { intptr_t verts = reinterpret_cast<intptr_t>(vertices) + i * kVertsPerAAFillRect * vertexStride; - if (fNeedsLocalCoords) { + if (fHelper.usesLocalCoords()) { if (info->hasLocalMatrix()) { localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(info)->localMatrix(); } else { @@ -253,28 +267,19 @@ private: } } generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), info->viewMatrix(), - info->rect(), info->devRect(), fCanTweakAlphaForCoverage, - localMatrix); + info->rect(), info->devRect(), + fHelper.compatibleWithAlphaAsCoverage(), localMatrix); info = this->next(info); } - helper.recordDraw(target, gp.get(), this->pipeline()); + helper.recordDraw(target, gp.get(), fHelper.makePipeline(target)); } bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { AAFillRectOp* that = t->cast<AAFillRectOp>(); - if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), - that->bounds(), caps)) { + if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { return false; } - SkASSERT(fNeedsLocalCoords == that->fNeedsLocalCoords); - - // In the event of two ops, one who can tweak, one who cannot, we just fall back to not - // tweaking. - if (fCanTweakAlphaForCoverage && !that->fCanTweakAlphaForCoverage) { - fCanTweakAlphaForCoverage = false; - } - fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin()); fRectCnt += that->fRectCnt; this->joinBounds(*that); @@ -333,55 +338,61 @@ private: return reinterpret_cast<const RectInfo*>(next); } - bool fNeedsLocalCoords; - bool fCanTweakAlphaForCoverage; SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData; + Helper fHelper; int fRectCnt; - typedef GrLegacyMeshDrawOp INHERITED; + typedef GrMeshDrawOp INHERITED; }; -namespace GrAAFillRectOp { +} // anonymous namespace + +namespace GrRectOpFactory { -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& devRect) { - return std::unique_ptr<GrLegacyMeshDrawOp>( - new AAFillRectOp(color, viewMatrix, rect, devRect, nullptr)); +std::unique_ptr<GrDrawOp> MakeAAFill(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& rect, const GrUserStencilSettings* stencil) { + if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { + return nullptr; + } + SkRect devRect; + viewMatrix.mapRect(&devRect, rect); + return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, stencil); } -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, - const SkRect& rect, - const SkRect& devRect) { - return std::unique_ptr<GrLegacyMeshDrawOp>( - new AAFillRectOp(color, viewMatrix, rect, devRect, &localMatrix)); +std::unique_ptr<GrDrawOp> MakeAAFillWithDevRect(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& rect, const SkRect& devRect) { + if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { + return nullptr; + } + return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, nullptr); } -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, - const SkRect& rect) { +std::unique_ptr<GrDrawOp> MakeAAFillWithLocalMatrix(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, + const SkRect& rect) { + if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { + return nullptr; + } SkRect devRect; viewMatrix.mapRect(&devRect, rect); - return Make(color, viewMatrix, localMatrix, rect, devRect); + return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr); } -std::unique_ptr<GrLegacyMeshDrawOp> MakeWithLocalRect(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& localRect) { +std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& rect, const SkRect& localRect) { + if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { + return nullptr; + } SkRect devRect; viewMatrix.mapRect(&devRect, rect); SkMatrix localMatrix; if (!localMatrix.setRectToRect(rect, localRect, SkMatrix::kFill_ScaleToFit)) { return nullptr; } - return Make(color, viewMatrix, localMatrix, rect, devRect); + return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr); } -}; + +} // namespace GrRectOpFactory /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -389,21 +400,22 @@ std::unique_ptr<GrLegacyMeshDrawOp> MakeWithLocalRect(GrColor color, #include "GrDrawOpTest.h" -GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAFillRectOp) { - GrColor color = GrRandomColor(random); - SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); +GR_DRAW_OP_TEST_DEFINE(AAFillRectOp) { + SkMatrix viewMatrix; + do { + viewMatrix = GrTest::TestMatrixInvertible(random); + } while (!view_matrix_ok_for_aa_fill_rect(viewMatrix)); SkRect rect = GrTest::TestRect(random); - SkRect devRect = GrTest::TestRect(random); - return GrAAFillRectOp::Make(color, viewMatrix, rect, devRect); -} - -GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAFillRectOpLocalMatrix) { - GrColor color = GrRandomColor(random); - SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); - SkMatrix localMatrix = GrTest::TestMatrix(random); - SkRect rect = GrTest::TestRect(random); - SkRect devRect = GrTest::TestRect(random); - return GrAAFillRectOp::Make(color, viewMatrix, localMatrix, rect, devRect); + SkRect devRect; + viewMatrix.mapRect(&devRect, rect); + const SkMatrix* localMatrix = nullptr; + SkMatrix m; + if (random->nextBool()) { + m = GrTest::TestMatrix(random); + } + const GrUserStencilSettings* stencil = + random->nextBool() ? nullptr : GrGetRandomStencil(random, context); + return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, localMatrix, stencil); } #endif diff --git a/src/gpu/ops/GrAAFillRectOp.h b/src/gpu/ops/GrAAFillRectOp.h deleted file mode 100644 index 7d977164fc..0000000000 --- a/src/gpu/ops/GrAAFillRectOp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrAAFillRectOp_DEFINED -#define GrAAFillRectOp_DEFINED - -#include "GrColor.h" -#include "SkRefCnt.h" - -class GrLegacyMeshDrawOp; -class SkMatrix; -struct SkRect; - -namespace GrAAFillRectOp { -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& devRect); - -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, - const SkRect& rect); - -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, - const SkRect& rect, - const SkRect& devRect); - -std::unique_ptr<GrLegacyMeshDrawOp> MakeWithLocalRect(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& localRect); -}; - -#endif diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp index 7af6c3e58e..82b4ec13fa 100644 --- a/src/gpu/ops/GrAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrAAStrokeRectOp.cpp @@ -5,12 +5,12 @@ * found in the LICENSE file. */ -#include "GrAAStrokeRectOp.h" - #include "GrDefaultGeoProcFactory.h" #include "GrOpFlushState.h" +#include "GrRectOpFactory.h" #include "GrResourceKey.h" #include "GrResourceProvider.h" +#include "GrSimpleMeshDrawOpHelper.h" #include "SkStrokeRec.h" GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); @@ -110,13 +110,26 @@ static sk_sp<GrGeometryProcessor> create_stroke_rect_gp(bool tweakAlphaForCovera viewMatrix); } -class AAStrokeRectOp final : public GrLegacyMeshDrawOp { +namespace { + +class AAStrokeRectOp final : public GrMeshDrawOp { +private: + using Helper = GrSimpleMeshDrawOpHelper; + public: DEFINE_OP_CLASS_ID - AAStrokeRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside, - const SkRect& devInside) - : INHERITED(ClassID()), fViewMatrix(viewMatrix) { + static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& devOutside, const SkRect& devInside) { + return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, devOutside, + devInside); + } + + AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix, + const SkRect& devOutside, const SkRect& devInside) + : INHERITED(ClassID()) + , fHelper(helperArgs, GrAAType::kCoverage) + , fViewMatrix(viewMatrix) { SkASSERT(!devOutside.isEmpty()); SkASSERT(!devInside.isEmpty()); @@ -125,30 +138,35 @@ public: fMiterStroke = true; } - static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, - const SkRect& rect, const SkStrokeRec& stroke) { + static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& rect, const SkStrokeRec& stroke) { bool isMiter; if (!allowed_stroke(stroke, &isMiter)) { return nullptr; } + return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, rect, stroke, + isMiter); + } - AAStrokeRectOp* op = new AAStrokeRectOp(); - op->fMiterStroke = isMiter; - RectInfo& info = op->fRects.push_back(); + AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix, + const SkRect& rect, const SkStrokeRec& stroke, bool isMiter) + : INHERITED(ClassID()) + , fHelper(helperArgs, GrAAType::kCoverage) + , fViewMatrix(viewMatrix) { + fMiterStroke = isMiter; + RectInfo& info = fRects.push_back(); compute_rects(&info.fDevOutside, &info.fDevOutsideAssist, &info.fDevInside, &info.fDegenerate, viewMatrix, rect, stroke.getWidth(), isMiter); info.fColor = color; if (isMiter) { - op->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo); + this->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo); } else { // The outer polygon of the bevel stroke is an octagon specified by the points of a // pair of overlapping rectangles where one is wide and the other is narrow. SkRect bounds = info.fDevOutside; bounds.joinPossiblyEmptyRect(info.fDevOutsideAssist); - op->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo); + this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo); } - op->fViewMatrix = viewMatrix; - return std::unique_ptr<GrLegacyMeshDrawOp>(op); } const char* name() const override { return "AAStrokeRect"; } @@ -166,20 +184,18 @@ public: info.fDevOutsideAssist.fBottom, info.fDevInside.fLeft, info.fDevInside.fTop, info.fDevInside.fRight, info.fDevInside.fBottom, info.fDegenerate); } - string.append(DumpPipelineInfo(*this->pipeline())); string.append(INHERITED::dumpInfo()); return string; } -private: - AAStrokeRectOp() : INHERITED(ClassID()) {} + FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); } - void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color, - GrProcessorAnalysisCoverage* coverage) const override { - color->setToConstant(fRects[0].fColor); - *coverage = GrProcessorAnalysisCoverage::kSingleChannel; + bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { + return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kSingleChannel, + &fRects.back().fColor); } - void applyPipelineOptimizations(const PipelineOptimizations&) override; + +private: void onPrepareDraws(Target*) const override; static const int kMiterIndexCnt = 3 * 24; @@ -192,8 +208,6 @@ private: static const GrBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, bool miterStroke); - bool usesLocalCoords() const { return fUsesLocalCoords; } - bool canTweakAlphaForCoverage() const { return fCanTweakAlphaForCoverage; } const SkMatrix& viewMatrix() const { return fViewMatrix; } bool miterStroke() const { return fMiterStroke; } @@ -221,29 +235,20 @@ private: bool fDegenerate; }; + Helper fHelper; SkSTArray<1, RectInfo, true> fRects; - bool fUsesLocalCoords; - bool fCanTweakAlphaForCoverage; SkMatrix fViewMatrix; bool fMiterStroke; - typedef GrLegacyMeshDrawOp INHERITED; + typedef GrMeshDrawOp INHERITED; }; -void AAStrokeRectOp::applyPipelineOptimizations(const PipelineOptimizations& optimizations) { - optimizations.getOverrideColorIfSet(&fRects[0].fColor); - - fUsesLocalCoords = optimizations.readsLocalCoords(); - fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage(); - fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage(); -} +} // anonymous namespace void AAStrokeRectOp::onPrepareDraws(Target* target) const { - bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); - - sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage, + sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(fHelper.compatibleWithAlphaAsCoverage(), this->viewMatrix(), - this->usesLocalCoords())); + fHelper.usesLocalCoords())); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; @@ -251,7 +256,7 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) const { size_t vertexStride = gp->getVertexStride(); - SkASSERT(canTweakAlphaForCoverage + SkASSERT(fHelper.compatibleWithAlphaAsCoverage() ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); int innerVertexNum = 4; @@ -284,9 +289,9 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) const { info.fDevInside, fMiterStroke, info.fDegenerate, - canTweakAlphaForCoverage); + fHelper.compatibleWithAlphaAsCoverage()); } - helper.recordDraw(target, gp.get(), this->pipeline()); + helper.recordDraw(target, gp.get(), fHelper.makePipeline(target)); } const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvider, @@ -386,8 +391,7 @@ const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvi bool AAStrokeRectOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { AAStrokeRectOp* that = t->cast<AAStrokeRectOp>(); - if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), - that->bounds(), caps)) { + if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { return false; } @@ -397,18 +401,11 @@ bool AAStrokeRectOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { } // We apply the viewmatrix to the rect points on the cpu. However, if the pipeline uses - // local coords then we won't be able to combine. We could actually upload the viewmatrix - // using vertex attributes in these cases, but haven't investigated that - if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { + // local coords then we won't be able to combine. TODO: Upload local coords as an attribute. + if (fHelper.usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { return false; } - // In the event of two ops, one who can tweak, one who cannot, we just fall back to not - // tweaking. - if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) { - fCanTweakAlphaForCoverage = false; - } - fRects.push_back_n(that->fRects.count(), that->fRects.begin()); this->joinBounds(*that); return true; @@ -569,31 +566,43 @@ void AAStrokeRectOp::generateAAStrokeRectGeometry(void* vertices, } } -namespace GrAAStrokeRectOp { +namespace GrRectOpFactory { -std::unique_ptr<GrLegacyMeshDrawOp> MakeFillBetweenRects(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& devOutside, - const SkRect& devInside) { - return std::unique_ptr<GrLegacyMeshDrawOp>( - new AAStrokeRectOp(color, viewMatrix, devOutside, devInside)); -} +std::unique_ptr<GrDrawOp> MakeAAFillNestedRects(GrPaint&& paint, + const SkMatrix& viewMatrix, + const SkRect rects[2]) { + SkASSERT(viewMatrix.rectStaysRect()); + SkASSERT(!rects[0].isEmpty() && !rects[1].isEmpty()); -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec& stroke) { - return AAStrokeRectOp::Make(color, viewMatrix, rect, stroke); + SkRect devOutside, devInside; + viewMatrix.mapRect(&devOutside, rects[0]); + viewMatrix.mapRect(&devInside, rects[1]); + if (devInside.isEmpty()) { + if (devOutside.isEmpty()) { + return nullptr; + } + return MakeAAFillWithDevRect(std::move(paint), viewMatrix, rects[0], devOutside); + } + + return AAStrokeRectOp::Make(std::move(paint), viewMatrix, devOutside, devInside); } + +std::unique_ptr<GrDrawOp> MakeAAStroke(GrPaint&& paint, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke) { + return AAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, stroke); } +} // namespace GrRectOpFactory + /////////////////////////////////////////////////////////////////////////////////////////////////// #if GR_TEST_UTILS #include "GrDrawOpTest.h" -GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) { +GR_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) { bool miterStroke = random->nextBool(); // Create either a empty rect or a non-empty rect. @@ -602,14 +611,12 @@ GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) { SkScalar minDim = SkMinScalar(rect.width(), rect.height()); SkScalar strokeWidth = random->nextUScalar1() * minDim; - GrColor color = GrRandomColor(random); - SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); rec.setStrokeStyle(strokeWidth); rec.setStrokeParams(SkPaint::kButt_Cap, miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Join, 1.f); SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random); - return GrAAStrokeRectOp::Make(color, matrix, rect, rec); + return GrRectOpFactory::MakeAAStroke(std::move(paint), matrix, rect, rec); } #endif diff --git a/src/gpu/ops/GrAAStrokeRectOp.h b/src/gpu/ops/GrAAStrokeRectOp.h deleted file mode 100644 index 074f8e00e9..0000000000 --- a/src/gpu/ops/GrAAStrokeRectOp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrAAStrokeRectOp_DEFINED -#define GrAAStrokeRectOp_DEFINED - -#include "GrColor.h" -#include "SkRefCnt.h" - -class GrLegacyMeshDrawOp; -class SkMatrix; -struct SkRect; -class SkStrokeRec; - -namespace GrAAStrokeRectOp { - -std::unique_ptr<GrLegacyMeshDrawOp> MakeFillBetweenRects(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& devOutside, - const SkRect& devInside); - -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec& stroke); -} - -#endif diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index bc5702b393..c712a9c6bc 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -6,7 +6,6 @@ */ #include "GrDefaultPathRenderer.h" - #include "GrContext.h" #include "GrDefaultGeoProcFactory.h" #include "GrDrawOpTest.h" @@ -20,9 +19,8 @@ #include "SkStrokeRec.h" #include "SkTLazy.h" #include "SkTraceEvent.h" - #include "ops/GrMeshDrawOp.h" -#include "ops/GrNonAAFillRectOp.h" +#include "ops/GrRectOpFactory.h" GrDefaultPathRenderer::GrDefaultPathRenderer() { } @@ -522,8 +520,8 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget viewMatrix; renderTargetContext->addDrawOp( clip, - GrNonAAFillRectOp::Make(std::move(paint), viewM, bounds, nullptr, &localMatrix, - aaType, passes[p])); + GrRectOpFactory::MakeNonAAFillWithLocalMatrix( + std::move(paint), viewM, localMatrix, bounds, aaType, passes[p])); } else { std::unique_ptr<GrLegacyMeshDrawOp> op = DefaultPathOp::Make(paint.getColor(), path, srcSpaceTol, newCoverage, diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp index ef64ecfe7d..f49c8cd586 100644 --- a/src/gpu/ops/GrMSAAPathRenderer.cpp +++ b/src/gpu/ops/GrMSAAPathRenderer.cpp @@ -6,7 +6,6 @@ */ #include "GrMSAAPathRenderer.h" - #include "GrAuditTrail.h" #include "GrClip.h" #include "GrDefaultGeoProcFactory.h" @@ -26,7 +25,7 @@ #include "glsl/GrGLSLUtil.h" #include "glsl/GrGLSLVertexShaderBuilder.h" #include "ops/GrMeshDrawOp.h" -#include "ops/GrNonAAFillRectOp.h" +#include "ops/GrRectOpFactory.h" static const float kTolerance = 0.5f; @@ -667,8 +666,8 @@ bool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetCon (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() : viewMatrix; renderTargetContext->addDrawOp( clip, - GrNonAAFillRectOp::Make(std::move(paint), viewM, bounds, nullptr, &localMatrix, - aaType, passes[1])); + GrRectOpFactory::MakeNonAAFillWithLocalMatrix(std::move(paint), viewM, localMatrix, + bounds, aaType, passes[1])); } return true; } diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp index defc7907b9..c30f4a198c 100644 --- a/src/gpu/ops/GrNonAAFillRectOp.cpp +++ b/src/gpu/ops/GrNonAAFillRectOp.cpp @@ -5,7 +5,6 @@ * found in the LICENSE file. */ -#include "GrNonAAFillRectOp.h" #include "GrAppliedClip.h" #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" @@ -14,6 +13,7 @@ #include "GrOpFlushState.h" #include "GrPrimitiveProcessor.h" #include "GrQuad.h" +#include "GrRectOpFactory.h" #include "GrResourceProvider.h" #include "GrSimpleMeshDrawOpHelper.h" #include "SkMatrixPriv.h" @@ -358,25 +358,45 @@ private: } // anonymous namespace -namespace GrNonAAFillRectOp { - -std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect* localRect, - const SkMatrix* localMatrix, - GrAAType aaType, - const GrUserStencilSettings* stencilSettings) { - if (!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective())) { - return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, localRect, localMatrix, +namespace GrRectOpFactory { + +std::unique_ptr<GrDrawOp> MakeNonAAFill(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& rect, GrAAType aaType, + const GrUserStencilSettings* stencilSettings) { + if (viewMatrix.hasPerspective()) { + return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr, + nullptr, aaType, stencilSettings); + } else { + return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, nullptr, aaType, + stencilSettings); + } +} + +std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix( + GrPaint&& paint, const SkMatrix& viewMatrix, const SkMatrix& localMatrix, + const SkRect& rect, GrAAType aaType, const GrUserStencilSettings* stencilSettings) { + if (viewMatrix.hasPerspective() || localMatrix.hasPerspective()) { + return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr, + &localMatrix, aaType, stencilSettings); + } else { + return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, &localMatrix, aaType, stencilSettings); + } +} + +std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& rect, const SkRect& localRect, + GrAAType aaType) { + if (viewMatrix.hasPerspective()) { + return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, &localRect, + nullptr, aaType, nullptr); } else { - return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, localRect, - localMatrix, aaType, stencilSettings); + return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, &localRect, nullptr, + aaType, nullptr); } } -}; // namespace GrNonAAFillRectOp +} // namespace GrRectOpFactory /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -385,14 +405,17 @@ GR_DRAW_OP_TEST_DEFINE(NonAAFillRectOp) { SkRect localRect = GrTest::TestRect(random); SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); SkMatrix localMatrix = GrTest::TestMatrix(random); - bool hasLocalRect = random->nextBool(); - bool hasLocalMatrix = random->nextBool(); const GrUserStencilSettings* stencil = GrGetRandomStencil(random, context); GrAAType aaType = GrAAType::kNone; if (fsaaType == GrFSAAType::kUnifiedMSAA) { aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone; } - return GrNonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, - hasLocalRect ? &localRect : nullptr, - hasLocalMatrix ? &localMatrix : nullptr, aaType, stencil); + const SkRect* lr = random->nextBool() ? &localRect : nullptr; + const SkMatrix* lm = random->nextBool() ? &localMatrix : nullptr; + if (viewMatrix.hasPerspective() || (lm && lm->hasPerspective())) { + return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType, + stencil); + } else { + return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType, stencil); + } } diff --git a/src/gpu/ops/GrNonAAFillRectOp.h b/src/gpu/ops/GrNonAAFillRectOp.h deleted file mode 100644 index 70dd8fdcb5..0000000000 --- a/src/gpu/ops/GrNonAAFillRectOp.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrNonAAFillRectOp_DEFINED -#define GrNonAAFillRectOp_DEFINED - -#include <memory> -#include "GrColor.h" -#include "GrDrawOp.h" - -class GrPaint; -class SkMatrix; -struct SkRect; -struct GrUserStencilSettings; -enum class GrAAType : unsigned; - -namespace GrNonAAFillRectOp { -std::unique_ptr<GrDrawOp> Make(GrPaint&&, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect* localRect, - const SkMatrix* localMatrix, - GrAAType, - const GrUserStencilSettings* = nullptr); -}; - -#endif diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp index 94dc373fc6..4177b6526e 100644 --- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp @@ -5,15 +5,15 @@ * found in the LICENSE file. */ -#include "GrNonAAStrokeRectOp.h" - #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" #include "GrDrawOpTest.h" #include "GrMeshDrawOp.h" #include "GrOpFlushState.h" -#include "SkStrokeRec.h" +#include "GrRectOpFactory.h" +#include "GrSimpleMeshDrawOpHelper.h" #include "SkRandom.h" +#include "SkStrokeRec.h" /* create a triangle strip that strokes the specified rect. There are 8 unique vertices, but we repeat the last 2 to close up. Alternatively we @@ -46,7 +46,12 @@ inline static bool allowed_stroke(const SkStrokeRec& stroke) { (stroke.getJoin() == SkPaint::kMiter_Join && stroke.getMiter() > SK_ScalarSqrt2); } -class NonAAStrokeRectOp final : public GrLegacyMeshDrawOp { +namespace { + +class NonAAStrokeRectOp final : public GrMeshDrawOp { +private: + using Helper = GrSimpleMeshDrawOpHelper; + public: DEFINE_OP_CLASS_ID @@ -58,31 +63,44 @@ public: "Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], " "StrokeWidth: %.2f\n", fColor, fRect.fLeft, fRect.fTop, fRect.fRight, fRect.fBottom, fStrokeWidth); - string.append(DumpPipelineInfo(*this->pipeline())); string.append(INHERITED::dumpInfo()); return string; } - static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, - const SkRect& rect, const SkStrokeRec& stroke, - bool snapToPixelCenters) { + static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& rect, const SkStrokeRec& stroke, + GrAAType aaType) { if (!allowed_stroke(stroke)) { return nullptr; } - NonAAStrokeRectOp* op = new NonAAStrokeRectOp(); - op->fColor = color; - op->fViewMatrix = viewMatrix; - op->fRect = rect; + Helper::Flags flags = Helper::Flags::kNone; + // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of + // hairline rects. We jam all the vertices to pixel centers to avoid this, but not + // when MSAA is enabled because it can cause ugly artifacts. + if (stroke.getStyle() == SkStrokeRec::kHairline_Style && aaType != GrAAType::kMSAA) { + flags |= Helper::Flags::kSnapVerticesToPixelCenters; + } + return Helper::FactoryHelper<NonAAStrokeRectOp>(std::move(paint), flags, viewMatrix, rect, + stroke, aaType); + } + + NonAAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, Helper::Flags flags, + const SkMatrix& viewMatrix, const SkRect& rect, const SkStrokeRec& stroke, + GrAAType aaType) + : INHERITED(ClassID()), fHelper(helperArgs, aaType, flags) { + fColor = color; + fViewMatrix = viewMatrix; + fRect = rect; // Sort the rect for hairlines - op->fRect.sort(); - op->fStrokeWidth = stroke.getWidth(); + fRect.sort(); + fStrokeWidth = stroke.getWidth(); - SkScalar rad = SkScalarHalf(op->fStrokeWidth); + SkScalar rad = SkScalarHalf(fStrokeWidth); SkRect bounds = rect; bounds.outset(rad, rad); // If our caller snaps to pixel centers then we have to round out the bounds - if (snapToPixelCenters) { + if (flags & Helper::Flags::kSnapVerticesToPixelCenters) { viewMatrix.mapRect(&bounds); // We want to be consistent with how we snap non-aa lines. To match what we do in // GrGLSLVertexShaderBuilder, we first floor all the vertex values and then add half a @@ -92,28 +110,27 @@ public: SkScalarFloorToScalar(bounds.fRight), SkScalarFloorToScalar(bounds.fBottom)); bounds.offset(0.5f, 0.5f); - op->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); + this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); } else { - op->setTransformedBounds(bounds, op->fViewMatrix, HasAABloat::kNo, IsZeroArea::kNo); + this->setTransformedBounds(bounds, fViewMatrix, HasAABloat::kNo, IsZeroArea::kNo); } - return std::unique_ptr<GrLegacyMeshDrawOp>(op); } -private: - NonAAStrokeRectOp() : INHERITED(ClassID()) {} + FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); } - void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color, - GrProcessorAnalysisCoverage* coverage) const override { - color->setToConstant(fColor); - *coverage = GrProcessorAnalysisCoverage::kNone; + bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { + bool result = fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, + &fColor); + return result; } +private: void onPrepareDraws(Target* target) const override { sk_sp<GrGeometryProcessor> gp; { using namespace GrDefaultGeoProcFactory; Color color(fColor); - LocalCoords::Type localCoordsType = fNeedsLocalCoords + LocalCoords::Type localCoordsType = fHelper.usesLocalCoords() ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; gp = GrDefaultGeoProcFactory::Make(color, Coverage::kSolid_Type, localCoordsType, @@ -159,12 +176,7 @@ private: GrMesh mesh(primType); mesh.setNonIndexedNonInstanced(vertexCount); mesh.setVertexData(vertexBuffer, firstVertex); - target->draw(gp.get(), this->pipeline(), mesh); - } - - void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override { - optimizations.getOverrideColorIfSet(&fColor); - fNeedsLocalCoords = optimizations.readsLocalCoords(); + target->draw(gp.get(), fHelper.makePipeline(target), mesh); } bool onCombineIfPossible(GrOp* t, const GrCaps&) override { @@ -173,42 +185,46 @@ private: return false; } + Helper fHelper; GrColor fColor; SkMatrix fViewMatrix; SkRect fRect; SkScalar fStrokeWidth; - bool fNeedsLocalCoords; const static int kVertsPerHairlineRect = 5; const static int kVertsPerStrokeRect = 10; - typedef GrLegacyMeshDrawOp INHERITED; + typedef GrMeshDrawOp INHERITED; }; -namespace GrNonAAStrokeRectOp { +} // anonymous namespace -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec& stroke, - bool snapToPixelCenters) { - return NonAAStrokeRectOp::Make(color, viewMatrix, rect, stroke, snapToPixelCenters); -} +namespace GrRectOpFactory { +std::unique_ptr<GrDrawOp> MakeNonAAStroke(GrPaint&& paint, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke, + GrAAType aaType) { + return NonAAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, stroke, aaType); } +} // namespace GrRectOpFactory #if GR_TEST_UTILS -GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(NonAAStrokeRectOp) { +GR_DRAW_OP_TEST_DEFINE(NonAAStrokeRectOp) { SkMatrix viewMatrix = GrTest::TestMatrix(random); - GrColor color = GrRandomColor(random); SkRect rect = GrTest::TestRect(random); SkScalar strokeWidth = random->nextBool() ? 0.0f : 2.0f; - SkPaint paint; - paint.setStrokeWidth(strokeWidth); - paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeJoin(SkPaint::kMiter_Join); - SkStrokeRec strokeRec(paint); - return GrNonAAStrokeRectOp::Make(color, viewMatrix, rect, strokeRec, random->nextBool()); + SkPaint strokePaint; + strokePaint.setStrokeWidth(strokeWidth); + strokePaint.setStyle(SkPaint::kStroke_Style); + strokePaint.setStrokeJoin(SkPaint::kMiter_Join); + SkStrokeRec strokeRec(strokePaint); + GrAAType aaType = GrAAType::kNone; + if (fsaaType == GrFSAAType::kUnifiedMSAA) { + aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone; + } + return NonAAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, strokeRec, aaType); } #endif diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.h b/src/gpu/ops/GrNonAAStrokeRectOp.h deleted file mode 100644 index 4071cfd2a9..0000000000 --- a/src/gpu/ops/GrNonAAStrokeRectOp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrNonAAStrokeRectOp_DEFINED -#define GrNonAAStrokeRectOp_DEFINED - -#include "GrColor.h" -#include "SkRefCnt.h" - -class GrLegacyMeshDrawOp; -struct SkRect; -class SkStrokeRec; -class SkMatrix; - -namespace GrNonAAStrokeRectOp { - -std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec&, - bool snapToPixelCenters); -} - -#endif diff --git a/src/gpu/ops/GrRectOpFactory.cpp b/src/gpu/ops/GrRectOpFactory.cpp deleted file mode 100644 index 45e2053f8d..0000000000 --- a/src/gpu/ops/GrRectOpFactory.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrRectOpFactory.h" - -#include "GrAAStrokeRectOp.h" -#include "GrMeshDrawOp.h" -#include "SkStrokeRec.h" - -namespace GrRectOpFactory { - -std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFillNestedRects(GrColor color, - const SkMatrix& viewMatrix, - const SkRect rects[2]) { - SkASSERT(viewMatrix.rectStaysRect()); - SkASSERT(!rects[0].isEmpty() && !rects[1].isEmpty()); - - SkRect devOutside, devInside; - viewMatrix.mapRect(&devOutside, rects[0]); - viewMatrix.mapRect(&devInside, rects[1]); - if (devInside.isEmpty()) { - if (devOutside.isEmpty()) { - return nullptr; - } - return GrAAFillRectOp::Make(color, viewMatrix, devOutside, devOutside); - } - - return GrAAStrokeRectOp::MakeFillBetweenRects(color, viewMatrix, devOutside, devInside); -} -}; diff --git a/src/gpu/ops/GrRectOpFactory.h b/src/gpu/ops/GrRectOpFactory.h index 58927ef91b..cf3da2f8bd 100644 --- a/src/gpu/ops/GrRectOpFactory.h +++ b/src/gpu/ops/GrRectOpFactory.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. + * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. @@ -8,58 +8,66 @@ #ifndef GrRectOpFactory_DEFINED #define GrRectOpFactory_DEFINED -#include "GrAAFillRectOp.h" -#include "GrAAStrokeRectOp.h" -#include "GrAnalyticRectOp.h" -#include "GrColor.h" -#include "GrMeshDrawOp.h" -#include "GrNonAAStrokeRectOp.h" -#include "GrPaint.h" -#include "SkMatrix.h" -#include "SkRefCnt.h" +#include <memory> +#include "GrTypes.h" +enum class GrAAType : unsigned; +class GrDrawOp; +class GrPaint; +struct GrUserStencilSettings; +class SkMatrix; struct SkRect; class SkStrokeRec; /** - * A factory for returning GrDrawOps which can draw rectangles. + * A set of factory functions for drawing rectangles including fills, strokes, coverage-antialiased, + * and non-antialiased. The non-antialiased ops can be used with MSAA. As with other GrDrawOp + * factories, the GrPaint is only consumed by these methods if a valid op is returned. If null is + * returned then the paint is unmodified and may still be used. */ namespace GrRectOpFactory { +/** AA Fill */ -inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFill(const GrPaint& paint, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& croppedRect, - const SkRect& devRect) { - return GrAAFillRectOp::Make(paint.getColor(), viewMatrix, croppedRect, devRect); -} - -inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFill(GrColor color, - const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, - const SkRect& rect, - const SkRect& devRect) { - return GrAAFillRectOp::Make(color, viewMatrix, localMatrix, rect, devRect); -} - -inline std::unique_ptr<GrLegacyMeshDrawOp> MakeNonAAStroke(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec& strokeRec, - bool snapToPixelCenters) { - return GrNonAAStrokeRectOp::Make(color, viewMatrix, rect, strokeRec, snapToPixelCenters); -} - -inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAStroke(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec& stroke) { - return GrAAStrokeRectOp::Make(color, viewMatrix, rect, stroke); -} - -// First rect is outer; second rect is inner -std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFillNestedRects(GrColor, const SkMatrix& viewMatrix, - const SkRect rects[2]); -}; +std::unique_ptr<GrDrawOp> MakeAAFill(GrPaint&&, const SkMatrix&, const SkRect&, + const GrUserStencilSettings* = nullptr); + +// Using this method to supply a device rect simply saves recalculation if the device rect is known. +std::unique_ptr<GrDrawOp> MakeAAFillWithDevRect(GrPaint&&, const SkMatrix& viewMatrix, + const SkRect& rect, const SkRect& devRect); + +std::unique_ptr<GrDrawOp> MakeAAFillWithLocalMatrix(GrPaint&&, const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, const SkRect&); + +std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrPaint&&, const SkMatrix&, const SkRect& rect, + const SkRect& localRect); + +/** Non-AA Fill - GrAAType must be either kNone or kMSAA. */ + +std::unique_ptr<GrDrawOp> MakeNonAAFill(GrPaint&&, const SkMatrix& viewMatrix, const SkRect& rect, + GrAAType, const GrUserStencilSettings* = nullptr); + +std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix(GrPaint&&, const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, const SkRect&, + GrAAType, + const GrUserStencilSettings* = nullptr); + +std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrPaint&&, const SkMatrix&, const SkRect& rect, + const SkRect& localRect, GrAAType); + +/** AA Stroke */ + +std::unique_ptr<GrDrawOp> MakeAAStroke(GrPaint&&, const SkMatrix&, const SkRect&, + const SkStrokeRec&); + +// rects[0] == outer rectangle, rects[1] == inner rectangle. Null return means there is nothing to +// draw rather than failure. +std::unique_ptr<GrDrawOp> MakeAAFillNestedRects(GrPaint&&, const SkMatrix&, const SkRect rects[2]); + +/** Non-AA Stroke - GrAAType must be either kNone or kMSAA. */ + +std::unique_ptr<GrDrawOp> MakeNonAAStroke(GrPaint&&, const SkMatrix&, const SkRect&, + const SkStrokeRec&, GrAAType); + +} // namespace GrRectOpFactory #endif diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h index dcd8dd887e..903859c309 100644 --- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h +++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h @@ -35,19 +35,26 @@ public: template <typename Op, typename... OpArgs> static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs); - GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType, - GrUserStencilSettings* stencilSettings = nullptr) + enum class Flags : uint32_t { + kNone = 0x0, + kSnapVerticesToPixelCenters = 0x1, + }; + GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags); + + GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType, Flags flags = Flags::kNone) : fProcessors(args.fProcessorSet) , fPipelineFlags(args.fSRGBFlags) , fAAType((int)aaType) , fRequiresDstTexture(false) , fUsesLocalCoords(false) , fCompatibleWithAlphaAsCoveage(false) { - SkASSERT(!stencilSettings); SkDEBUGCODE(fDidAnalysis = false); if (GrAATypeIsHW(aaType)) { fPipelineFlags |= GrPipeline::kHWAntialias_Flag; } + if (flags & Flags::kSnapVerticesToPixelCenters) { + fPipelineFlags |= GrPipeline::kSnapVerticesToPixelCenters_Flag; + } } ~GrSimpleMeshDrawOpHelper() { @@ -167,6 +174,7 @@ private: class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper { public: using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs; + using Flags = GrSimpleMeshDrawOpHelper::Flags; // using declarations can't be templated, so this is a pass through function instead. template <typename Op, typename... OpArgs> @@ -176,8 +184,9 @@ public: } GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs& args, GrAAType aaType, - const GrUserStencilSettings* stencilSettings) - : INHERITED(args, aaType) + const GrUserStencilSettings* stencilSettings, + Flags flags = Flags::kNone) + : INHERITED(args, aaType, flags) , fStencilSettings(stencilSettings ? stencilSettings : &GrUserStencilSettings::kUnused) {} @@ -191,6 +200,7 @@ public: using GrSimpleMeshDrawOpHelper::xpRequiresDstTexture; using GrSimpleMeshDrawOpHelper::usesLocalCoords; + using GrSimpleMeshDrawOpHelper::compatibleWithAlphaAsCoverage; bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps& caps, const SkRect& aBounds, const SkRect& bBounds) const { @@ -227,4 +237,6 @@ std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrPaint&& pain } } +GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::Flags) + #endif diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp index 46e9fa7aae..a613841d9a 100644 --- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp @@ -17,7 +17,7 @@ #include "GrResourceProvider.h" #include "GrStencilPathOp.h" #include "GrStyle.h" -#include "ops/GrNonAAFillRectOp.h" +#include "ops/GrRectOpFactory.h" GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resourceProvider, const GrCaps& caps) { @@ -134,10 +134,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { if (GrAAType::kMixedSamples == coverAAType) { coverAAType = GrAAType::kNone; } - args.fRenderTargetContext->addDrawOp( - *args.fClip, - GrNonAAFillRectOp::Make(std::move(args.fPaint), viewM, bounds, nullptr, &invert, - coverAAType, &kInvertedCoverPass)); + args.fRenderTargetContext->addDrawOp(*args.fClip, + GrRectOpFactory::MakeNonAAFillWithLocalMatrix( + std::move(args.fPaint), viewM, invert, + bounds, coverAAType, &kInvertedCoverPass)); } } else { std::unique_ptr<GrDrawOp> op = |