From ee783966d4e3f4d9674d4eb9f9ff1b0b73057697 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Wed, 1 Aug 2018 09:55:10 -0400 Subject: [PATCH] templatize GrSurfaceProxyRef Change-Id: I23e848d852a0c126a6581d2682af3f9e927e876f Reviewed-on: https://skia-review.googlesource.com/144607 Reviewed-by: Robert Phillips Commit-Queue: Brian Salomon --- gn/gpu.gni | 3 +- include/private/GrOpList.h | 2 +- include/private/GrProxyRef.h | 149 ++++++++++++++++++++++++++++ include/private/GrSurfaceProxy.h | 3 +- include/private/GrSurfaceProxyRef.h | 68 ------------- src/gpu/GrFragmentProcessor.cpp | 6 +- src/gpu/GrFragmentProcessor.h | 8 +- src/gpu/GrPrimitiveProcessor.cpp | 6 +- src/gpu/GrPrimitiveProcessor.h | 7 +- src/gpu/GrProcessor.h | 1 - src/gpu/GrSurfaceProxyRef.cpp | 118 ---------------------- 11 files changed, 166 insertions(+), 205 deletions(-) create mode 100644 include/private/GrProxyRef.h delete mode 100644 include/private/GrSurfaceProxyRef.h delete mode 100644 src/gpu/GrSurfaceProxyRef.cpp diff --git a/gn/gpu.gni b/gn/gpu.gni index 45aafa585d..2c1f338d8e 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -36,10 +36,10 @@ skia_gpu_sources = [ "$_include/private/GrCCClipPath.h", "$_include/private/GrCCPerOpListPaths.h", "$_include/private/GrOpList.h", + "$_include/private/GrProxyRef.h", "$_include/private/GrSingleOwner.h", "$_include/private/GrRenderTargetProxy.h", "$_include/private/GrSurfaceProxy.h", - "$_include/private/GrSurfaceProxyRef.h", "$_include/private/GrTextureProxy.h", "$_include/private/GrTypesPriv.h", @@ -187,7 +187,6 @@ skia_gpu_sources = [ "$_src/gpu/GrStyle.h", "$_src/gpu/GrSurfaceContextPriv.h", "$_src/gpu/GrSurfaceProxyPriv.h", - "$_src/gpu/GrSurfaceProxyRef.cpp", "$_src/gpu/GrSwizzle.h", "$_src/gpu/GrTessellator.cpp", "$_src/gpu/GrTessellator.h", diff --git a/include/private/GrOpList.h b/include/private/GrOpList.h index be7389fb7b..26d3365988 100644 --- a/include/private/GrOpList.h +++ b/include/private/GrOpList.h @@ -9,7 +9,7 @@ #define GrOpList_DEFINED #include "GrColor.h" -#include "GrSurfaceProxyRef.h" +#include "GrProxyRef.h" #include "GrTextureProxy.h" #include "SkRefCnt.h" #include "SkTDArray.h" diff --git a/include/private/GrProxyRef.h b/include/private/GrProxyRef.h new file mode 100644 index 0000000000..7af6ec49d2 --- /dev/null +++ b/include/private/GrProxyRef.h @@ -0,0 +1,149 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrProxyRef_DEFINED +#define GrProxyRef_DEFINED + +#include "GrSurfaceProxy.h" +#include "GrTextureProxy.h" +#include "GrTypesPriv.h" + +/** + * Helper for owning a ref and/or pending IO on a GrSurfaceProxy. This is useful when ownership + * must transform from ref'ed to pending IO when the owner is recorded into a GrOpList. + */ +template class GrProxyRef { +public: + GrProxyRef() = default; + GrProxyRef(const GrProxyRef&) = delete; + GrProxyRef& operator=(const GrProxyRef&) = delete; + + /** ioType expresses what type of IO operations will be marked as pending on the proxy when + markPendingIO is called. */ + GrProxyRef(sk_sp proxy, GrIOType ioType) { this->setProxy(std::move(proxy), ioType); } + + ~GrProxyRef() { this->reset(); } + + /** ioType expresses what type of IO operations will be marked as + pending on the proxy when markPendingIO is called. */ + void setProxy(sk_sp 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; + } + } + + T* 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() { + if (fPendingIO) { + SkASSERT(fProxy); + switch (fIOType) { + case kRead_GrIOType: + fProxy->completedRead(); + break; + case kWrite_GrIOType: + fProxy->completedWrite(); + break; + case kRW_GrIOType: + fProxy->completedRead(); + fProxy->completedWrite(); + break; + } + fPendingIO = false; + } + if (fOwnRef) { + SkASSERT(fProxy); + fProxy->unref(); + fOwnRef = false; + } + fProxy = nullptr; + } + + /** Called by owning GrProgramElement when the program element is first scheduled for + execution. It can only be called once. */ + void 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; + } + } + + /** 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 { + SkASSERT(fOwnRef); + SkASSERT(fPendingIO); + SkASSERT(fProxy); + fProxy->unref(); + fOwnRef = false; + } + + /** 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 { + 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; + } + +private: + T* fProxy = nullptr; + mutable bool fOwnRef = false; + mutable bool fPendingIO = false; + GrIOType fIOType = kRead_GrIOType; +}; + +using GrSurfaceProxyRef = GrProxyRef; +using GrTextureProxyRef = GrProxyRef; + +#endif diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 425b183ef8..5a50314bdf 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -189,8 +189,7 @@ protected: private: // This class is used to manage conversion of refs to pending reads/writes. - friend class GrSurfaceProxyRef; - template friend class GrPendingIOResource; + template friend class GrProxyRef; void didRemoveRefOrPendingIO() const { if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) { diff --git a/include/private/GrSurfaceProxyRef.h b/include/private/GrSurfaceProxyRef.h deleted file mode 100644 index fb2ed3746a..0000000000 --- a/include/private/GrSurfaceProxyRef.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2018 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrSurfaceProxyRef_DEFINED -#define GrSurfaceProxyRef_DEFINED - -#include "../private/SkNoncopyable.h" -#include "GrTypesPriv.h" - -class GrSurfaceProxy; - -class GrSurfaceProxyRef : SkNoncopyable { -public: - GrSurfaceProxyRef(); - - /** ioType expresses what type of IO operations will be marked as - pending on the resource when markPendingIO is called. */ - GrSurfaceProxyRef(sk_sp, GrIOType); - - ~GrSurfaceProxyRef(); - - /** ioType expresses what type of IO operations will be marked as - pending on the resource when markPendingIO is called. */ - void setProxy(sk_sp, GrIOType); - - 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(); - - /** 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; - -private: - GrSurfaceProxy* fProxy; - mutable bool fOwnRef; - mutable bool fPendingIO; - GrIOType fIOType; - - typedef SkNoncopyable INHERITED; -}; - -#endif diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 081aff31f8..33cde77c3f 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -92,9 +92,9 @@ bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) cons void GrFragmentProcessor::markPendingExecution() const { for (int i = 0; i < fTextureSamplerCnt; ++i) { - auto* proxy = this->textureSampler(i).programProxy(); - proxy->markPendingIO(); - proxy->removeRef(); + auto* ref = this->textureSampler(i).proxyRef(); + ref->markPendingIO(); + ref->removeRef(); } for (int i = 0; i < this->numChildProcessors(); ++i) { this->childProcessor(i).markPendingExecution(); diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h index 9075015f6e..5b9ce2483d 100644 --- a/src/gpu/GrFragmentProcessor.h +++ b/src/gpu/GrFragmentProcessor.h @@ -9,10 +9,10 @@ #define GrFragmentProcessor_DEFINED #include "GrProcessor.h" +#include "GrProxyRef.h" class GrCoordTransform; class GrGLSLFragmentProcessor; -class GrInvariantOutput; class GrPaint; class GrPipeline; class GrProcessorKeyBuilder; @@ -441,17 +441,17 @@ public: return fProxyRef.get()->peekTexture(); } - GrTextureProxy* proxy() const { return fProxyRef.get()->asTextureProxy(); } + GrTextureProxy* proxy() const { return fProxyRef.get(); } const GrSamplerState& samplerState() const { return fSamplerState; } bool isInitialized() const { return SkToBool(fProxyRef.get()); } /** * For internal use by GrFragmentProcessor. */ - const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; } + const GrTextureProxyRef* proxyRef() const { return &fProxyRef; } private: - GrSurfaceProxyRef fProxyRef; + GrTextureProxyRef fProxyRef; GrSamplerState fSamplerState; }; diff --git a/src/gpu/GrPrimitiveProcessor.cpp b/src/gpu/GrPrimitiveProcessor.cpp index 10b13370f4..84db9cafec 100644 --- a/src/gpu/GrPrimitiveProcessor.cpp +++ b/src/gpu/GrPrimitiveProcessor.cpp @@ -76,19 +76,19 @@ size_t GrPrimitiveProcessor::debugOnly_instanceAttributeOffset(int i) const { void GrPrimitiveProcessor::addPendingIOs() const { for (int i = 0; i < fTextureSamplerCnt; ++i) { - this->textureSampler(i).programProxy()->markPendingIO(); + this->textureSampler(i).proxyRef()->markPendingIO(); } } void GrPrimitiveProcessor::removeRefs() const { for (int i = 0; i < fTextureSamplerCnt; ++i) { - this->textureSampler(i).programProxy()->removeRef(); + this->textureSampler(i).proxyRef()->removeRef(); } } void GrPrimitiveProcessor::pendingIOComplete() const { for (int i = 0; i < fTextureSamplerCnt; ++i) { - this->textureSampler(i).programProxy()->pendingIOComplete(); + this->textureSampler(i).proxyRef()->pendingIOComplete(); } } diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h index 20471ea139..ddebd2171f 100644 --- a/src/gpu/GrPrimitiveProcessor.h +++ b/src/gpu/GrPrimitiveProcessor.h @@ -10,6 +10,7 @@ #include "GrColor.h" #include "GrProcessor.h" +#include "GrProxyRef.h" #include "GrShaderVar.h" class GrCoordTransform; @@ -216,7 +217,7 @@ public: return fProxyRef.get()->peekTexture(); } - GrTextureProxy* proxy() const { return fProxyRef.get()->asTextureProxy(); } + GrTextureProxy* proxy() const { return fProxyRef.get(); } GrShaderFlags visibility() const { return fVisibility; } const GrSamplerState& samplerState() const { return fSamplerState; } @@ -224,10 +225,10 @@ public: /** * For internal use by GrPrimitiveProcessor. */ - const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; } + const GrTextureProxyRef* proxyRef() const { return &fProxyRef; } private: - GrSurfaceProxyRef fProxyRef; + GrTextureProxyRef fProxyRef; GrSamplerState fSamplerState; GrShaderFlags fVisibility = kNone_GrShaderFlags; }; diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 1c0161a811..4afb246244 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -16,7 +16,6 @@ #include "GrSamplerState.h" #include "GrShaderVar.h" #include "GrSurfaceProxyPriv.h" -#include "GrSurfaceProxyRef.h" #include "GrTextureProxy.h" #include "SkMath.h" #include "SkString.h" diff --git a/src/gpu/GrSurfaceProxyRef.cpp b/src/gpu/GrSurfaceProxyRef.cpp deleted file mode 100644 index ad13e4a450..0000000000 --- a/src/gpu/GrSurfaceProxyRef.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2018 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrSurfaceProxyRef.h" -#include "GrTextureProxy.h" - -GrSurfaceProxyRef::GrSurfaceProxyRef() { - fProxy = nullptr; - fOwnRef = false; - fPendingIO = false; -} - -GrSurfaceProxyRef::GrSurfaceProxyRef(sk_sp proxy, GrIOType ioType) { - fProxy = nullptr; - fOwnRef = false; - fPendingIO = false; - this->setProxy(std::move(proxy), ioType); -} - -GrSurfaceProxyRef::~GrSurfaceProxyRef() { - this->reset(); -} - -void GrSurfaceProxyRef::reset() { - if (fPendingIO) { - SkASSERT(fProxy); - switch (fIOType) { - case kRead_GrIOType: - fProxy->completedRead(); - break; - case kWrite_GrIOType: - fProxy->completedWrite(); - break; - case kRW_GrIOType: - fProxy->completedRead(); - fProxy->completedWrite(); - break; - } - fPendingIO = false; - } - if (fOwnRef) { - SkASSERT(fProxy); - fProxy->unref(); - fOwnRef = false; - } - - fProxy = nullptr; -} - -void GrSurfaceProxyRef::setProxy(sk_sp 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 GrSurfaceProxyRef::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 GrSurfaceProxyRef::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 GrSurfaceProxyRef::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; -} -