Added GrSurfaceContext and GrTextureContext
authorBrian Osman <brianosman@google.com>
Wed, 23 Nov 2016 14:37:01 +0000 (09:37 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 23 Nov 2016 15:52:27 +0000 (15:52 +0000)
This lets copy-to-texture to be treated like copy-to-rt.
To match current behavior, though, copies to texture are
still executed immediately (forcing a flush).

Once MDB is enabled, copies to texture will be deferred.

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5093

Change-Id: Icc0ce5435507a5f0a237c22eedef879824952367
Reviewed-on: https://skia-review.googlesource.com/5093
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
20 files changed:
gn/gpu.gni
include/gpu/GrRenderTarget.h
include/gpu/GrRenderTargetContext.h
include/gpu/GrSurfaceContext.h [new file with mode: 0644]
include/gpu/GrTextureContext.h [new file with mode: 0644]
include/private/GrRenderTargetProxy.h
include/private/GrSurfaceProxy.h
include/private/GrTextureProxy.h
src/gpu/GrContext.cpp
src/gpu/GrContextPriv.h
src/gpu/GrDrawingManager.cpp
src/gpu/GrDrawingManager.h
src/gpu/GrOpList.h
src/gpu/GrRenderTargetContext.cpp
src/gpu/GrRenderTargetOpList.h
src/gpu/GrRenderTargetProxy.cpp
src/gpu/GrSurfaceContext.cpp [new file with mode: 0644]
src/gpu/GrSurfaceProxy.cpp
src/gpu/GrTextureContext.cpp [new file with mode: 0644]
src/gpu/GrTextureOpList.h

index a705ed6af287bde2828e8b14182d671f733a9772..1779f7f5b21526971acde05ebd2c57257aeb4f73 100644 (file)
@@ -31,7 +31,9 @@ skia_gpu_sources = [
   "$_include/gpu/GrResourceKey.h",
   "$_include/gpu/GrShaderVar.h",
   "$_include/gpu/GrSurface.h",
+  "$_include/gpu/GrSurfaceContext.h",
   "$_include/gpu/GrTexture.h",
+  "$_include/gpu/GrTextureContext.h",
   "$_include/gpu/GrSamplerParams.h",
   "$_include/gpu/GrTextureProvider.h",
   "$_include/gpu/GrTestUtils.h",
@@ -192,9 +194,11 @@ skia_gpu_sources = [
   "$_src/gpu/GrSoftwarePathRenderer.h",
   "$_src/gpu/GrSurfacePriv.h",
   "$_src/gpu/GrSurface.cpp",
+  "$_src/gpu/GrSurfaceContext.cpp",
   "$_src/gpu/GrSurfaceProxy.cpp",
   "$_src/gpu/GrSwizzle.h",
   "$_src/gpu/GrTexture.cpp",
+  "$_src/gpu/GrTextureContext.cpp",
   "$_src/gpu/GrTextureParamsAdjuster.h",
   "$_src/gpu/GrTextureParamsAdjuster.cpp",
   "$_src/gpu/GrTexturePriv.h",
index dcbe8ea974aa64d3c8269a1a2adfd42d740ba21a..2d4eaf74828bbccb5a6c80393e05c47e808af2c9 100644 (file)
@@ -115,10 +115,6 @@ public:
     GrRenderTargetPriv renderTargetPriv();
     const GrRenderTargetPriv renderTargetPriv() const;
 
-    GrRenderTargetOpList* getLastRenderTargetOpList() {
-        return (GrRenderTargetOpList*) this->getLastOpList();
-    }
-
 protected:
     enum class Flags {
         kNone                = 0,
index 6ed321c0f76308651ba41c2f9579aa647fa1c5a4..20ca59f45aaedc1ed964bf45b3b85f2debd27920 100644 (file)
 #include "GrColor.h"
 #include "GrContext.h"
 #include "GrPaint.h"
-#include "GrRenderTarget.h"
+#include "GrSurfaceContext.h"
 #include "SkRefCnt.h"
-#include "SkRegion.h"
 #include "SkSurfaceProps.h"
 #include "../private/GrInstancedPipelineInfo.h"
 #include "../private/GrRenderTargetProxy.h"
-#include "../private/GrSingleOwner.h"
 
-class GrAuditTrail;
 class GrClip;
 class GrDrawBatch;
-class GrRenderTargetContextPriv;
-class GrDrawPathBatchBase;
 class GrDrawingManager;
 class GrFixedClip;
-class GrPaint;
-class GrPathProcessor;
 class GrPipelineBuilder;
 class GrRenderTarget;
+class GrRenderTargetContextPriv;
 class GrRenderTargetOpList;
 class GrStyle;
 class GrSurface;
@@ -44,18 +38,19 @@ class SkPaint;
 class SkPath;
 struct SkPoint;
 struct SkRect;
+class SkRegion;
 class SkRRect;
 struct SkRSXform;
 class SkTextBlob;
 
-/*
- * A helper object to orchestrate draws
+/**
+ * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
  */
-class SK_API GrRenderTargetContext : public SkRefCnt {
+class SK_API GrRenderTargetContext : public GrSurfaceContext {
 public:
     ~GrRenderTargetContext() override;
 
-    bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
+    bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
 
     // TODO: it is odd that we need both the SkPaint in the following 3 methods.
     // We should extract the text parameters from SkPaint and pass them separately
@@ -385,8 +380,6 @@ public:
     GrRenderTargetContextPriv priv();
     const GrRenderTargetContextPriv priv() const;
 
-    GrAuditTrail* auditTrail() { return fAuditTrail; }
-
     bool isWrapped_ForTesting() const;
 
 protected:
@@ -396,7 +389,6 @@ protected:
 
     GrDrawingManager* drawingManager() { return fDrawingManager; }
 
-    SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
     SkDEBUGCODE(void validate() const;)
 
 private:
@@ -462,16 +454,11 @@ private:
     // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
     // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
     GrRenderTargetOpList*             fOpList;
-    GrContext*                        fContext;
     GrInstancedPipelineInfo           fInstancedPipelineInfo;
 
     sk_sp<SkColorSpace>               fColorSpace;
     sk_sp<GrColorSpaceXform>          fColorXformFromSRGB;
     SkSurfaceProps                    fSurfaceProps;
-    GrAuditTrail*                     fAuditTrail;
-
-    // In debug builds we guard against improper thread handling
-    SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
 };
 
 #endif
diff --git a/include/gpu/GrSurfaceContext.h b/include/gpu/GrSurfaceContext.h
new file mode 100644 (file)
index 0000000..a05d37f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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 GrSurfaceContext_DEFINED
+#define GrSurfaceContext_DEFINED
+
+#include "SkRefCnt.h"
+
+class GrAuditTrail;
+class GrContext;
+class GrSingleOwner;
+class GrSurface;
+struct SkIPoint;
+struct SkIRect;
+
+/**
+ * A helper object to orchestrate commands for a particular surface
+ */
+class SK_API GrSurfaceContext : public SkRefCnt {
+public:
+    ~GrSurfaceContext() override {}
+
+    virtual bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) = 0;
+
+    GrAuditTrail* auditTrail() { return fAuditTrail; }
+
+protected:
+    GrSurfaceContext(GrContext*, GrAuditTrail*, GrSingleOwner*);
+
+    SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
+
+    GrContext*            fContext;
+    GrAuditTrail*         fAuditTrail;
+
+    // In debug builds we guard against improper thread handling
+    SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
+};
+
+#endif
diff --git a/include/gpu/GrTextureContext.h b/include/gpu/GrTextureContext.h
new file mode 100644 (file)
index 0000000..da71c07
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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 GrTextureContext_DEFINED
+#define GrTextureContext_DEFINED
+
+#include "GrSurfaceContext.h"
+#include "../private/GrTextureProxy.h"
+
+class GrContext;
+class GrDrawingManager;
+class GrSurface;
+class GrTextureOpList;
+class GrTextureProxy;
+struct SkIPoint;
+struct SkIRect;
+
+/**
+ * A helper object to orchestrate commands (currently just copies) for GrSurfaces that are
+ * GrTextures and not GrRenderTargets.
+ */
+class SK_API GrTextureContext : public GrSurfaceContext {
+public:
+    ~GrTextureContext() override;
+
+    bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
+
+protected:
+    GrTextureContext(GrContext*, GrDrawingManager*, sk_sp<GrTextureProxy>, GrAuditTrail*,
+                     GrSingleOwner*);
+
+    GrDrawingManager* drawingManager() { return fDrawingManager; }
+
+    SkDEBUGCODE(void validate() const;)
+
+private:
+    friend class GrDrawingManager; // for ctor
+
+    GrTextureOpList* getOpList();
+
+    GrDrawingManager*            fDrawingManager;
+    sk_sp<GrTextureProxy>        fTextureProxy;
+
+    // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
+    // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
+    GrTextureOpList*             fOpList;
+};
+
+#endif
index bfc6e059739ff5d0f0fe4094ec18068ca5529ca7..83107daf6183ba7ff8cc9909995be518b9f17344 100644 (file)
@@ -53,12 +53,6 @@ public:
 
     GrRenderTarget::Flags testingOnly_getFlags() const;
 
-    GrRenderTargetOpList* getLastRenderTargetOpList() {
-        return (GrRenderTargetOpList*) this->getLastOpList();
-    }
-
-    SkDEBUGCODE(void validate(GrContext*) const;)
-
 protected:
     friend class GrSurfaceProxy;  // for ctors
 
index 1ff6df809d3de913c60b397391c7e475583947fc..61dc9e1fea4722a039de667b942c385bd457ccdc 100644 (file)
 #include "SkRect.h"
 
 class GrCaps;
-class GrOpList;
-class GrTextureProvider;
-class GrTextureProxy;
+class GrRenderTargetOpList;
 class GrRenderTargetProxy;
+class GrTextureOpList;
 class GrTextureProvider;
+class GrTextureProxy;
 
 // This class replicates the functionality GrIORef<GrSurface> but tracks the
 // utilitization for later resource allocation (for the deferred case) and
@@ -244,6 +244,9 @@ public:
     void setLastOpList(GrOpList* opList);
     GrOpList* getLastOpList() { return fLastOpList; }
 
+    GrRenderTargetOpList* getLastRenderTargetOpList();
+    GrTextureOpList* getLastTextureOpList();
+
     /**
      * Retrieves the amount of GPU memory that will be or currently is used by this resource 
      * in bytes. It is approximate since we aren't aware of additional padding or copies made
@@ -261,6 +264,8 @@ public:
 
     bool isWrapped_ForTesting() const;
 
+    SkDEBUGCODE(void validate(GrContext*) const;)
+
 protected:
     // Deferred version
     GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted)
index a206e76e37a4cafeac166e3d3d000cf0928197bb..5eb3066489bc97ffc1f74c467cea4947e2f211a2 100644 (file)
@@ -12,6 +12,7 @@
 #include "GrTexture.h"
 
 class GrCaps;
+class GrTextureOpList;
 class GrTextureProvider;
 
 // This class delays the acquisition of textures until they are actually required
index 1a5ee20721ef5bf09f48d7d5f55b75859c5d8745..7b789bd08dbcb9a49a4db9b0f3a5c3bd5baca034 100644 (file)
@@ -14,7 +14,9 @@
 #include "GrResourceProvider.h"
 #include "GrRenderTargetProxy.h"
 #include "GrSoftwarePathRenderer.h"
+#include "GrSurfaceContext.h"
 #include "GrSurfacePriv.h"
+#include "GrTextureContext.h"
 
 #include "SkConfig8888.h"
 #include "SkGrPriv.h"
@@ -557,31 +559,23 @@ bool GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
         return false;
     }
 
-    if (!dst->asRenderTarget()) {
-        SkIRect clippedSrcRect;
-        SkIPoint clippedDstPoint;
-        if (!GrCopySurfaceBatch::ClipSrcRectAndDstPoint(dst, src, srcRect, dstPoint,
-                                                        &clippedSrcRect, &clippedDstPoint)) {
-            return false;
-        }
-        // If we don't have an RT for the dst then we won't have a GrRenderTargetContext to insert
-        // the copy surface into. In the future we plan to have a more limited Context type
-        // (GrCopyContext?) that has the subset of GrRenderTargetContext operations that should be
-        // allowed on textures that aren't render targets.
-        // For now we just flush any writes to the src and issue an immediate copy to the dst.
-        src->flushWrites();
-        return fGpu->copySurface(dst, src, clippedSrcRect, clippedDstPoint);
-    }
-    sk_sp<GrRenderTargetContext> renderTargetContext(
-        this->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(dst->asRenderTarget()),
-                                                           nullptr));
-    if (!renderTargetContext) {
+#ifndef ENABLE_MDB
+    // We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
+    // execute the copy immediately. Ensure the data is ready.
+    src->flushWrites();
+#endif
+
+    sk_sp<GrSurfaceContext> surfaceContext(
+        this->contextPriv().makeWrappedSurfaceContext(sk_ref_sp(dst)));
+
+    if (!surfaceContext) {
         return false;
     }
 
-    if (!renderTargetContext->copySurface(src, srcRect, dstPoint)) {
+    if (!surfaceContext->copySurface(src, srcRect, dstPoint)) {
         return false;
     }
+
     return true;
 }
 
@@ -633,6 +627,19 @@ sk_sp<GrRenderTargetContext> GrContextPriv::makeWrappedRenderTargetContext(
                                                            surfaceProps);
 }
 
+sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface> surface) {
+    ASSERT_SINGLE_OWNER_PRIV
+
+    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface)));
+
+    if (proxy->asRenderTargetProxy()) {
+        return this->drawingManager()->makeRenderTargetContext(std::move(proxy), nullptr, nullptr);
+    } else {
+        SkASSERT(proxy->asTextureProxy());
+        return this->drawingManager()->makeTextureContext(std::move(proxy));
+    }
+}
+
 sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
                                                                    const GrBackendTextureDesc& desc, 
                                                                    sk_sp<SkColorSpace> colorSpace,
index d2fa7c16104b338496d9cae9de7ae162c946f37b..dcf08075071b3906e591ad4ae8b8fe7f05223651 100644 (file)
@@ -9,6 +9,7 @@
 #define GrContextPriv_DEFINED
 
 #include "GrContext.h"
+#include "GrSurfaceContext.h"
 
 /** Class that adds methods to GrContext that are only intended for use internal to Skia.
     This class is purely a privileged window into GrContext. It should never have additional
@@ -22,6 +23,9 @@ public:
                                                                 sk_sp<SkColorSpace> colorSpace,
                                                                 const SkSurfaceProps* = nullptr);
 
+    // Create a surfaceContext that wraps an existing texture or renderTarget
+    sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurface> tex);
+
     sk_sp<GrRenderTargetContext> makeBackendTextureRenderTargetContext(
                                                          const GrBackendTextureDesc& desc,
                                                          sk_sp<SkColorSpace> colorSpace,
index 5267df3626aea173445bfb04402a7544a6e693dc..e1dff8b14f2a42ddc3d4b830a014d8bea8a58dca 100644 (file)
@@ -14,6 +14,8 @@
 #include "GrResourceProvider.h"
 #include "GrSoftwarePathRenderer.h"
 #include "GrSurfacePriv.h"
+#include "GrTextureContext.h"
+#include "GrTextureOpList.h"
 #include "SkSurface_Gpu.h"
 #include "SkTTopoSort.h"
 
@@ -172,6 +174,24 @@ GrRenderTargetOpList* GrDrawingManager::newOpList(GrRenderTargetProxy* rtp) {
     return SkRef(opList);
 }
 
+GrTextureOpList* GrDrawingManager::newOpList(GrTextureProxy* textureProxy) {
+    SkASSERT(fContext);
+
+    GrTextureOpList* opList = new GrTextureOpList(textureProxy, fContext->getGpu(),
+                                                  fContext->getAuditTrail());
+
+#ifndef ENABLE_MDB
+    // When MDB is disabled we still create a new GrOpList, but don't store or ref it - we rely
+    // on the caller to immediately execute and free it.
+    return opList;
+#else
+    *fOpLists.append() = opList;
+
+    // Drawing manager gets the creation ref - this ref is for the caller
+    return SkRef(opList);
+#endif
+}
+
 GrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
     if (!fAtlasTextContext) {
         fAtlasTextContext.reset(GrAtlasTextContext::Create());
@@ -253,3 +273,17 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
                                                                   fContext->getAuditTrail(),
                                                                   fSingleOwner));
 }
+
+sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy) {
+    if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
+        return nullptr;
+    }
+
+    // GrTextureRenderTargets should always be using GrRenderTargetContext
+    SkASSERT(!sProxy->asRenderTargetProxy());
+
+    sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
+
+    return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
+                                                        fContext->getAuditTrail(), fSingleOwner));
+}
index 3816868c7568ffe62d92bb99e15611448010970a..90a3064e24f8df50bb6b42ee6867d695abe18651 100644 (file)
@@ -22,6 +22,8 @@ class GrRenderTargetContext;
 class GrRenderTargetProxy;
 class GrSingleOWner;
 class GrSoftwarePathRenderer;
+class GrTextureContext;
+class GrTextureOpList;
 
 // The GrDrawingManager allocates a new GrRenderTargetContext for each GrRenderTarget
 // but all of them still land in the same GrOpList!
@@ -38,10 +40,12 @@ public:
     sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
                                                          sk_sp<SkColorSpace>,
                                                          const SkSurfaceProps*);
+    sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>);
 
     // The caller automatically gets a ref on the returned opList. It must
     // be balanced by an unref call.
     GrRenderTargetOpList* newOpList(GrRenderTargetProxy* rtp);
+    GrTextureOpList* newOpList(GrTextureProxy* textureProxy);
 
     GrContext* getContext() { return fContext; }
 
index 9c965f8f0fc1c13f3787b206dcbb7eef8a2022d0..313807d63c3cfd80079d9d223e93869322a78d21 100644 (file)
 
 class GrAuditTrail;
 class GrBatchFlushState;
+class GrRenderTargetOpList;
 class GrSurface;
 class GrSurfaceProxy;
+class GrTextureOpList;
 
 class GrOpList : public SkRefCnt {
 public:
@@ -61,6 +63,16 @@ public:
         return fDependencies.find(dependedOn) >= 0;
     }
 
+    /*
+     * Safely cast this GrOpList to a GrTextureOpList (if possible).
+     */
+    virtual GrTextureOpList* asTextureOpList() { return nullptr; }
+
+    /*
+     * Safely case this GrOpList to a GrRenderTargetOpList (if possible).
+     */
+    virtual GrRenderTargetOpList* asRenderTargetOpList() { return nullptr; }
+
     /*
      * Dump out the GrOpList dependency DAG
      */
index 6238fa8025199fe3e9d4bf94a46b6d12783c20d4..f08f39a1be450456b220c7dacdd7b3ef19c5cf9c 100644 (file)
@@ -81,18 +81,14 @@ GrRenderTargetContext::GrRenderTargetContext(GrContext* context,
                                              const SkSurfaceProps* surfaceProps,
                                              GrAuditTrail* auditTrail,
                                              GrSingleOwner* singleOwner)
-    : fDrawingManager(drawingMgr)
+    : GrSurfaceContext(context, auditTrail, singleOwner)
+    , fDrawingManager(drawingMgr)
     , fRenderTargetProxy(std::move(rtp))
     , fOpList(SkSafeRef(fRenderTargetProxy->getLastRenderTargetOpList()))
-    , fContext(context)
     , fInstancedPipelineInfo(fRenderTargetProxy.get())
     , fColorSpace(std::move(colorSpace))
     , fColorXformFromSRGB(nullptr)
     , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
-    , fAuditTrail(auditTrail)
-#ifdef SK_DEBUG
-    , fSingleOwner(singleOwner)
-#endif
 {
     if (fColorSpace) {
         // sRGB sources are very common (SkColor, etc...), so we cache that gamut transformation
index b084d482913c90d42fe8bf5ad95d1ee45e32d93c..d96f83d21a8805aeba6f24cd2f3d28d8c2ffe413 100644 (file)
@@ -127,6 +127,8 @@ public:
         return fInstancedRendering.get();
     }
 
+    GrRenderTargetOpList* asRenderTargetOpList() override { return this; }
+
     SkDEBUGCODE(void dump() const override;)
 
 private:
index cb9b97a4a95b0cb43acacf4583002d2e3a6203e8..03637cf9af1a2e89987899c8ca9f9b77387de0f4 100644 (file)
@@ -54,17 +54,6 @@ GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider)
     return surf->asRenderTarget();
 }
 
-
-#ifdef SK_DEBUG
-void GrRenderTargetProxy::validate(GrContext* context) const {
-    if (fTarget) {
-        SkASSERT(fTarget->getContext() == context);
-    }
-
-    INHERITED::validate();
-}
-#endif
-
 size_t GrRenderTargetProxy::onGpuMemorySize() const {
     if (fTarget) {
         return fTarget->gpuMemorySize();
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
new file mode 100644 (file)
index 0000000..682233b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrSurfaceContext.h"
+
+#include "../private/GrAuditTrail.h"
+
+
+// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
+// GrOpLists to be picked up and added to by renderTargetContexts lower in the call
+// stack. When this occurs with a closed GrOpList, a new one will be allocated
+// when the renderTargetContext attempts to use it (via getOpList).
+GrSurfaceContext::GrSurfaceContext(GrContext* context,
+                                   GrAuditTrail* auditTrail,
+                                   GrSingleOwner* singleOwner)
+    : fContext(context)
+    , fAuditTrail(auditTrail)
+#ifdef SK_DEBUG
+    , fSingleOwner(singleOwner)
+#endif
+{
+}
index 9de41ef48264ca13908990e33b300fcce4ffe6f0..95fc8b9a8af9b02afd4e447031d70d04ae11ce8b 100644 (file)
@@ -66,6 +66,14 @@ void GrSurfaceProxy::setLastOpList(GrOpList* opList) {
     SkRefCnt_SafeAssign(fLastOpList, opList);
 }
 
+GrRenderTargetOpList* GrSurfaceProxy::getLastRenderTargetOpList() {
+    return fLastOpList ? fLastOpList->asRenderTargetOpList() : nullptr;
+}
+
+GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
+    return fLastOpList ? fLastOpList->asTextureOpList() : nullptr;
+}
+
 sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf) {
     if (surf->asTexture()) {
         if (surf->asRenderTarget()) {
@@ -109,3 +117,12 @@ sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
     return GrSurfaceProxy::MakeDeferred(caps, desc, SkBackingFit::kExact, budgeted);
 }
 
+#ifdef SK_DEBUG
+void GrSurfaceProxy::validate(GrContext* context) const {
+    if (fTarget) {
+        SkASSERT(fTarget->getContext() == context);
+    }
+
+    INHERITED::validate();
+}
+#endif
diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp
new file mode 100644 (file)
index 0000000..5c0c17b
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTextureContext.h"
+#include "GrDrawingManager.h"
+#include "GrResourceProvider.h"
+#include "GrTextureOpList.h"
+
+#include "../private/GrAuditTrail.h"
+
+#define ASSERT_SINGLE_OWNER \
+    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
+#define RETURN_FALSE_IF_ABANDONED  if (fDrawingManager->wasAbandoned()) { return false; }
+
+GrTextureContext::GrTextureContext(GrContext* context,
+                                   GrDrawingManager* drawingMgr,
+                                   sk_sp<GrTextureProxy> textureProxy,
+                                   GrAuditTrail* auditTrail,
+                                   GrSingleOwner* singleOwner)
+    : GrSurfaceContext(context, auditTrail, singleOwner)
+    , fDrawingManager(drawingMgr)
+    , fTextureProxy(std::move(textureProxy))
+    , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList()))
+{
+    SkDEBUGCODE(this->validate();)
+}
+
+#ifdef SK_DEBUG
+void GrTextureContext::validate() const {
+    SkASSERT(fTextureProxy);
+    fTextureProxy->validate(fContext);
+
+    if (fOpList && !fOpList->isClosed()) {
+        SkASSERT(fTextureProxy->getLastOpList() == fOpList);
+    }
+}
+#endif
+
+GrTextureContext::~GrTextureContext() {
+    ASSERT_SINGLE_OWNER
+    SkSafeUnref(fOpList);
+}
+
+GrTextureOpList* GrTextureContext::getOpList() {
+    ASSERT_SINGLE_OWNER
+    SkDEBUGCODE(this->validate();)
+
+    if (!fOpList || fOpList->isClosed()) {
+        fOpList = fDrawingManager->newOpList(fTextureProxy.get());
+    }
+
+    return fOpList;
+}
+
+bool GrTextureContext::copySurface(GrSurface* src, const SkIRect& srcRect,
+                                   const SkIPoint& dstPoint) {
+    ASSERT_SINGLE_OWNER
+    RETURN_FALSE_IF_ABANDONED
+    SkDEBUGCODE(this->validate();)
+    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copySurface");
+
+    // TODO: this needs to be fixed up since it ends the deferrable of the GrTexture
+    sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->textureProvider())));
+    if (!tex) {
+        return false;
+    }
+
+    GrTextureOpList* opList = this->getOpList();
+    bool result = opList->copySurface(tex.get(), src, srcRect, dstPoint);
+
+#ifndef ENABLE_MDB
+    GrBatchFlushState flushState(fContext->getGpu(), nullptr);
+    opList->prepareBatches(&flushState);
+    opList->drawBatches(&flushState);
+    opList->reset();
+#endif
+
+    return result;
+}
index 33ca656cf6018d2ae01d8c3ae83339a47fd40024..76741848903179b0eb3f37d19fbad7684f2bdf28 100644 (file)
@@ -55,6 +55,8 @@ public:
                      const SkIRect& srcRect,
                      const SkIPoint& dstPoint);
 
+    GrTextureOpList* asTextureOpList() override { return this; }
+
     SkDEBUGCODE(void dump() const override;)
 
 private: