Handle color and stencil clears in GrClearOp
With prior changes, it became "clear" that GrClearOp and GrClearStencilClipOp behaved very similarly, except that the stencil op did not have any onCombine logic. This just combines them in to a single clear op that will call the render pass's clear and stencil clear functions as needed. I also implemented combine logic to apply color and stencil clears in a single op if the scissor state was compatible (although there's no render pass API to combine the two clears into a single GPU function). Change-Id: I8aa749fe64cc487d187854fd0acf6b03b86f1356 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290822 Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
parent
be20205787
commit
9cced93b7a
@ -368,8 +368,6 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/ops/GrAtlasTextOp.h",
|
||||
"$_src/gpu/ops/GrClearOp.cpp",
|
||||
"$_src/gpu/ops/GrClearOp.h",
|
||||
"$_src/gpu/ops/GrClearStencilClipOp.cpp",
|
||||
"$_src/gpu/ops/GrClearStencilClipOp.h",
|
||||
"$_src/gpu/ops/GrDashLinePathRenderer.cpp",
|
||||
"$_src/gpu/ops/GrDashLinePathRenderer.h",
|
||||
"$_src/gpu/ops/GrDashOp.cpp",
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include "src/gpu/geometry/GrStyledShape.h"
|
||||
#include "src/gpu/ops/GrAtlasTextOp.h"
|
||||
#include "src/gpu/ops/GrClearOp.h"
|
||||
#include "src/gpu/ops/GrClearStencilClipOp.h"
|
||||
#include "src/gpu/ops/GrDrawAtlasOp.h"
|
||||
#include "src/gpu/ops/GrDrawOp.h"
|
||||
#include "src/gpu/ops/GrDrawVerticesOp.h"
|
||||
@ -553,7 +552,7 @@ void GrRenderTargetContext::internalClear(const SkIRect* scissor,
|
||||
GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
|
||||
SkRect::Make(scissorState.rect())));
|
||||
} else {
|
||||
this->addOp(GrClearOp::Make(fContext, scissorState, color));
|
||||
this->addOp(GrClearOp::MakeColor(fContext, scissorState, color));
|
||||
}
|
||||
}
|
||||
|
||||
@ -959,7 +958,7 @@ void GrRenderTargetContext::internalStencilClear(const SkIRect* scissor, bool in
|
||||
GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
|
||||
SkRect::Make(scissorState.rect()), ss));
|
||||
} else {
|
||||
this->addOp(GrClearStencilClipOp::Make(fContext, scissorState, insideStencilMask));
|
||||
this->addOp(GrClearOp::MakeStencilClip(fContext, scissorState, insideStencilMask));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,21 +14,74 @@
|
||||
#include "src/gpu/GrProxyProvider.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
|
||||
std::unique_ptr<GrClearOp> GrClearOp::Make(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
const SkPMColor4f& color) {
|
||||
GrOpMemoryPool* pool = context->priv().opMemoryPool();
|
||||
return pool->allocate<GrClearOp>(scissor, color);
|
||||
static bool contains_scissor(const GrScissorState& a, const GrScissorState& b) {
|
||||
return !a.enabled() || (b.enabled() && a.rect().contains(b.rect()));
|
||||
}
|
||||
|
||||
GrClearOp::GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color)
|
||||
std::unique_ptr<GrClearOp> GrClearOp::MakeColor(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
const SkPMColor4f& color) {
|
||||
GrOpMemoryPool* pool = context->priv().opMemoryPool();
|
||||
return pool->allocate<GrClearOp>(Buffer::kColor, scissor, color, false);
|
||||
}
|
||||
|
||||
std::unique_ptr<GrClearOp> GrClearOp::MakeStencilClip(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
bool insideMask) {
|
||||
GrOpMemoryPool* pool = context->priv().opMemoryPool();
|
||||
return pool->allocate<GrClearOp>(Buffer::kStencilClip, scissor, SkPMColor4f(), insideMask);
|
||||
}
|
||||
|
||||
GrClearOp::GrClearOp(Buffer buffer, const GrScissorState& scissor,
|
||||
const SkPMColor4f& color, bool insideMask)
|
||||
: INHERITED(ClassID())
|
||||
, fScissor(scissor)
|
||||
, fColor(color) {
|
||||
, fColor(color)
|
||||
, fStencilInsideMask(insideMask)
|
||||
, fBuffer(buffer) {
|
||||
this->setBounds(SkRect::Make(scissor.rect()), HasAABloat::kNo, IsHairline::kNo);
|
||||
}
|
||||
|
||||
GrOp::CombineResult GrClearOp::onCombineIfPossible(GrOp* t, GrRecordingContext::Arenas*,
|
||||
const GrCaps& caps) {
|
||||
GrClearOp* other = t->cast<GrClearOp>();
|
||||
|
||||
if (other->fBuffer == fBuffer) {
|
||||
// This could be much more complicated. Currently we look at cases where the new clear
|
||||
// contains the old clear, or when the new clear is a subset of the old clear and they clear
|
||||
// to the same value (color or stencil mask depending on target).
|
||||
if (contains_scissor(other->fScissor, fScissor)) {
|
||||
fScissor = other->fScissor;
|
||||
fColor = other->fColor;
|
||||
fStencilInsideMask = other->fStencilInsideMask;
|
||||
return CombineResult::kMerged;
|
||||
} else if (other->fColor == fColor && other->fStencilInsideMask == fStencilInsideMask &&
|
||||
contains_scissor(fScissor, other->fScissor)) {
|
||||
return CombineResult::kMerged;
|
||||
}
|
||||
} else if (other->fScissor == fScissor) {
|
||||
// When the scissors are the exact same but the buffers are different, we can combine and
|
||||
// clear both stencil and clear together in onExecute().
|
||||
if (other->fBuffer & Buffer::kColor) {
|
||||
SkASSERT((fBuffer & Buffer::kStencilClip) && !(fBuffer & Buffer::kColor));
|
||||
fColor = other->fColor;
|
||||
}
|
||||
if (other->fBuffer & Buffer::kStencilClip) {
|
||||
SkASSERT(!(fBuffer & Buffer::kStencilClip) && (fBuffer & Buffer::kColor));
|
||||
fStencilInsideMask = other->fStencilInsideMask;
|
||||
}
|
||||
fBuffer = Buffer::kBoth;
|
||||
}
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
|
||||
void GrClearOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
|
||||
SkASSERT(state->opsRenderPass());
|
||||
state->opsRenderPass()->clear(fScissor, fColor);
|
||||
if (fBuffer & Buffer::kColor) {
|
||||
state->opsRenderPass()->clear(fScissor, fColor);
|
||||
}
|
||||
|
||||
if (fBuffer & Buffer::kStencilClip) {
|
||||
state->opsRenderPass()->clearStencilClip(fScissor, fStencilInsideMask);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef GrClearOp_DEFINED
|
||||
#define GrClearOp_DEFINED
|
||||
|
||||
#include "include/gpu/GrTypes.h"
|
||||
#include "src/gpu/GrScissorState.h"
|
||||
#include "src/gpu/ops/GrOp.h"
|
||||
|
||||
@ -19,9 +20,13 @@ public:
|
||||
DEFINE_OP_CLASS_ID
|
||||
|
||||
// A fullscreen or scissored clear, depending on the clip and proxy dimensions
|
||||
static std::unique_ptr<GrClearOp> Make(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
const SkPMColor4f& color);
|
||||
static std::unique_ptr<GrClearOp> MakeColor(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
const SkPMColor4f& color);
|
||||
|
||||
static std::unique_ptr<GrClearOp> MakeStencilClip(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
bool insideMask);
|
||||
|
||||
const char* name() const override { return "Clear"; }
|
||||
|
||||
@ -44,33 +49,20 @@ public:
|
||||
private:
|
||||
friend class GrOpMemoryPool; // for ctors
|
||||
|
||||
GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color);
|
||||
enum class Buffer {
|
||||
kColor = 0b01,
|
||||
kStencilClip = 0b10,
|
||||
|
||||
kBoth = 0b11,
|
||||
};
|
||||
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Buffer);
|
||||
|
||||
GrClearOp(Buffer buffer, const GrScissorState& scissor, const SkPMColor4f& color, bool stencil);
|
||||
|
||||
CombineResult onCombineIfPossible(GrOp* t, GrRecordingContext::Arenas*,
|
||||
const GrCaps& caps) override {
|
||||
// This could be much more complicated. Currently we look at cases where the new clear
|
||||
// contains the old clear, or when the new clear is a subset of the old clear and is the
|
||||
// same color.
|
||||
GrClearOp* cb = t->cast<GrClearOp>();
|
||||
if (cb->contains(this)) {
|
||||
fScissor = cb->fScissor;
|
||||
fColor = cb->fColor;
|
||||
return CombineResult::kMerged;
|
||||
} else if (cb->fColor == fColor && this->contains(cb)) {
|
||||
return CombineResult::kMerged;
|
||||
}
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
const GrCaps& caps) override;
|
||||
|
||||
bool contains(const GrClearOp* that) const {
|
||||
// The constructor ensures that scissor gets disabled on any clip that fills the entire RT.
|
||||
return !fScissor.enabled() ||
|
||||
(that->fScissor.enabled() && fScissor.rect().contains(that->fScissor.rect()));
|
||||
}
|
||||
|
||||
void onPrePrepare(GrRecordingContext*,
|
||||
const GrSurfaceProxyView* writeView,
|
||||
GrAppliedClip*,
|
||||
void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView* writeView, GrAppliedClip*,
|
||||
const GrXferProcessor::DstProxyView&) override {}
|
||||
|
||||
void onPrepare(GrOpFlushState*) override {}
|
||||
@ -79,8 +71,12 @@ private:
|
||||
|
||||
GrScissorState fScissor;
|
||||
SkPMColor4f fColor;
|
||||
bool fStencilInsideMask;
|
||||
Buffer fBuffer;
|
||||
|
||||
typedef GrOp INHERITED;
|
||||
};
|
||||
|
||||
GR_MAKE_BITFIELD_CLASS_OPS(GrClearOp::Buffer)
|
||||
|
||||
#endif
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/gpu/ops/GrClearStencilClipOp.h"
|
||||
|
||||
#include "include/private/GrRecordingContext.h"
|
||||
#include "src/gpu/GrMemoryPool.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrOpsRenderPass.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
|
||||
std::unique_ptr<GrOp> GrClearStencilClipOp::Make(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
bool insideStencilMask) {
|
||||
GrOpMemoryPool* pool = context->priv().opMemoryPool();
|
||||
|
||||
return pool->allocate<GrClearStencilClipOp>(scissor, insideStencilMask);
|
||||
}
|
||||
|
||||
void GrClearStencilClipOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
|
||||
SkASSERT(state->opsRenderPass());
|
||||
state->opsRenderPass()->clearStencilClip(fScissor, fInsideStencilMask);
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrClearStencilClipOp_DEFINED
|
||||
#define GrClearStencilClipOp_DEFINED
|
||||
|
||||
#include "src/gpu/GrRenderTargetProxy.h"
|
||||
#include "src/gpu/GrScissorState.h"
|
||||
#include "src/gpu/ops/GrOp.h"
|
||||
|
||||
class GrOpFlushState;
|
||||
class GrRecordingContext;
|
||||
|
||||
class GrClearStencilClipOp final : public GrOp {
|
||||
public:
|
||||
DEFINE_OP_CLASS_ID
|
||||
|
||||
static std::unique_ptr<GrOp> Make(GrRecordingContext* context,
|
||||
const GrScissorState& scissor,
|
||||
bool insideStencilMask);
|
||||
|
||||
const char* name() const override { return "ClearStencilClip"; }
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
SkString dumpInfo() const override {
|
||||
SkString string("Scissor [");
|
||||
if (fScissor.enabled()) {
|
||||
const SkIRect& r = fScissor.rect();
|
||||
string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
} else {
|
||||
string.append("disabled");
|
||||
}
|
||||
string.appendf("], insideMask: %s\n", fInsideStencilMask ? "true" : "false");
|
||||
string.append(INHERITED::dumpInfo());
|
||||
return string;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class GrOpMemoryPool; // for ctor
|
||||
|
||||
GrClearStencilClipOp(const GrScissorState& scissor, bool insideStencilMask)
|
||||
: INHERITED(ClassID())
|
||||
, fScissor(scissor)
|
||||
, fInsideStencilMask(insideStencilMask) {
|
||||
this->setBounds(SkRect::Make(scissor.rect()), HasAABloat::kNo, IsHairline::kNo);
|
||||
}
|
||||
|
||||
void onPrePrepare(GrRecordingContext*,
|
||||
const GrSurfaceProxyView* writeView,
|
||||
GrAppliedClip*,
|
||||
const GrXferProcessor::DstProxyView&) override {}
|
||||
|
||||
void onPrepare(GrOpFlushState*) override {}
|
||||
|
||||
void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
|
||||
|
||||
const GrScissorState fScissor;
|
||||
const bool fInsideStencilMask;
|
||||
|
||||
typedef GrOp INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user