diff options
author | Robert Phillips <robertphillips@google.com> | 2017-05-04 08:52:22 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-04 13:29:29 +0000 |
commit | 952a2435f7a38624ffbd0ac3b44d30f4b887a48b (patch) | |
tree | d3076827d7fdb1e6864b0a69cc9596a5bae1a64f | |
parent | 9f3dcb3f760274d42e28095fd3cf0f484168d996 (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.h | 58 | ||||
-rw-r--r-- | include/private/GrSurfaceProxy.h | 2 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceRef.cpp | 113 |
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; +} + |