diff options
Diffstat (limited to 'src/gpu/ops/GrAAStrokeRectOp.cpp')
-rw-r--r-- | src/gpu/ops/GrAAStrokeRectOp.cpp | 147 |
1 files changed, 77 insertions, 70 deletions
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 |