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();