195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon/* 295740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * Copyright 2014 Google Inc. 395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * 495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * Use of this source code is governed by a BSD-style license that can be 595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * found in the LICENSE file. 695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon */ 795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#ifndef GrProgramElement_DEFINED 995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#define GrProgramElement_DEFINED 1095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 1195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#include "SkRefCnt.h" 1295740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#include "SkTArray.h" 1395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 14f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomonclass GrGpuResourceRef; 1595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 1695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon/** 17b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * Base class for GrProcessor. GrDrawState uses this to manage 18b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * transitioning a GrProcessor from being owned by a client to being scheduled for execution. It 1995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * converts resources owned by the effect from being ref'ed to having pending reads/writes. 2095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * 2195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * All GrGpuResource objects owned by a GrProgramElement or derived classes (either directly or 22f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon * indirectly) must be wrapped in a GrGpuResourceRef and registered with the GrProgramElement using 23f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon * addGpuResource(). This allows the regular refs to be converted to pending IO events 2495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon * when the program element is scheduled for deferred execution. 2595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon */ 2695740981c36266e4595ddde2264aa38e3c7e2d02bsalomonclass GrProgramElement : public SkNoncopyable { 2795740981c36266e4595ddde2264aa38e3c7e2d02bsalomonpublic: 286f07665768dc84453316e7b2bbd6049576764cb1mtklein SK_DECLARE_INST_COUNT(GrProgramElement) 2995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 3095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon virtual ~GrProgramElement() { 3195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon // fRefCnt can be one when an effect is created statically using GR_CREATE_STATIC_EFFECT 3295740981c36266e4595ddde2264aa38e3c7e2d02bsalomon SkASSERT((0 == fRefCnt || 1 == fRefCnt) && 0 == fPendingExecutions); 3395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon // Set to invalid values. 3495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon SkDEBUGCODE(fRefCnt = fPendingExecutions = -10;) 3595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon } 3695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 3795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon void ref() const { 38ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->validate(); 3995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon // Once the ref cnt reaches zero it should never be ref'ed again. 4095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon SkASSERT(fRefCnt > 0); 4195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon ++fRefCnt; 42ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->validate(); 4395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon } 4495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 4595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon void unref() const { 4695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon this->validate(); 4795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon --fRefCnt; 48d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon if (0 == fRefCnt) { 49d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon if (0 == fPendingExecutions) { 50d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon SkDELETE(this); 51ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon return; 52d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon } else { 53d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon this->removeRefs(); 54d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon } 5595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon } 56ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->validate(); 5795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon } 5895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 5952e9d63f7110ac691609660342cdab32082a4235bsalomon /** 6052e9d63f7110ac691609660342cdab32082a4235bsalomon * Gets an id that is unique for this GrProgramElement object. This will never return 0. 6152e9d63f7110ac691609660342cdab32082a4235bsalomon */ 6252e9d63f7110ac691609660342cdab32082a4235bsalomon uint32_t getUniqueID() const { return fUniqueID; } 6352e9d63f7110ac691609660342cdab32082a4235bsalomon 6495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon void validate() const { 6595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#ifdef SK_DEBUG 6695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon SkASSERT(fRefCnt >= 0); 6795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon SkASSERT(fPendingExecutions >= 0); 6895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon SkASSERT(fRefCnt + fPendingExecutions > 0); 6995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#endif 7095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon } 7195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 7295740981c36266e4595ddde2264aa38e3c7e2d02bsalomonprotected: 7352e9d63f7110ac691609660342cdab32082a4235bsalomon GrProgramElement() : fRefCnt(1), fPendingExecutions(0), fUniqueID(CreateUniqueID()) {} 7495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 7595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon /** Subclasses registers their resources using this function. It is assumed the GrProgramResouce 7695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon is and will remain owned by the subclass and this function will retain a raw ptr. Once a 77f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon GrGpuResourceRef is registered its setResource must not be called. 7895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon */ 79f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon void addGpuResource(const GrGpuResourceRef* res) { 80f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon fGpuResources.push_back(res); 8195740981c36266e4595ddde2264aa38e3c7e2d02bsalomon } 8295740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 8395740981c36266e4595ddde2264aa38e3c7e2d02bsalomonprivate: 8452e9d63f7110ac691609660342cdab32082a4235bsalomon static uint32_t CreateUniqueID(); 8552e9d63f7110ac691609660342cdab32082a4235bsalomon 86ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon void addPendingExecution() const { 87ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->validate(); 88ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon SkASSERT(fRefCnt > 0); 89ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon if (0 == fPendingExecutions) { 90ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->addPendingIOs(); 91ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon } 92ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon ++fPendingExecutions; 93ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->validate(); 94ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon } 9595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 96ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon void completedExecution() const { 97ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->validate(); 98ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon --fPendingExecutions; 99ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon if (0 == fPendingExecutions) { 100ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon if (0 == fRefCnt) { 101ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon SkDELETE(this); 102ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon return; 103ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon } else { 104ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->pendingIOComplete(); 105ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon } 106ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon } 107ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon this->validate(); 108ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon } 10995740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 110d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon void removeRefs() const; 111ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon void addPendingIOs() const; 112ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon void pendingIOComplete() const; 113d012877a6d30ae768f9ccf3239ba09d730cbb6a5bsalomon 11495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon mutable int32_t fRefCnt; 11595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon // Count of deferred executions not yet issued to the 3D API. 11695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon mutable int32_t fPendingExecutions; 11752e9d63f7110ac691609660342cdab32082a4235bsalomon uint32_t fUniqueID; 11895740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 119f96ba02513eadd9fa24d75396ec9f2d6682e464cbsalomon SkSTArray<4, const GrGpuResourceRef*, true> fGpuResources; 12095740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 121ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon // Only this class can access addPendingExecution() and completedExecution(). 122ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon template <typename T> friend class GrPendingProgramElement; 12395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 12495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon typedef SkNoncopyable INHERITED; 12595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon}; 12695740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 12795740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#endif 128