From e57194f74d125c7b0ba767ae5357b97d102792ef Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Mon, 9 Jan 2017 15:30:02 -0500 Subject: [PATCH] Move resource ref/io manipulation from GrProgramElement to GrProcessor Change-Id: I783e74107f7d34b57d80b843fe23ce7126b77424 Reviewed-on: https://skia-review.googlesource.com/6816 Reviewed-by: Robert Phillips Commit-Queue: Brian Salomon --- gn/gpu.gni | 1 - include/gpu/GrGpuResourceRef.h | 2 +- include/gpu/GrProcessor.h | 7 ++++++- include/gpu/GrProgramElement.h | 40 ++++++++++++---------------------------- src/gpu/GrProcessor.cpp | 39 ++++++++++++++++++++++++++++++++++++--- src/gpu/GrProgramElement.cpp | 28 ---------------------------- 6 files changed, 55 insertions(+), 62 deletions(-) delete mode 100644 src/gpu/GrProgramElement.cpp diff --git a/gn/gpu.gni b/gn/gpu.gni index a635401..41dd076 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -145,7 +145,6 @@ skia_gpu_sources = [ "$_src/gpu/GrPrimitiveProcessor.h", "$_src/gpu/GrProgramDesc.cpp", "$_src/gpu/GrProgramDesc.h", - "$_src/gpu/GrProgramElement.cpp", "$_src/gpu/GrProcessor.cpp", "$_src/gpu/GrProcessorUnitTest.cpp", "$_src/gpu/GrProcOptInfo.cpp", diff --git a/include/gpu/GrGpuResourceRef.h b/include/gpu/GrGpuResourceRef.h index a51d814..d6da1d2 100644 --- a/include/gpu/GrGpuResourceRef.h +++ b/include/gpu/GrGpuResourceRef.h @@ -79,7 +79,7 @@ private: called. */ void pendingIOComplete() const; - friend class GrProgramElement; + friend class GrProcessor; GrGpuResource* fResource; mutable bool fOwnRef; diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h index 95a669e..f0f895f 100644 --- a/include/gpu/GrProcessor.h +++ b/include/gpu/GrProcessor.h @@ -59,7 +59,7 @@ private: Dynamically allocated GrProcessors are managed by a per-thread memory pool. The ref count of an processor must reach 0 before the thread terminates and the pool is destroyed. */ -class GrProcessor : public GrProgramElement { +class GrProcessor : public GrProgramElement { public: class TextureSampler; class BufferAccess; @@ -171,6 +171,11 @@ private: return id; } + friend class GrProgramElement; + void addPendingIOs() const; + void removeRefs() const; + void pendingIOComplete() const; + enum { kIllegalProcessorClassID = 0, }; diff --git a/include/gpu/GrProgramElement.h b/include/gpu/GrProgramElement.h index e0d8608..71905ac 100644 --- a/include/gpu/GrProgramElement.h +++ b/include/gpu/GrProgramElement.h @@ -14,6 +14,9 @@ class GrGpuResourceRef; /** + * Note: We are converting GrProcessor from ref counting to a single owner model using move + * semantics. This class will be removed. + * * Base class for GrProcessor. This exists to manage transitioning a GrProcessor from being owned by * a client to being scheduled for execution. While a GrProcessor is ref'ed by drawing code its * GrGpu resources must also be ref'ed to prevent incorrectly recycling them through the cache. @@ -30,18 +33,13 @@ class GrGpuResourceRef; * safe to recycle a resource even though we still have buffered GrOps that read or write to the * the resource. * - * To make this work all GrGpuResource objects owned by a GrProgramElement or derived classes - * (either directly or indirectly) must be wrapped in a GrGpuResourceRef and registered with the - * GrProgramElement using addGpuResource(). This allows the regular refs to be converted to pending - * IO events when the program element is scheduled for deferred execution. - * - * Moreover, a GrProgramElement that in turn owns other GrProgramElements must convert its ownership - * of its children to pending executions when its ref count reaches zero so that the GrGpuResources - * owned by the children GrProgramElements are correctly converted from ownership by ref to - * ownership by pending IO. Any GrProgramElement hierarchy is managed by subclasses which must - * implement notifyRefCntIsZero() in order to convert refs of children to pending executions. + * To make this work the subclass, GrProcessor, implements addPendingIOs and pendingIOComplete. The + * former adds pending reads/writes as appropriate when the processor is recorded in a GrOpList. The + * latter removes them after the op list executes the operation. These calls must propagate to any + * children processors. Similarly, the subclass implements a removeRefs function in order to remove + * refs from resources once the processor is only owned for pending execution. */ -class GrProgramElement : public SkNoncopyable { +template class GrProgramElement : public SkNoncopyable { public: virtual ~GrProgramElement() { // fRefCnt can be one when an effect is created statically using GR_CREATE_STATIC_EFFECT @@ -67,7 +65,7 @@ public: delete this; return; } else { - this->removeRefs(); + static_cast(this)->removeRefs(); } } this->validate(); @@ -84,19 +82,11 @@ public: protected: GrProgramElement() : fRefCnt(1), fPendingExecutions(0) {} - /** Subclasses registers their resources using this function. It is assumed the GrProgramResouce - is and will remain owned by the subclass and this function will retain a raw ptr. Once a - GrGpuResourceRef is registered its setResource must not be called. - */ - void addGpuResource(const GrGpuResourceRef* res) { - fGpuResources.push_back(res); - } - void addPendingExecution() const { this->validate(); SkASSERT(fRefCnt > 0); if (0 == fPendingExecutions) { - this->addPendingIOs(); + static_cast(this)->addPendingIOs(); } ++fPendingExecutions; this->validate(); @@ -110,7 +100,7 @@ protected: delete this; return; } else { - this->pendingIOComplete(); + static_cast(this)->pendingIOComplete(); } } this->validate(); @@ -121,16 +111,10 @@ private: executions. */ virtual void notifyRefCntIsZero() const = 0; - void removeRefs() const; - void addPendingIOs() const; - void pendingIOComplete() const; - mutable int32_t fRefCnt; // Count of deferred executions not yet issued to the 3D API. mutable int32_t fPendingExecutions; - SkSTArray<4, const GrGpuResourceRef*, true> fGpuResources; - // Only this class can access addPendingExecution() and completedExecution(). template friend class GrPendingProgramElement; diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 0512aa8..f4bead2 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -114,17 +114,50 @@ GrProcessor::~GrProcessor() {} void GrProcessor::addTextureSampler(const TextureSampler* access) { fTextureSamplers.push_back(access); - this->addGpuResource(access->programTexture()); } void GrProcessor::addBufferAccess(const BufferAccess* access) { fBufferAccesses.push_back(access); - this->addGpuResource(access->programBuffer()); } void GrProcessor::addImageStorageAccess(const ImageStorageAccess* access) { fImageStorageAccesses.push_back(access); - this->addGpuResource(access->programTexture()); +} + +void GrProcessor::addPendingIOs() const { + for (const auto& sampler : fTextureSamplers) { + sampler->programTexture()->markPendingIO(); + } + for (const auto& buffer : fBufferAccesses) { + buffer->programBuffer()->markPendingIO(); + } + for (const auto& imageStorage : fImageStorageAccesses) { + imageStorage->programTexture()->markPendingIO(); + } +} + +void GrProcessor::removeRefs() const { + for (const auto& sampler : fTextureSamplers) { + sampler->programTexture()->removeRef(); + } + for (const auto& buffer : fBufferAccesses) { + buffer->programBuffer()->removeRef(); + } + for (const auto& imageStorage : fImageStorageAccesses) { + imageStorage->programTexture()->removeRef(); + } +} + +void GrProcessor::pendingIOComplete() const { + for (const auto& sampler : fTextureSamplers) { + sampler->programTexture()->pendingIOComplete(); + } + for (const auto& buffer : fBufferAccesses) { + buffer->programBuffer()->pendingIOComplete(); + } + for (const auto& imageStorage : fImageStorageAccesses) { + imageStorage->programTexture()->pendingIOComplete(); + } } void* GrProcessor::operator new(size_t size) { diff --git a/src/gpu/GrProgramElement.cpp b/src/gpu/GrProgramElement.cpp deleted file mode 100644 index 82bb721..0000000 --- a/src/gpu/GrProgramElement.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrProgramElement.h" -#include "GrGpuResourceRef.h" -#include "SkAtomics.h" - -void GrProgramElement::addPendingIOs() const { - for (int i = 0; i < fGpuResources.count(); ++i) { - fGpuResources[i]->markPendingIO(); - } -} - -void GrProgramElement::removeRefs() const { - for (int i = 0; i < fGpuResources.count(); ++i) { - fGpuResources[i]->removeRef(); - } -} - -void GrProgramElement::pendingIOComplete() const { - for (int i = 0; i < fGpuResources.count(); ++i) { - fGpuResources[i]->pendingIOComplete(); - } -} -- 2.7.4