aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-05-04 08:52:22 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-04 13:29:29 +0000
commit952a2435f7a38624ffbd0ac3b44d30f4b887a48b (patch)
treed3076827d7fdb1e6864b0a69cc9596a5bae1a64f
parent9f3dcb3f760274d42e28095fd3cf0f484168d996 (diff)
Add GrGpuTextureProxyRef
Basically a GrTextureProxified clone of GrGpuResourceRef Change-Id: I8772550bb867ef2cf2d53efef0a0346bb7c90eb6 Reviewed-on: https://skia-review.googlesource.com/15221 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r--include/gpu/GrGpuResourceRef.h58
-rw-r--r--include/private/GrSurfaceProxy.h2
-rw-r--r--src/gpu/GrGpuResourceRef.cpp113
3 files changed, 172 insertions, 1 deletions
diff --git a/include/gpu/GrGpuResourceRef.h b/include/gpu/GrGpuResourceRef.h
index 3a170f44d2..f82b502574 100644
--- a/include/gpu/GrGpuResourceRef.h
+++ b/include/gpu/GrGpuResourceRef.h
@@ -89,6 +89,64 @@ private:
typedef SkNoncopyable INHERITED;
};
+class GrTextureProxy;
+
+class GrTextureProxyRef : SkNoncopyable {
+public:
+ virtual ~GrTextureProxyRef();
+
+ GrTextureProxy* getProxy() const { return fProxy; }
+
+ /** Does this object own a pending read or write on the resource it is wrapping. */
+ bool ownsPendingIO() const { return fPendingIO; }
+
+ /** What type of IO does this represent? This is independent of whether a normal ref or a
+ pending IO is currently held. */
+ GrIOType ioType() const { return fIOType; }
+
+ /** Shortcut for calling setProxy() with NULL. It cannot be called after markingPendingIO
+ is called. */
+ void reset();
+
+protected:
+ GrTextureProxyRef();
+
+ /** ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ GrTextureProxyRef(sk_sp<GrTextureProxy>, GrIOType);
+
+ /** ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ void setProxy(sk_sp<GrTextureProxy>, GrIOType);
+
+private:
+ /** Called by owning GrProgramElement when the program element is first scheduled for
+ execution. It can only be called once. */
+ void markPendingIO() const;
+
+ /** Called when the program element/draw state is no longer owned by GrOpList-client code.
+ This lets the cache know that the drawing code will no longer schedule additional reads or
+ writes to the resource using the program element or draw state. It can only be called once.
+ */
+ void removeRef() const;
+
+ /** Called to indicate that the previous pending IO is complete. Useful when the owning object
+ still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
+ pending executions have been complete. Can only be called if removeRef() was not previously
+ called. */
+ void pendingIOComplete() const;
+
+ friend class GrResourceIOProcessor;
+
+ GrTextureProxy* fProxy;
+ mutable bool fOwnRef;
+ mutable bool fPendingIO;
+ GrIOType fIOType;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+
/**
* Templated version of GrGpuResourceRef to enforce type safety.
*/
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 7f47145cb0..94490603bc 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -125,7 +125,7 @@ protected:
private:
// This class is used to manage conversion of refs to pending reads/writes.
- friend class GrGpuResourceRef;
+ friend class GrTextureProxyRef;
template <typename, GrIOType> friend class GrPendingIOResource;
void addPendingRead() const {
diff --git a/src/gpu/GrGpuResourceRef.cpp b/src/gpu/GrGpuResourceRef.cpp
index 532e0655d8..fc1c8b914f 100644
--- a/src/gpu/GrGpuResourceRef.cpp
+++ b/src/gpu/GrGpuResourceRef.cpp
@@ -125,3 +125,116 @@ void GrGpuResourceRef::removeRef() const {
fResource->unref();
fOwnRef = false;
}
+
+///////////////////////////////////////////////////////////////////////////////
+#include "GrTextureProxy.h"
+
+GrTextureProxyRef::GrTextureProxyRef() {
+ fProxy = nullptr;
+ fOwnRef = false;
+ fPendingIO = false;
+}
+
+GrTextureProxyRef::GrTextureProxyRef(sk_sp<GrTextureProxy> proxy, GrIOType ioType) {
+ fProxy = nullptr;
+ fOwnRef = false;
+ fPendingIO = false;
+ this->setProxy(proxy, ioType);
+}
+
+GrTextureProxyRef::~GrTextureProxyRef() {
+ if (fOwnRef) {
+ SkASSERT(fProxy);
+ fProxy->unref();
+ }
+ if (fPendingIO) {
+ switch (fIOType) {
+ case kRead_GrIOType:
+ fProxy->completedRead();
+ break;
+ case kWrite_GrIOType:
+ fProxy->completedWrite();
+ break;
+ case kRW_GrIOType:
+ fProxy->completedRead();
+ fProxy->completedWrite();
+ break;
+ }
+ }
+}
+
+void GrTextureProxyRef::reset() {
+ SkASSERT(!fPendingIO);
+ SkASSERT(SkToBool(fProxy) == fOwnRef);
+ if (fOwnRef) {
+ fProxy->unref();
+ fOwnRef = false;
+ fProxy = nullptr;
+ }
+}
+
+void GrTextureProxyRef::setProxy(sk_sp<GrTextureProxy> proxy, GrIOType ioType) {
+ SkASSERT(!fPendingIO);
+ SkASSERT(SkToBool(fProxy) == fOwnRef);
+ SkSafeUnref(fProxy);
+ if (!proxy) {
+ fProxy = nullptr;
+ fOwnRef = false;
+ } else {
+ fProxy = proxy.release(); // due to the semantics of this class we unpack from sk_sp
+ fOwnRef = true;
+ fIOType = ioType;
+ }
+}
+
+void GrTextureProxyRef::markPendingIO() const {
+ // This should only be called when the owning GrProgramElement gets its first
+ // pendingExecution ref.
+ SkASSERT(!fPendingIO);
+ SkASSERT(fProxy);
+ fPendingIO = true;
+ switch (fIOType) {
+ case kRead_GrIOType:
+ fProxy->addPendingRead();
+ break;
+ case kWrite_GrIOType:
+ fProxy->addPendingWrite();
+ break;
+ case kRW_GrIOType:
+ fProxy->addPendingRead();
+ fProxy->addPendingWrite();
+ break;
+ }
+}
+
+void GrTextureProxyRef::pendingIOComplete() const {
+ // This should only be called when the owner's pending executions have ocurred but it is still
+ // reffed.
+ SkASSERT(fOwnRef);
+ SkASSERT(fPendingIO);
+ switch (fIOType) {
+ case kRead_GrIOType:
+ fProxy->completedRead();
+ break;
+ case kWrite_GrIOType:
+ fProxy->completedWrite();
+ break;
+ case kRW_GrIOType:
+ fProxy->completedRead();
+ fProxy->completedWrite();
+ break;
+
+ }
+ fPendingIO = false;
+}
+
+void GrTextureProxyRef::removeRef() const {
+ // This should only be called once, when the owners last ref goes away and
+ // there is a pending execution.
+ SkASSERT(fOwnRef);
+ SkASSERT(fPendingIO);
+ SkASSERT(fProxy);
+ fProxy->unref();
+ fOwnRef = false;
+}
+