Revert "Simplify GrRTC::clean APIs"
This reverts commit 6cbd7c2e57af9c499f7e99feb215b890fdd3a10a.
Reason for revert: mac/generated files failures
Original change's description:
> Simplify GrRTC::clean APIs
>
> The CanClearFullscreen enum type is removed. Most usages of clear() had
> kYes because a null scissor rect was provided, or had kNo because the
> scissor was really critical to the behavior. A few places did provide a
> scissor and kYes (e.g. for initializing the target).
>
> To simplify this, the public GrRTC has two variants of clear(). One with
> only a color (for fullscreen clears), and one with a rect for partial
> clears. The private API also adds a clearAtLeast() function that replaces
> the several cases where we'd have a scissor but could expand to fullscreen.
>
> I find the current control flow in internalClear() to be hard to
> follow (albeit I was the one to make it that way...), but later CLs
> will improve it.
>
> Bug: skia:10205
> Change-Id: I87cf8d688c58fbe58ee854fbc4ffe22482d969c6
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290256
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
TBR=bsalomon@google.com,csmartdalton@google.com,michaelludwig@google.com
Change-Id: I7131df6f5323f4f9c120cbcfd9bc57e627e2eb65
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:10205
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291842
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index f1b86ca..898dcd6 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -191,7 +191,8 @@
auto clear = [&](SkIRect rect) {
// Transform rect into the render target's coord system.
rect.offset(-rtcToSrcOffset);
- dstRenderTargetContext->priv().clearAtLeast(rect, SK_PMColor4fTRANSPARENT);
+ dstRenderTargetContext->clear(&rect, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
};
if (!top.isEmpty()) {
diff --git a/src/core/SkLegacyGpuBlurUtils.cpp b/src/core/SkLegacyGpuBlurUtils.cpp
index 8be824a..66a14d7 100644
--- a/src/core/SkLegacyGpuBlurUtils.cpp
+++ b/src/core/SkLegacyGpuBlurUtils.cpp
@@ -242,11 +242,13 @@
contentRect->offset(-rtcToSrcOffset);
if (!top.isEmpty()) {
- dstRenderTargetContext->priv().clearAtLeast(top, SK_PMColor4fTRANSPARENT);
+ dstRenderTargetContext->clear(&top, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
}
if (!bottom.isEmpty()) {
- dstRenderTargetContext->priv().clearAtLeast(bottom, SK_PMColor4fTRANSPARENT);
+ dstRenderTargetContext->clear(&bottom, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
}
if (mid.isEmpty()) {
diff --git a/src/effects/imagefilters/SkAlphaThresholdFilter.cpp b/src/effects/imagefilters/SkAlphaThresholdFilter.cpp
index c0f571d..2080c5c 100644
--- a/src/effects/imagefilters/SkAlphaThresholdFilter.cpp
+++ b/src/effects/imagefilters/SkAlphaThresholdFilter.cpp
@@ -110,7 +110,8 @@
}
SkRegion::Iterator iter(fRegion);
- rtContext->clear(SK_PMColor4fTRANSPARENT);
+ rtContext->clear(nullptr, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
GrFixedClip clip(SkIRect::MakeWH(bounds.width(), bounds.height()));
while (!iter.done()) {
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index 7f3f4c8..6e02413 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -589,7 +589,7 @@
dstRect.width(), radius.fHeight);
SkPMColor4f clearColor = MorphType::kErode == morphType
? SK_PMColor4fWHITE : SK_PMColor4fTRANSPARENT;
- dstRTContext->clear(clearRect, clearColor);
+ dstRTContext->clear(&clearRect, clearColor, GrRenderTargetContext::CanClearFullscreen::kNo);
srcView = dstRTContext->readSurfaceView();
srcAlphaType = dstRTContext->colorInfo().alphaType();
diff --git a/src/gpu/GrDynamicAtlas.cpp b/src/gpu/GrDynamicAtlas.cpp
index 2bc309b..881d439 100644
--- a/src/gpu/GrDynamicAtlas.cpp
+++ b/src/gpu/GrDynamicAtlas.cpp
@@ -13,7 +13,7 @@
#include "src/gpu/GrRectanizerPow2.h"
#include "src/gpu/GrRectanizerSkyline.h"
#include "src/gpu/GrRenderTarget.h"
-#include "src/gpu/GrRenderTargetContextPriv.h"
+#include "src/gpu/GrRenderTargetContext.h"
// Each Node covers a sub-rectangle of the final atlas. When a GrDynamicAtlas runs out of room, we
// create a new Node the same size as all combined nodes in the atlas as-is, and then place the new
@@ -199,6 +199,7 @@
}
SkIRect clearRect = SkIRect::MakeSize(fDrawBounds);
- rtc->priv().clearAtLeast(clearRect, SK_PMColor4fTRANSPARENT);
+ rtc->clear(&clearRect, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
return rtc;
}
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index b25098e..469b7f9 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -753,15 +753,7 @@
// clear the part that we care about.
SkPMColor4f initialCoverage =
InitialState::kAllIn == this->initialState() ? SK_PMColor4fWHITE : SK_PMColor4fTRANSPARENT;
- if (clip.hasWindowRectangles()) {
- GrPaint paint;
- paint.setColor4f(initialCoverage);
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- rtc->drawRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::Make(clip.scissorRect()));
- } else {
- rtc->priv().clearAtLeast(clip.scissorRect(), initialCoverage);
- }
+ rtc->priv().clear(clip, initialCoverage, GrRenderTargetContext::CanClearFullscreen::kYes);
// Set the matrix so that rendered clip elements are transformed to mask space from clip space.
SkMatrix translate;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 4dea63b..be418f6 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -479,6 +479,32 @@
this->getOpsTask()->discard();
}
+void GrRenderTargetContext::clear(const SkIRect* rect,
+ const SkPMColor4f& color,
+ CanClearFullscreen canClearFullscreen) {
+ ASSERT_SINGLE_OWNER
+ RETURN_IF_ABANDONED
+ SkDEBUGCODE(this->validate();)
+ GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "clear", fContext);
+
+ AutoCheckFlush acf(this->drawingManager());
+ this->internalClear(rect ? GrFixedClip(*rect) : GrFixedClip::Disabled(), color,
+ canClearFullscreen);
+}
+
+void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
+ const SkPMColor4f& color,
+ CanClearFullscreen canClearFullscreen) {
+ ASSERT_SINGLE_OWNER_PRIV
+ RETURN_IF_ABANDONED_PRIV
+ SkDEBUGCODE(fRenderTargetContext->validate();)
+ GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "clear",
+ fRenderTargetContext->fContext);
+
+ AutoCheckFlush acf(fRenderTargetContext->drawingManager());
+ fRenderTargetContext->internalClear(clip, color, canClearFullscreen);
+}
+
static void clear_to_grpaint(const SkPMColor4f& color, GrPaint* paint) {
paint->setColor4f(color);
if (color.isOpaque()) {
@@ -491,39 +517,19 @@
}
}
-// NOTE: We currently pass the premul color unmodified to the gpu, since we assume the GrRTC has a
-// premul alpha type. If we ever support different alpha type render targets, this function should
-// transform the color as appropriate.
-void GrRenderTargetContext::internalClear(const SkIRect* scissor,
+void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
const SkPMColor4f& color,
- bool upgradePartialToFull) {
- ASSERT_SINGLE_OWNER
- RETURN_IF_ABANDONED
- SkDEBUGCODE(this->validate();)
- GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "clear", fContext);
-
- // The clear will be fullscreen if no scissor is provided, or if the scissor is larger than
- // the logical bounds of the render target, or if the special flag was provided that allows
- // partial clears to upgrade to full (because it's a scratch resource and the caller knows
- // anything outside the scissor doesn't matter, but if full screen clears aren't free, then
- // the scissor is still provided so that fewer pixels are written to).
- // TODO: wrt the shouldInitializeTextures path, it would be more performant to
- // only clear the entire target if we knew it had not been cleared before. As
- // is this could end up doing a lot of redundant clears.
- GrScissorState scissorState;
- if (scissor) {
- // TODO(michaelludwig) - This will get simpler when GrScissorState knows the device dims
- scissorState.set(*scissor);
- if (!scissorState.intersect(SkIRect::MakeWH(this->width(), this->height()))) {
- // The clear is offscreen, so skip it (normally this would be handled by addDrawOp,
- // except clear ops are not draw ops).
- return;
- }
+ CanClearFullscreen canClearFullscreen) {
+ bool isFull = false;
+ if (!clip.hasWindowRectangles()) {
+ // TODO: wrt the shouldInitializeTextures path, it would be more performant to
+ // only clear the entire target if we knew it had not been cleared before. As
+ // is this could end up doing a lot of redundant clears.
+ isFull = !clip.scissorEnabled() ||
+ (CanClearFullscreen::kYes == canClearFullscreen &&
+ (this->caps()->preferFullscreenClears() || this->caps()->shouldInitializeTextures())) ||
+ clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
}
- bool isFull = !scissorState.enabled() ||
- scissorState.rect().contains(SkIRect::MakeWH(this->width(), this->height())) ||
- (upgradePartialToFull && (this->caps()->preferFullscreenClears() ||
- this->caps()->shouldInitializeTextures()));
if (isFull) {
GrOpsTask* opsTask = this->getOpsTask();
@@ -548,19 +554,20 @@
GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
rtRect));
} else {
- this->addOp(GrClearOp::Make(fContext, GrScissorState(), color, this->asSurfaceProxy()));
+ this->addOp(GrClearOp::Make(
+ fContext, SkIRect::MakeEmpty(), color, /* fullscreen */ true));
}
} else {
- if (this->caps()->performPartialClearsAsDraws()) {
+ if (this->caps()->performPartialClearsAsDraws() || clip.hasWindowRectangles()) {
// performPartialClearsAsDraws() also returns true if any clear has to be a draw.
GrPaint paint;
clear_to_grpaint(color, &paint);
- this->addDrawOp(GrFixedClip::Disabled(),
+ this->addDrawOp(clip,
GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
- SkRect::Make(scissorState.rect())));
+ SkRect::Make(clip.scissorRect())));
} else {
- std::unique_ptr<GrOp> op(GrClearOp::Make(fContext, scissorState, color,
+ std::unique_ptr<GrOp> op(GrClearOp::Make(fContext, clip.scissorState(), color,
this->asSurfaceProxy()));
// This version of the clear op factory can return null if the clip doesn't intersect
// with the surface proxy's boundary
@@ -710,14 +717,14 @@
drawBounds = quad->fDevice.bounds();
if (drawBounds.contains(rtRect)) {
// Fullscreen clear
- this->clear(*constColor);
+ this->clear(nullptr, *constColor, CanClearFullscreen::kYes);
return QuadOptimization::kSubmitted;
} else if (GrClip::IsPixelAligned(drawBounds) &&
drawBounds.width() > 256 && drawBounds.height() > 256) {
// Scissor + clear (round shouldn't do anything since we are pixel aligned)
SkIRect scissorRect;
drawBounds.round(&scissorRect);
- this->clear(scissorRect, *constColor);
+ this->clear(&scissorRect, *constColor, CanClearFullscreen::kNo);
return QuadOptimization::kSubmitted;
}
}
@@ -949,7 +956,7 @@
if (this->caps()->performStencilClearsAsDraws()) {
// There is a driver bug with clearing stencil. We must use an op to manually clear the
// stencil buffer before the op that required 'setNeedsStencil'.
- this->internalStencilClear(nullptr, /* inside mask */ false);
+ this->internalStencilClear(GrFixedClip::Disabled(), /* inside mask */ false);
} else {
this->getOpsTask()->setInitialStencilContent(
GrOpsTask::StencilContent::kUserBitsCleared);
@@ -957,30 +964,38 @@
}
}
-void GrRenderTargetContext::internalStencilClear(const SkIRect* scissor, bool insideStencilMask) {
+void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
+ ASSERT_SINGLE_OWNER_PRIV
+ RETURN_IF_ABANDONED_PRIV
+ SkDEBUGCODE(fRenderTargetContext->validate();)
+ GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "clearStencilClip",
+ fRenderTargetContext->fContext);
+
+ AutoCheckFlush acf(fRenderTargetContext->drawingManager());
+
+ fRenderTargetContext->internalStencilClear(clip, insideStencilMask);
+}
+
+void GrRenderTargetContext::internalStencilClear(const GrFixedClip& clip, bool insideStencilMask) {
this->setNeedsStencil(/* useMixedSamplesIfNotMSAA = */ false);
bool clearWithDraw = this->caps()->performStencilClearsAsDraws() ||
- (scissor && this->caps()->performPartialClearsAsDraws());
- if (clearWithDraw) {
+ (clip.scissorEnabled() && this->caps()->performPartialClearsAsDraws());
+ // TODO(michaelludwig): internalStencilClear will eventually just take a GrScissorState so
+ // we won't need to check window rectangles here.
+ if (clearWithDraw || clip.hasWindowRectangles()) {
const GrUserStencilSettings* ss = GrStencilSettings::SetClipBitSettings(insideStencilMask);
- SkRect rect = scissor ? SkRect::Make(*scissor)
- : SkRect::MakeWH(this->width(), this->height());
+ SkRect rect = clip.scissorEnabled() ? SkRect::Make(clip.scissorRect())
+ : SkRect::MakeWH(this->width(), this->height());
// Configure the paint to have no impact on the color buffer
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
- this->addDrawOp(GrFixedClip::Disabled(),
- GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
- rect, ss));
+ this->addDrawOp(clip, GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
+ rect, ss));
} else {
- GrScissorState scissorState;
- if (scissor) {
- scissorState.set(*scissor);
- }
-
std::unique_ptr<GrOp> op(GrClearStencilClipOp::Make(
- fContext, scissorState, insideStencilMask, this->asRenderTargetProxy()));
+ fContext, clip.scissorState(), insideStencilMask, this->asRenderTargetProxy()));
if (!op) {
return;
}
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index abf3b8c..ca0ac26 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -148,17 +148,22 @@
*/
void discard();
+ enum class CanClearFullscreen : bool {
+ kNo = false,
+ kYes = true
+ };
+
/**
- * Clear the rect of the render target to the given color.
- * @param rect the rect to clear to
+ * Clear the entire or rect of the render target, ignoring any clips.
+ * @param rect the rect to clear or the whole thing if rect is NULL.
* @param color the color to clear to.
+ * @param CanClearFullscreen allows partial clears to be converted to fullscreen clears on
+ * tiling platforms where that is an optimization.
*/
- void clear(const SkIRect& rect, const SkPMColor4f& color) {
- this->internalClear(&rect, color);
- }
- // Clears the entire render target to the color.
+ void clear(const SkIRect* rect, const SkPMColor4f& color, CanClearFullscreen);
+
void clear(const SkPMColor4f& color) {
- this->internalClear(nullptr, color);
+ return this->clear(nullptr, color, CanClearFullscreen::kYes);
}
/**
@@ -617,9 +622,8 @@
GrOpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const;
void setNeedsStencil(bool useMixedSamplesIfNotMSAA);
- void internalClear(const SkIRect* scissor, const SkPMColor4f&,
- bool upgradePartialToFull = false);
- void internalStencilClear(const SkIRect* scissor, bool insideStencilMask);
+ void internalClear(const GrFixedClip&, const SkPMColor4f&, CanClearFullscreen);
+ void internalStencilClear(const GrFixedClip&, bool insideStencilMask);
// Only consumes the GrPaint if successful.
bool drawFilledDRRect(const GrClip& clip,
diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h
index cad91f1..188d251 100644
--- a/src/gpu/GrRenderTargetContextPriv.h
+++ b/src/gpu/GrRenderTargetContextPriv.h
@@ -43,15 +43,11 @@
opsTask->fLastClipNumAnalyticFPs != numClipAnalyticFPs;
}
- // Clear at minimum the pixels within 'scissor', but is allowed to clear the full render target
- // if that is the more performant option.
- void clearAtLeast(const SkIRect& scissor, const SkPMColor4f& color) {
- fRenderTargetContext->internalClear(&scissor, color, /* upgrade to full */ true);
- }
+ using CanClearFullscreen = GrRenderTargetContext::CanClearFullscreen;
- void clearStencilClip(const SkIRect& scissor, bool insideStencilMask) {
- fRenderTargetContext->internalStencilClear(&scissor, insideStencilMask);
- }
+ void clear(const GrFixedClip&, const SkPMColor4f&, CanClearFullscreen);
+
+ void clearStencilClip(const GrFixedClip&, bool insideStencilMask);
// While this can take a general clip, since GrReducedClip relies on this function, it must take
// care to only provide hard clips or we could get stuck in a loop. The general clip is needed
diff --git a/src/gpu/GrStencilMaskHelper.cpp b/src/gpu/GrStencilMaskHelper.cpp
index 3adab6d..f9870f4 100644
--- a/src/gpu/GrStencilMaskHelper.cpp
+++ b/src/gpu/GrStencilMaskHelper.cpp
@@ -462,15 +462,7 @@
}
void GrStencilMaskHelper::clear(bool insideStencil) {
- if (fClip.fixedClip().hasWindowRectangles()) {
- // Use a draw to benefit from window rectangles when resetting the stencil buffer; for
- // large buffers with MSAA this can be significant.
- draw_stencil_rect(fRTC, fClip.fixedClip(),
- GrStencilSettings::SetClipBitSettings(insideStencil), SkMatrix::I(),
- SkRect::Make(fClip.fixedClip().scissorRect()), GrAA::kNo);
- } else {
- fRTC->priv().clearStencilClip(fClip.fixedClip().scissorRect(), insideStencil);
- }
+ fRTC->priv().clearStencilClip(fClip.fixedClip(), insideStencil);
}
void GrStencilMaskHelper::finish() {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 2e1d9e8..b316059 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -209,7 +209,8 @@
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "clearAll", fContext.get());
SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
- fRenderTargetContext->priv().clearAtLeast(rect, SK_PMColor4fTRANSPARENT);
+ fRenderTargetContext->clear(&rect, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
}
void SkGpuDevice::replaceRenderTargetContext(std::unique_ptr<GrRenderTargetContext> rtc,
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.h b/src/gpu/effects/generated/GrRRectBlurEffect.h
index e26a5c9..7c592c3 100644
--- a/src/gpu/effects/generated/GrRRectBlurEffect.h
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.h
@@ -66,7 +66,8 @@
GrPaint paint;
- rtc->clear(SK_PMColor4fTRANSPARENT);
+ rtc->clear(nullptr, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
rtc->drawRRect(GrNoClip(), std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
GrStyle::SimpleFill());
diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp
index 753f75d..dc1b939 100644
--- a/src/gpu/ops/GrClearOp.cpp
+++ b/src/gpu/ops/GrClearOp.cpp
@@ -17,22 +17,45 @@
std::unique_ptr<GrClearOp> GrClearOp::Make(GrRecordingContext* context,
const GrScissorState& scissor,
const SkPMColor4f& color,
- const GrSurfaceProxy* dstProxy) {
+ GrSurfaceProxy* dstProxy) {
const SkIRect rect = SkIRect::MakeSize(dstProxy->dimensions());
if (scissor.enabled() && !SkIRect::Intersects(scissor.rect(), rect)) {
return nullptr;
}
GrOpMemoryPool* pool = context->priv().opMemoryPool();
+
return pool->allocate<GrClearOp>(scissor, color, dstProxy);
}
-GrClearOp::GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color,
- const GrSurfaceProxy* proxy)
+std::unique_ptr<GrClearOp> GrClearOp::Make(GrRecordingContext* context,
+ const SkIRect& rect,
+ const SkPMColor4f& color,
+ bool fullScreen) {
+ SkASSERT(fullScreen || !rect.isEmpty());
+
+ GrOpMemoryPool* pool = context->priv().opMemoryPool();
+
+ return pool->allocate<GrClearOp>(rect, color, fullScreen);
+}
+
+GrClearOp::GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* proxy)
: INHERITED(ClassID())
, fScissor(scissor)
, fColor(color) {
- this->setBounds(scissor.enabled() ? SkRect::Make(scissor.rect()) : proxy->getBoundsRect(),
+ const SkIRect rtRect = SkIRect::MakeSize(proxy->dimensions());
+ if (fScissor.enabled()) {
+ // Don't let scissors extend outside the RT. This may improve op combining.
+ if (!fScissor.intersect(rtRect)) {
+ SkASSERT(0); // should be caught upstream
+ fScissor.set(SkIRect::MakeEmpty());
+ }
+
+ if (proxy->isFunctionallyExact() && fScissor.rect() == rtRect) {
+ fScissor.setDisabled();
+ }
+ }
+ this->setBounds(SkRect::Make(fScissor.enabled() ? fScissor.rect() : rtRect),
HasAABloat::kNo, IsHairline::kNo);
}
diff --git a/src/gpu/ops/GrClearOp.h b/src/gpu/ops/GrClearOp.h
index 770a7de..0857064 100644
--- a/src/gpu/ops/GrClearOp.h
+++ b/src/gpu/ops/GrClearOp.h
@@ -21,7 +21,12 @@
static std::unique_ptr<GrClearOp> Make(GrRecordingContext* context,
const GrScissorState& scissor,
const SkPMColor4f& color,
- const GrSurfaceProxy* dstProxy);
+ GrSurfaceProxy* dstProxy);
+
+ static std::unique_ptr<GrClearOp> Make(GrRecordingContext* context,
+ const SkIRect& rect,
+ const SkPMColor4f& color,
+ bool fullScreen);
const char* name() const override { return "Clear"; }
@@ -47,7 +52,18 @@
private:
friend class GrOpMemoryPool; // for ctors
- GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color, const GrSurfaceProxy* proxy);
+ GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* proxy);
+
+ GrClearOp(const SkIRect& rect, const SkPMColor4f& color, bool fullScreen)
+ : INHERITED(ClassID())
+ , fScissor(rect)
+ , fColor(color) {
+
+ if (fullScreen) {
+ fScissor.setDisabled();
+ }
+ this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsHairline::kNo);
+ }
CombineResult onCombineIfPossible(GrOp* t, GrRecordingContext::Arenas*,
const GrCaps& caps) override {