From 881f143aec15e35e76bab64ab0c93de610b7f3fd Mon Sep 17 00:00:00 2001 From: Robert Phillips Date: Thu, 15 Jun 2017 12:28:21 -0400 Subject: Hide GrGpuResourceRef from prying eyes Change-Id: I5535b8cc8e82ed4b6fe847b96b417531b4bae348 Reviewed-on: https://skia-review.googlesource.com/19967 Reviewed-by: Brian Salomon Commit-Queue: Robert Phillips --- src/gpu/GrGpuResourceRef.h | 235 ++++++++++++++++++++++++++++++++++++++++++++ src/gpu/GrMesh.h | 1 - src/gpu/GrOpList.h | 1 - src/gpu/GrPipelineBuilder.h | 1 - src/gpu/GrProgramElement.h | 2 - 5 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 src/gpu/GrGpuResourceRef.h (limited to 'src/gpu') diff --git a/src/gpu/GrGpuResourceRef.h b/src/gpu/GrGpuResourceRef.h new file mode 100644 index 0000000000..a56674b494 --- /dev/null +++ b/src/gpu/GrGpuResourceRef.h @@ -0,0 +1,235 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGpuResourceRef_DEFINED +#define GrGpuResourceRef_DEFINED + +#include "GrGpuResource.h" +#include "SkRefCnt.h" + +/** + * This class is intended only for internal use in core Gr code. + * + * Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages + * 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 sk_sp, 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. + */ +class GrGpuResourceRef : SkNoncopyable { +public: + ~GrGpuResourceRef(); + + 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; } + + /** 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 setResource() with NULL. It cannot be called after markingPendingIO + is called. */ + void reset(); + +protected: + GrGpuResourceRef(); + + /** 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. */ + GrGpuResourceRef(GrGpuResource*, GrIOType); + + /** 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*, 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; + + GrGpuResource* fResource; + mutable bool fOwnRef; + mutable bool fPendingIO; + GrIOType fIOType; + + typedef SkNoncopyable INHERITED; +}; + +class GrSurfaceProxy; + +class GrSurfaceProxyRef : SkNoncopyable { +public: + virtual ~GrSurfaceProxyRef(); + + GrSurfaceProxy* get() 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: + GrSurfaceProxyRef(); + + /** ioType expresses what type of IO operations will be marked as + pending on the resource when markPendingIO is called. */ + GrSurfaceProxyRef(sk_sp, GrIOType); + + /** ioType expresses what type of IO operations will be marked as + pending on the resource when markPendingIO is called. */ + void setProxy(sk_sp, 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; + friend class GrOpList; // for setProxy + + GrSurfaceProxy* fProxy; + mutable bool fOwnRef; + mutable bool fPendingIO; + GrIOType fIOType; + + typedef SkNoncopyable INHERITED; +}; + + +/** + * Templated version of GrGpuResourceRef to enforce type safety. + */ +template class GrTGpuResourceRef : public GrGpuResourceRef { +public: + GrTGpuResourceRef() {} + + /** 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. */ + GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) { } + + T* get() const { return static_cast(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, GrIOType ioType) { this->setResource(resource, ioType); } + +private: + typedef GrGpuResourceRef INHERITED; +}; + +/** + * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a + * ref. + */ +template class GrPendingIOResource : SkNoncopyable { +public: + GrPendingIOResource(T* resource = NULL) : fResource(NULL) { + this->reset(resource); + } + + GrPendingIOResource(const GrPendingIOResource& that) + : GrPendingIOResource(that.get()) { + } + + void reset(T* resource = nullptr) { + if (resource) { + switch (IO_TYPE) { + case kRead_GrIOType: + resource->addPendingRead(); + break; + case kWrite_GrIOType: + resource->addPendingWrite(); + break; + case kRW_GrIOType: + resource->addPendingRead(); + resource->addPendingWrite(); + break; + } + } + this->release(); + fResource = resource; + } + + ~GrPendingIOResource() { + this->release(); + } + + explicit operator bool() const { return SkToBool(fResource); } + + bool operator==(const GrPendingIOResource& other) const { + return fResource == other.fResource; + } + + T* get() const { return fResource; } + +private: + void release() { + if (fResource) { + switch (IO_TYPE) { + case kRead_GrIOType: + fResource->completedRead(); + break; + case kWrite_GrIOType: + fResource->completedWrite(); + break; + case kRW_GrIOType: + fResource->completedRead(); + fResource->completedWrite(); + break; + } + } + } + + T* fResource; +}; +#endif diff --git a/src/gpu/GrMesh.h b/src/gpu/GrMesh.h index bdb62f5f0f..feced48d6f 100644 --- a/src/gpu/GrMesh.h +++ b/src/gpu/GrMesh.h @@ -9,7 +9,6 @@ #define GrMesh_DEFINED #include "GrBuffer.h" -#include "GrGpuResourceRef.h" class GrPrimitiveProcessor; diff --git a/src/gpu/GrOpList.h b/src/gpu/GrOpList.h index 04142d873f..37ca3333d8 100644 --- a/src/gpu/GrOpList.h +++ b/src/gpu/GrOpList.h @@ -9,7 +9,6 @@ #define GrOpList_DEFINED #include "GrGpuResourceRef.h" - #include "SkRefCnt.h" #include "SkTDArray.h" diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index aedc07ca06..9023e8ae1d 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -8,7 +8,6 @@ #ifndef GrPipelineBuilder_DEFINED #define GrPipelineBuilder_DEFINED -#include "GrGpuResourceRef.h" #include "GrPipeline.h" #include "GrProcessorSet.h" #include "GrUserStencilSettings.h" diff --git a/src/gpu/GrProgramElement.h b/src/gpu/GrProgramElement.h index 425f57a59d..ef96738ade 100644 --- a/src/gpu/GrProgramElement.h +++ b/src/gpu/GrProgramElement.h @@ -11,8 +11,6 @@ #include "../private/SkTArray.h" #include "SkRefCnt.h" -class GrGpuResourceRef; - /** * Note: We are converting GrProcessor from ref counting to a single owner model using move * semantics. This class will be removed. -- cgit v1.2.3