Use FillRRectOp in drawStrokedLine for dmsaa This makes it so we don't trigger msaa in drawStrokedLine anymore. Bug: skia:skia:12872 Change-Id: Id68b55ba9e3989f2a775affe9a1b20bf3186123c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/502816 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Christopher Dalton <csmartdalton@google.com>
diff --git a/gm/drawlines_with_local_matrix.cpp b/gm/drawlines_with_local_matrix.cpp new file mode 100644 index 0000000..0fca912 --- /dev/null +++ b/gm/drawlines_with_local_matrix.cpp
@@ -0,0 +1,47 @@ +/* + * Copyright 2022 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm/gm.h" +#include "include/core/SkCanvas.h" +#include "include/core/SkPaint.h" +#include "include/effects/SkGradientShader.h" + +DEF_SIMPLE_GM(drawlines_with_local_matrix, canvas, 500, 500) { + canvas->clipRect({0,0,500,500}); + SkPaint grad; + grad.setAntiAlias(true); + grad.setStrokeCap(SkPaint::kSquare_Cap); + float pos[6] = {0, 2/6.f, 3/6.f, 4/6.f, 5/6.f, 1}; + constexpr SkColor indigo = SkColorSetARGB(0xFF, 0x4b, 0x00, 0x82); + constexpr SkColor violet = SkColorSetARGB(0xFF, 0xee, 0x82, 0xee); + SkColor colors[6] = {SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorBLUE, indigo, violet}; + grad.setShader(SkGradientShader::MakeRadial({250,250}, 280, colors, pos, 6,SkTileMode::kClamp)); + canvas->drawPaint(grad); + + SkPaint white; + white.setAntiAlias(true); + white.setStrokeCap(SkPaint::kSquare_Cap); + white.setColor(SK_ColorWHITE); + + auto drawLine = [&](float x0, float y0, float x1, float y1, float w) { + SkPoint p[2] = {{x0, y0}, {x1, y1}}; + white.setStrokeWidth(w); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, p, white); + grad.setStrokeWidth(w - 4); + canvas->drawPoints(SkCanvas::kLines_PointMode, 2, p, grad); + }; + + drawLine(20, 20, 200, 120, 20); + drawLine(20, 200, 20, 100, 20); + drawLine(480, 20, 400, 400, 20); + drawLine(50, 480, 260, 100, 20); + drawLine(270, 20, 380, 210, 20); + drawLine(280, 280, 400, 480, 20); + drawLine(160, 375, 280, 375, 20); + drawLine(220, 410, 220, 470, 20); + drawLine(250, 250, 250, 250, 20); +}
diff --git a/gn/gm.gni b/gn/gm.gni index c3132f6..e0a4d38 100644 --- a/gn/gm.gni +++ b/gn/gm.gni
@@ -157,6 +157,7 @@ "$_gm/drawbitmaprect.cpp", "$_gm/drawglyphs.cpp", "$_gm/drawimageset.cpp", + "$_gm/drawlines_with_local_matrix.cpp", "$_gm/drawminibitmaprect.cpp", "$_gm/drawregion.cpp", "$_gm/drawregionmodes.cpp",
diff --git a/src/gpu/ops/FillRRectOp.cpp b/src/gpu/ops/FillRRectOp.cpp index a8b9b1f..b9e0d7f5 100644 --- a/src/gpu/ops/FillRRectOp.cpp +++ b/src/gpu/ops/FillRRectOp.cpp
@@ -38,12 +38,27 @@ public: DEFINE_OP_CLASS_ID + struct LocalCoords { + enum class Type : bool { kRect, kMatrix }; + LocalCoords(const SkRect& localRect) + : fType(Type::kRect) + , fRect(localRect) {} + LocalCoords(const SkMatrix& localMatrix) + : fType(Type::kMatrix) + , fMatrix(localMatrix) {} + Type fType; + union { + SkRect fRect; + SkMatrix fMatrix; + }; + }; + static GrOp::Owner Make(GrRecordingContext*, SkArenaAlloc*, GrPaint&&, const SkMatrix& viewMatrix, const SkRRect&, - const SkRect& localRect, + const LocalCoords&, GrAA); const char* name() const override { return "FillRRectOp"; } @@ -94,7 +109,7 @@ SkArenaAlloc*, const SkMatrix& viewMatrix, const SkRRect&, - const SkRect& localRect, + const LocalCoords&, ProcessorFlags); GrProgramInfo* programInfo() override { return fProgramInfo; } @@ -112,25 +127,12 @@ Helper fHelper; ProcessorFlags fProcessorFlags; - struct LocalCoords { - enum class Type : bool { kRect, kMatrix }; - LocalCoords(const SkRect& localRect) - : fType(Type::kRect) - , fRect(localRect) {} - LocalCoords(const SkMatrix& localMatrix) - : fType(Type::kMatrix) - , fMatrix(localMatrix) {} - Type fType; - union { - SkRect fRect; - SkMatrix fMatrix; - }; - }; - struct Instance { - Instance(const SkMatrix& viewMatrix, const SkRRect& rrect, const SkRect& localRect, + Instance(const SkMatrix& viewMatrix, + const SkRRect& rrect, + const LocalCoords& localCoords, const SkPMColor4f& color) - : fViewMatrix(viewMatrix), fRRect(rrect), fLocalCoords(localRect), fColor(color) { + : fViewMatrix(viewMatrix), fRRect(rrect), fLocalCoords(localCoords), fColor(color) { } SkMatrix fViewMatrix; SkRRect fRRect; @@ -166,7 +168,7 @@ GrPaint&& paint, const SkMatrix& viewMatrix, const SkRRect& rrect, - const SkRect& localRect, + const LocalCoords& localCoords, GrAA aa) { const GrCaps* caps = ctx->priv().caps(); @@ -197,7 +199,7 @@ } return Helper::FactoryHelper<FillRRectOpImpl>(ctx, std::move(paint), arena, viewMatrix, rrect, - localRect, flags); + localCoords, flags); } FillRRectOpImpl::FillRRectOpImpl(GrProcessorSet* processorSet, @@ -205,7 +207,7 @@ SkArenaAlloc* arena, const SkMatrix& viewMatrix, const SkRRect& rrect, - const SkRect& localRect, + const LocalCoords& localCoords, ProcessorFlags processorFlags) : GrMeshDrawOp(ClassID()) , fHelper(processorSet, @@ -215,7 +217,7 @@ , fProcessorFlags(processorFlags & ~(ProcessorFlags::kHasLocalCoords | ProcessorFlags::kWideColor | ProcessorFlags::kMSAAEnabled)) - , fHeadInstance(arena->make<Instance>(viewMatrix, rrect, localRect, paintColor)) + , fHeadInstance(arena->make<Instance>(viewMatrix, rrect, localCoords, paintColor)) , fTailInstance(&fHeadInstance->fNext) { // FillRRectOp::Make fails if there is perspective. SkASSERT(!viewMatrix.hasPerspective()); @@ -906,6 +908,16 @@ return FillRRectOpImpl::Make(ctx, arena, std::move(paint), viewMatrix, rrect, localRect, aa); } +GrOp::Owner Make(GrRecordingContext* ctx, + SkArenaAlloc* arena, + GrPaint&& paint, + const SkMatrix& viewMatrix, + const SkRRect& rrect, + const SkMatrix& localMatrix, + GrAA aa) { + return FillRRectOpImpl::Make(ctx, arena, std::move(paint), viewMatrix, rrect, localMatrix, aa); +} + } // namespace skgpu::v1::FillRRectOp #if GR_TEST_UTILS
diff --git a/src/gpu/ops/FillRRectOp.h b/src/gpu/ops/FillRRectOp.h index 478cb6c..0443b0f 100644 --- a/src/gpu/ops/FillRRectOp.h +++ b/src/gpu/ops/FillRRectOp.h
@@ -27,6 +27,14 @@ const SkRect& localRect, GrAA); + GrOp::Owner Make(GrRecordingContext*, + SkArenaAlloc*, + GrPaint&&, + const SkMatrix& viewMatrix, + const SkRRect&, + const SkMatrix& localMatrix, + GrAA); + } // namespace skgpu::v1::FillRRectOp #endif // FillRRectOp_DEFINED
diff --git a/src/gpu/v1/SurfaceDrawContext.cpp b/src/gpu/v1/SurfaceDrawContext.cpp index ae60262..2c057f3 100644 --- a/src/gpu/v1/SurfaceDrawContext.cpp +++ b/src/gpu/v1/SurfaceDrawContext.cpp
@@ -1687,17 +1687,41 @@ parallel *= halfWidth; SkVector ortho = { parallel.fY, -parallel.fX }; - if (SkPaint::kButt_Cap == stroke.getCap()) { - // No extra extension for butt caps - parallel = {0.f, 0.f}; + SkPoint p0 = points[0], p1 = points[1]; + if (stroke.getCap() == SkPaint::kSquare_Cap) { + // Extra extension for square caps + p0 -= parallel; + p1 += parallel; } + + // If we are using dmsaa or reduced shader mode then attempt to draw with FillRRectOp. + if (this->caps()->drawInstancedSupport() && + (this->alwaysAntialias() || + (fContext->priv().caps()->reducedShaderMode() && aa == GrAA::kYes))) { + SkMatrix localMatrix = SkMatrix::MakeAll(p1.fX - p0.fX, ortho.fX, p0.fX, + p1.fY - p0.fY, ortho.fY, p0.fY, + 0, 0, 1); + if (auto op = FillRRectOp::Make(fContext, + this->arenaAlloc(), + std::move(paint), + SkMatrix::Concat(viewMatrix, localMatrix), + SkRRect::MakeRect({0,-1,1,1}), + localMatrix, + GrAA::kYes)) { + this->addDrawOp(clip, std::move(op)); + return; + } + } + // Order is TL, TR, BR, BL where arbitrarily "down" is p0 to p1 and "right" is positive - SkPoint corners[4] = { points[0] - ortho - parallel, - points[0] + ortho - parallel, - points[1] + ortho + parallel, - points[1] - ortho + parallel }; + SkPoint corners[4] = { p0 - ortho, + p0 + ortho, + p1 + ortho, + p1 - ortho }; GrQuadAAFlags edgeAA = (aa == GrAA::kYes) ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone; + + assert_alive(paint); this->fillQuadWithEdgeAA(clip, std::move(paint), aa, edgeAA, viewMatrix, corners, nullptr); }