2014-09-04 20:12:37 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2014-09-17 15:05:40 +00:00
|
|
|
#ifndef GrGpuResourceRef_DEFINED
|
|
|
|
#define GrGpuResourceRef_DEFINED
|
2014-09-04 20:12:37 +00:00
|
|
|
|
|
|
|
#include "SkRefCnt.h"
|
|
|
|
|
|
|
|
class GrGpuResource;
|
|
|
|
|
|
|
|
/**
|
2014-09-19 18:10:40 +00:00
|
|
|
* This class is intended only for internal use in core Gr code.
|
|
|
|
*
|
2014-09-04 20:12:37 +00:00
|
|
|
* Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages
|
2014-09-19 18:10:40 +00:00
|
|
|
* converting refs to pending IO operations. It allows a resource ownership to be in three
|
|
|
|
* states:
|
|
|
|
* 1. Owns a single ref
|
|
|
|
* 2. Owns a single ref and a pending IO operation (read, write, or read-write)
|
|
|
|
* 3. Owns a single pending IO operation.
|
|
|
|
*
|
|
|
|
* It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state
|
|
|
|
* 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from
|
|
|
|
* state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no
|
|
|
|
* valid way of going from state 3 back to 2 or 1.
|
|
|
|
*
|
|
|
|
* Like SkAutoTUnref, its constructor and setter adopt a ref from their caller.
|
|
|
|
*
|
|
|
|
* TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no
|
|
|
|
* longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef
|
|
|
|
* only settable via the constructor.
|
2014-09-04 20:12:37 +00:00
|
|
|
*/
|
2014-09-17 15:05:40 +00:00
|
|
|
class GrGpuResourceRef : SkNoncopyable {
|
2014-09-04 20:12:37 +00:00
|
|
|
public:
|
2014-09-17 15:05:40 +00:00
|
|
|
SK_DECLARE_INST_COUNT_ROOT(GrGpuResourceRef);
|
2014-09-16 20:54:53 +00:00
|
|
|
|
2014-09-04 20:12:37 +00:00
|
|
|
enum IOType {
|
|
|
|
kRead_IOType,
|
|
|
|
kWrite_IOType,
|
|
|
|
kRW_IOType,
|
|
|
|
|
|
|
|
kNone_IOType, // For internal use only, don't specify to constructor or setResource().
|
|
|
|
};
|
|
|
|
|
2014-09-17 15:05:40 +00:00
|
|
|
~GrGpuResourceRef();
|
2014-09-04 20:12:37 +00:00
|
|
|
|
|
|
|
GrGpuResource* getResource() const { return fResource; }
|
|
|
|
|
|
|
|
/** Does this object own a pending read or write on the resource it is wrapping. */
|
|
|
|
bool ownsPendingIO() const { return fPendingIO; }
|
|
|
|
|
|
|
|
/** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
|
|
|
|
is called. */
|
|
|
|
void reset();
|
|
|
|
|
2014-09-16 20:54:53 +00:00
|
|
|
protected:
|
2014-09-17 15:05:40 +00:00
|
|
|
GrGpuResourceRef();
|
2014-09-16 20:54:53 +00:00
|
|
|
|
|
|
|
/** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
|
|
|
|
pending on the resource when markPendingIO is called. */
|
2014-09-17 15:05:40 +00:00
|
|
|
GrGpuResourceRef(GrGpuResource*, IOType);
|
2014-09-16 20:54:53 +00:00
|
|
|
|
|
|
|
/** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
|
|
|
|
pending on the resource when markPendingIO is called. */
|
|
|
|
void setResource(GrGpuResource*, IOType);
|
|
|
|
|
2014-09-04 20:12:37 +00:00
|
|
|
private:
|
|
|
|
/** Called by owning GrProgramElement when the program element is first scheduled for
|
2014-09-19 18:10:40 +00:00
|
|
|
execution. It can only be called once. */
|
2014-09-04 20:12:37 +00:00
|
|
|
void markPendingIO() const;
|
|
|
|
|
|
|
|
/** Called when the program element/draw state is no longer owned by GrDrawTarget-client code.
|
|
|
|
This lets the cache know that the drawing code will no longer schedule additional reads or
|
2014-09-19 18:10:40 +00:00
|
|
|
writes to the resource using the program element or draw state. It can only be called once.
|
|
|
|
*/
|
2014-09-04 20:12:37 +00:00
|
|
|
void removeRef() const;
|
|
|
|
|
2014-09-04 21:13:44 +00:00
|
|
|
/** Called to indicate that the previous pending IO is complete. Useful when the owning object
|
2014-09-17 15:05:40 +00:00
|
|
|
still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
|
2014-09-19 18:10:40 +00:00
|
|
|
pending executions have been complete. Can only be called if removeRef() was not previously
|
|
|
|
called. */
|
2014-09-04 21:13:44 +00:00
|
|
|
void pendingIOComplete() const;
|
|
|
|
|
|
|
|
friend class GrRODrawState;
|
2014-09-04 20:12:37 +00:00
|
|
|
friend class GrProgramElement;
|
|
|
|
|
|
|
|
GrGpuResource* fResource;
|
|
|
|
mutable bool fOwnRef;
|
|
|
|
mutable bool fPendingIO;
|
|
|
|
IOType fIOType;
|
|
|
|
|
|
|
|
typedef SkNoncopyable INHERITED;
|
|
|
|
};
|
|
|
|
|
2014-09-19 18:10:40 +00:00
|
|
|
/**
|
|
|
|
* Templated version of GrGpuResourceRef to enforce type safety.
|
|
|
|
*/
|
2014-09-17 15:05:40 +00:00
|
|
|
template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
|
2014-09-16 20:54:53 +00:00
|
|
|
public:
|
2014-09-17 15:05:40 +00:00
|
|
|
GrTGpuResourceRef() {}
|
2014-09-16 20:54:53 +00:00
|
|
|
|
|
|
|
/** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
|
|
|
|
pending on the resource when markPendingIO is called. */
|
2014-09-17 15:05:40 +00:00
|
|
|
GrTGpuResourceRef(T* resource, IOType ioType) : INHERITED(resource, ioType) {}
|
2014-09-16 20:54:53 +00:00
|
|
|
|
|
|
|
T* get() const { return static_cast<T*>(this->getResource()); }
|
|
|
|
|
|
|
|
/** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
|
|
|
|
pending on the resource when markPendingIO is called. */
|
|
|
|
void set(T* resource, IOType ioType) { this->setResource(resource, ioType); }
|
2014-09-17 15:05:40 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
typedef GrGpuResourceRef INHERITED;
|
2014-09-16 20:54:53 +00:00
|
|
|
};
|
|
|
|
|
2014-09-19 18:10:40 +00:00
|
|
|
/**
|
|
|
|
* This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
|
|
|
|
* ref.
|
|
|
|
*/
|
|
|
|
template <typename T> class GrPendingIOResource : SkNoncopyable {
|
|
|
|
public:
|
|
|
|
typedef GrGpuResourceRef::IOType IOType;
|
|
|
|
GrPendingIOResource(T* resource, IOType ioType) : fResource(resource), fIOType(ioType) {
|
|
|
|
if (NULL != fResource) {
|
|
|
|
switch (fIOType) {
|
|
|
|
case GrGpuResourceRef::kNone_IOType:
|
|
|
|
SkFAIL("GrPendingIOResource with neither reads nor writes?");
|
|
|
|
break;
|
|
|
|
case GrGpuResourceRef::kRead_IOType:
|
|
|
|
fResource->addPendingRead();
|
|
|
|
break;
|
|
|
|
case GrGpuResourceRef::kWrite_IOType:
|
|
|
|
fResource->addPendingWrite();
|
|
|
|
break;
|
|
|
|
case GrGpuResourceRef::kRW_IOType:
|
|
|
|
fResource->addPendingRead();
|
|
|
|
fResource->addPendingWrite();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~GrPendingIOResource() {
|
|
|
|
if (NULL != fResource) {
|
|
|
|
switch (fIOType) {
|
|
|
|
case GrGpuResourceRef::kNone_IOType:
|
|
|
|
SkFAIL("GrPendingIOResource with neither reads nor writes?");
|
|
|
|
break;
|
|
|
|
case GrGpuResourceRef::kRead_IOType:
|
|
|
|
fResource->completedRead();
|
|
|
|
break;
|
|
|
|
case GrGpuResourceRef::kWrite_IOType:
|
|
|
|
fResource->completedWrite();
|
|
|
|
break;
|
|
|
|
case GrGpuResourceRef::kRW_IOType:
|
|
|
|
fResource->completedRead();
|
|
|
|
fResource->completedWrite();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
T* get() const { return fResource; }
|
2014-09-16 20:54:53 +00:00
|
|
|
|
2014-09-19 18:10:40 +00:00
|
|
|
private:
|
|
|
|
T* fResource;
|
|
|
|
IOType fIOType;
|
|
|
|
};
|
2014-09-04 20:12:37 +00:00
|
|
|
#endif
|