Switch over GrDiscardOp to IORef-ing the GrRenderTargetProxy
authorRobert Phillips <robertphillips@google.com>
Thu, 18 May 2017 16:17:35 +0000 (12:17 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 18 May 2017 16:56:30 +0000 (16:56 +0000)
This cannot land until after https://skia-review.googlesource.com/c/14186/ (Split up opLists (take 3)) sticks.

This is because, prior to that CL, the SurfaceProxies have a ref on the last OpList that wrote to them. Since this CL adds a IORef from a discardOp in an opList to the SurfaceProxy this can result in a loop. After the required CL sticks, opLists have a IORef on the SurfaceProxy to which they wrote and the SurfaceProxy just has a raw back pointer so there will be no loop.

Change-Id: I198035f5dd5a8fad549052dea6aaa61477a89844
Reviewed-on: https://skia-review.googlesource.com/16663
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
src/gpu/GrRenderTargetContext.cpp
src/gpu/ops/GrDiscardOp.h

index ffcd480..d144389 100644 (file)
@@ -194,7 +194,7 @@ void GrRenderTargetContext::discard() {
     // Currently this just inserts a discard op. However, once in MDB this can remove all the
     // previously recorded ops and change the load op to discard.
     if (this->caps()->discardRenderTargetSupport()) {
-        std::unique_ptr<GrOp> op(GrDiscardOp::Make(this));
+        std::unique_ptr<GrOp> op(GrDiscardOp::Make(fRenderTargetProxy.get()));
         if (!op) {
             return;
         }
index dd5c4ef..4ae9783 100644 (file)
@@ -8,28 +8,17 @@
 #ifndef GrDiscardOp_DEFINED
 #define GrDiscardOp_DEFINED
 
-#include "GrGpu.h"
 #include "GrOp.h"
 #include "GrOpFlushState.h"
 #include "GrRenderTarget.h"
-#include "GrRenderTargetContext.h"
+#include "GrRenderTargetProxy.h"
 
 class GrDiscardOp final : public GrOp {
 public:
     DEFINE_OP_CLASS_ID
 
-    // MDB TODO: replace the renderTargetContext with just the renderTargetProxy.
-    // For now, we need the renderTargetContext for its accessRenderTarget powers.
-    static std::unique_ptr<GrOp> Make(GrRenderTargetContext* rtc) {
-
-        // MDB TODO: remove this. In this hybrid state we need to be sure the RT is instantiable
-        // so it can carry the IO refs. In the future we will just get the proxy and
-        // it carry the IO refs.
-        if (!rtc->accessRenderTarget()) {
-            return nullptr;
-        }
-
-        return std::unique_ptr<GrOp>(new GrDiscardOp(rtc));
+    static std::unique_ptr<GrOp> Make(GrRenderTargetProxy* proxy) {
+        return std::unique_ptr<GrOp>(new GrDiscardOp(proxy));
     }
 
     const char* name() const override { return "Discard"; }
@@ -37,35 +26,33 @@ public:
     SkString dumpInfo() const override {
         SkString string;
         string.append(INHERITED::dumpInfo());
-        string.printf("rtID: %d proxyID: %d\n", fRenderTarget.get()->uniqueID().asUInt(),
-                                                fProxyUniqueID.asUInt());
+        string.printf("proxyID: %d\n", fRenderTargetProxy.get()->uniqueID().asUInt());
         return string;
     }
 
 private:
-    GrDiscardOp(GrRenderTargetContext* rtc)
+    GrDiscardOp(GrRenderTargetProxy* proxy)
         : INHERITED(ClassID())
-        , fProxyUniqueID(rtc->asSurfaceProxy()->uniqueID()) {
-        this->setBounds(SkRect::MakeIWH(rtc->width(), rtc->height()), HasAABloat::kNo,
-                        IsZeroArea::kNo);
-
-        fRenderTarget.reset(rtc->accessRenderTarget());
+        , fRenderTargetProxy(proxy) {
+        this->setBounds(SkRect::MakeIWH(proxy->width(), proxy->height()),
+                        HasAABloat::kNo, IsZeroArea::kNo);
     }
 
-    bool onCombineIfPossible(GrOp* that, const GrCaps& caps) override {
-        return fRenderTarget.get() == that->cast<GrDiscardOp>()->fRenderTarget.get();
-    }
+    bool onCombineIfPossible(GrOp* that, const GrCaps& caps) override { return false; }
 
     void onPrepare(GrOpFlushState*) override {}
 
     void onExecute(GrOpFlushState* state) override {
-        // MDB TODO: instantiate the renderTarget from the proxy in here
-        state->commandBuffer()->discard(fRenderTarget.get());
+        GrRenderTarget* rt = fRenderTargetProxy.get()->instantiateRenderTarget(
+                                                                    state->resourceProvider());
+        if (!rt) {
+            return;
+        }
+
+        state->commandBuffer()->discard(rt);
     }
 
-    // MDB TODO: remove this. When the renderTargetProxy carries the refs this will be redundant.
-    GrSurfaceProxy::UniqueID                             fProxyUniqueID;
-    GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
+    GrPendingIOResource<GrRenderTargetProxy, kWrite_GrIOType> fRenderTargetProxy;
 
     typedef GrOp INHERITED;
 };