Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c3b67eb

Browse files
csmartdalton86Skia Commit-Bot
authored andcommitted
Add a "conservative raster" flag for GrFillRectOp
Adds the ability to fill a rect with conservative raster enabled, and fixes a bug in the gpu tessellation atlas where there were artifacts from mixed samples. Change-Id: Ic0b4f2059129ac238fdcb08d43896fc2b9e50211 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/269989 Reviewed-by: Michael Ludwig <[email protected]> Commit-Queue: Chris Dalton <[email protected]>
1 parent e32506b commit c3b67eb

File tree

5 files changed

+49
-21
lines changed

5 files changed

+49
-21
lines changed

src/gpu/ops/GrFillRectOp.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "src/gpu/glsl/GrGLSLVarying.h"
2222
#include "src/gpu/ops/GrMeshDrawOp.h"
2323
#include "src/gpu/ops/GrQuadPerEdgeAA.h"
24-
#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
2524

2625
namespace {
2726

@@ -65,20 +64,21 @@ class FillRectOp final : public GrMeshDrawOp {
6564
GrPaint&& paint,
6665
GrAAType aaType,
6766
DrawQuad* quad,
68-
const GrUserStencilSettings* stencilSettings) {
67+
const GrUserStencilSettings* stencilSettings,
68+
Helper::InputFlags inputFlags) {
6969
// Clean up deviations between aaType and edgeAA
7070
GrQuadUtils::ResolveAAType(aaType, quad->fEdgeFlags, quad->fDevice,
7171
&aaType, &quad->fEdgeFlags);
7272
return Helper::FactoryHelper<FillRectOp>(context, std::move(paint), aaType, quad,
73-
stencilSettings);
73+
stencilSettings, inputFlags);
7474
}
7575

7676
// aaType is passed to Helper in the initializer list, so incongruities between aaType and
7777
// edgeFlags must be resolved prior to calling this constructor.
7878
FillRectOp(Helper::MakeArgs args, SkPMColor4f paintColor, GrAAType aaType,
79-
DrawQuad* quad, const GrUserStencilSettings* stencil)
79+
DrawQuad* quad, const GrUserStencilSettings* stencil, Helper::InputFlags inputFlags)
8080
: INHERITED(ClassID())
81-
, fHelper(args, aaType, stencil)
81+
, fHelper(args, aaType, stencil, inputFlags)
8282
, fQuads(1, !fHelper.isTrivial()) {
8383
// Set bounds before clipping so we don't have to worry about unioning the bounds of
8484
// the two potential quads (GrQuad::bounds() is perspective-safe).
@@ -425,8 +425,10 @@ std::unique_ptr<GrDrawOp> GrFillRectOp::Make(GrRecordingContext* context,
425425
GrPaint&& paint,
426426
GrAAType aaType,
427427
DrawQuad* quad,
428-
const GrUserStencilSettings* stencil) {
429-
return FillRectOp::Make(context, std::move(paint), aaType, std::move(quad), stencil);
428+
const GrUserStencilSettings* stencil,
429+
InputFlags inputFlags) {
430+
return FillRectOp::Make(context, std::move(paint), aaType, std::move(quad), stencil,
431+
inputFlags);
430432
}
431433

432434
std::unique_ptr<GrDrawOp> GrFillRectOp::MakeNonAARect(GrRecordingContext* context,
@@ -435,7 +437,8 @@ std::unique_ptr<GrDrawOp> GrFillRectOp::MakeNonAARect(GrRecordingContext* contex
435437
const SkRect& rect,
436438
const GrUserStencilSettings* stencil) {
437439
DrawQuad quad{GrQuad::MakeFromRect(rect, view), GrQuad(rect), GrQuadAAFlags::kNone};
438-
return FillRectOp::Make(context, std::move(paint), GrAAType::kNone, &quad, stencil);
440+
return FillRectOp::Make(context, std::move(paint), GrAAType::kNone, &quad, stencil,
441+
InputFlags::kNone);
439442
}
440443

441444
std::unique_ptr<GrDrawOp> GrFillRectOp::MakeOp(GrRecordingContext* context,
@@ -454,7 +457,7 @@ std::unique_ptr<GrDrawOp> GrFillRectOp::MakeOp(GrRecordingContext* context,
454457
quads[0].fAAFlags};
455458
paint.setColor4f(quads[0].fColor);
456459
std::unique_ptr<GrDrawOp> op = FillRectOp::Make(context, std::move(paint), aaType,
457-
&quad, stencilSettings);
460+
&quad, stencilSettings, InputFlags::kNone);
458461
FillRectOp* fillRects = op->cast<FillRectOp>();
459462

460463
*numConsumed = 1;

src/gpu/ops/GrFillRectOp.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "include/private/GrTypesPriv.h"
1212
#include "src/gpu/GrRenderTargetContext.h"
13+
#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
1314

1415
class GrDrawOp;
1516
class GrPaint;
@@ -27,12 +28,14 @@ struct SkRect;
2728
*/
2829
class GrFillRectOp {
2930
public:
31+
using InputFlags = GrSimpleMeshDrawOpHelper::InputFlags;
3032

3133
static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
3234
GrPaint&& paint,
3335
GrAAType aaType,
3436
DrawQuad* quad,
35-
const GrUserStencilSettings* stencil = nullptr);
37+
const GrUserStencilSettings* stencil = nullptr,
38+
InputFlags = InputFlags::kNone);
3639

3740
// Utility function to create a non-AA rect transformed by view. This is used commonly enough
3841
// in testing and GMs that manage ops without going through GrRTC that it's worth the

src/gpu/ops/GrSimpleMeshDrawOpHelper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class GrSimpleMeshDrawOpHelper {
4242
enum class InputFlags : uint8_t {
4343
kNone = 0,
4444
kSnapVerticesToPixelCenters = (uint8_t)GrPipeline::InputFlags::kSnapVerticesToPixelCenters,
45+
kConservativeRaster = (uint8_t)GrPipeline::InputFlags::kConservativeRaster,
4546
};
4647
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(InputFlags);
4748

src/gpu/tessellate/GrGpuTessellationPathRenderer.cpp

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
#include "src/gpu/GrMemoryPool.h"
1313
#include "src/gpu/GrRecordingContextPriv.h"
1414
#include "src/gpu/GrRenderTargetContext.h"
15-
#include "src/gpu/GrRenderTargetContextPriv.h"
15+
#include "src/gpu/GrSurfaceContextPriv.h"
1616
#include "src/gpu/geometry/GrShape.h"
17+
#include "src/gpu/ops/GrFillRectOp.h"
1718
#include "src/gpu/tessellate/GrDrawAtlasPathOp.h"
1819
#include "src/gpu/tessellate/GrTessellatePathOp.h"
1920

@@ -173,18 +174,39 @@ void GrGpuTessellationPathRenderer::renderAtlas(GrOnFlushResourceProvider* onFlu
173174
}
174175
}
175176

176-
// The next draw will be the final op in the renderTargetContext. So if Ganesh is planning
177-
// to discard the stencil values anyway, then we might not actually need to reset the
178-
// stencil values back to zero.
179-
bool mustResetStencil = !onFlushRP->caps()->discardStencilValuesAfterRenderPass() ||
180-
rtc->numSamples() <= 1; // Need a stencil reset for mixed samples.
177+
// Finally, draw a fullscreen rect to convert our stencilled paths into alpha coverage masks.
178+
auto fillRectFlags = GrFillRectOp::InputFlags::kNone;
179+
180+
// This will be the final op in the renderTargetContext. So if Ganesh is planning to discard the
181+
// stencil values anyway, then we might not actually need to reset the stencil values back to 0.
182+
bool mustResetStencil = !onFlushRP->caps()->discardStencilValuesAfterRenderPass();
183+
184+
if (rtc->numSamples() <= 1) {
185+
// We are mixed sampled. We need to enable conservative raster and ensure stencil values get
186+
// reset in order to avoid artifacts along the diagonal of the atlas.
187+
fillRectFlags |= GrFillRectOp::InputFlags::kConservativeRaster;
188+
mustResetStencil = true;
189+
}
190+
191+
SkRect coverRect = SkRect::MakeIWH(fAtlas.drawBounds().width(), fAtlas.drawBounds().height());
192+
const GrUserStencilSettings* stencil;
193+
if (mustResetStencil) {
194+
// Outset the cover rect in case there are T-junctions in the path bounds.
195+
coverRect.outset(1, 1);
196+
stencil = &kTestAndResetStencil;
197+
} else {
198+
stencil = &kTestStencil;
199+
}
200+
201+
GrQuad coverQuad(coverRect);
202+
DrawQuad drawQuad{coverQuad, coverQuad, GrQuadAAFlags::kAll};
181203

182-
// Draw a fullscreen rect to convert our stencilled paths into alpha coverage masks.
183204
GrPaint paint;
184205
paint.setColor4f(SK_PMColor4fWHITE);
185-
SkRect drawRect = SkRect::MakeIWH(fAtlas.drawBounds().width(), fAtlas.drawBounds().height());
186-
rtc->priv().stencilRect(GrNoClip(), (mustResetStencil) ? &kTestAndResetStencil : &kTestStencil,
187-
std::move(paint), GrAA::kYes, SkMatrix::I(), drawRect, nullptr);
206+
207+
auto coverOp = GrFillRectOp::Make(rtc->surfPriv().getContext(), std::move(paint),
208+
GrAAType::kMSAA, &drawQuad, stencil, fillRectFlags);
209+
rtc->addDrawOp(GrNoClip(), std::move(coverOp));
188210

189211
if (rtc->asSurfaceProxy()->requiresManualMSAAResolve()) {
190212
onFlushRP->addTextureResolveTask(sk_ref_sp(rtc->asTextureProxy()),

src/gpu/tessellate/GrTessellatePathOp.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ void GrTessellatePathOp::onPrepare(GrOpFlushState* state) {
8484
}
8585

8686
// Fastest CPU approach: emit one cubic wedge per verb, fanning out from the center.
87-
8887
if ((fPathVertexCount = GrPathParser::EmitCenterWedgePatches(fPath, &pathVertexAllocator))) {
8988
fStencilPathShader = state->allocator()->make<GrStencilWedgeShader>(fViewMatrix);
9089
}

0 commit comments

Comments
 (0)