Track if we need stencil on GrRenderTargetContext
There are a few places that have been checking whether the *proxy*
needs stencil, in order to determine if the current render target
context needs stencil. This is problematic since a render target
context can not require stencil itself, but wrap an existing proxy
that already has stencil.
Bug: skia:
Change-Id: I2719dd3a9df15fef3d64f991cda4fadea23266bb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/223970
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 080893e..84eb13b 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -536,31 +536,25 @@
}
}
-void GrRenderTargetOpList::setStencilLoadOp(GrLoadOp op) {
- fStencilLoadOp = op;
-}
-
void GrRenderTargetOpList::setColorLoadOp(GrLoadOp op, const SkPMColor4f& color) {
fColorLoadOp = op;
fLoadClearColor = color;
}
-bool GrRenderTargetOpList::resetForFullscreenClear() {
+bool GrRenderTargetOpList::resetForFullscreenClear(CanDiscardPreviousOps canDiscardPreviousOps) {
// Mark the color load op as discard (this may be followed by a clearColorOnLoad call to make
// the load op kClear, or it may be followed by an explicit op). In the event of an absClear()
// after a regular clear(), we could end up with a clear load op and a real clear op in the list
// if the load op were not reset here.
fColorLoadOp = GrLoadOp::kDiscard;
- // Regardless of how the clear is implemented (native clear or a fullscreen quad), all prior ops
- // would be overwritten, so discard them entirely. The one exception is if the opList is marked
- // as needing a stencil buffer then there may be a prior op that writes to the stencil buffer.
- // Although the clear will ignore the stencil buffer, following draw ops may not so we can't get
- // rid of all the preceding ops. Beware! If we ever add any ops that have a side effect beyond
- // modifying the stencil buffer we will need a more elaborate tracking system (skbug.com/7002).
- // Additionally, if we previously recorded a wait op, we cannot delete the wait op. Until we
- // track the wait ops separately from normal ops, we have to avoid clearing out any ops.
- if (this->isEmpty() || (!fTarget->asRenderTargetProxy()->needsStencil() && !fHasWaitOp)) {
+ // If we previously recorded a wait op, we cannot delete the wait op. Until we track the wait
+ // ops separately from normal ops, we have to avoid clearing out any ops in this case as well.
+ if (fHasWaitOp) {
+ canDiscardPreviousOps = CanDiscardPreviousOps::kNo;
+ }
+
+ if (CanDiscardPreviousOps::kYes == canDiscardPreviousOps || this->isEmpty()) {
this->deleteOps();
fDeferredProxies.reset();