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>
This commit is contained in:
parent
9f3dcb3f76
commit
952a2435f7
@ -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.
|
||||
*/
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user