diff options
author | 2016-11-16 11:17:17 -0800 | |
---|---|---|
committer | 2016-11-16 11:17:17 -0800 | |
commit | 1125a030c726854f94fd2b8eed49d1323fc1d038 (patch) | |
tree | 56a26a60c160186a4cada83e904d0d3c60c25a6e /include/private | |
parent | 20079a94e82fd7345dfb119a8777e5ba482a041c (diff) |
Add IORef capability to GrSurfaceProxy objects - take 2
Re-landing of https://skia-review.googlesource.com/c/4734/ (Add IORef capability to GrSurfaceProxy objects) with fixes for:
platforms that don't support discards.
memory leak due to copying over of GrSurfaceProxy's creation ref to instantiated GrSurface in instantiate()
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4827
BUG=skia:
Change-Id: If0b695d5cafc5ef3fdd251c38262849d09e5d27f
Review-Url: https://codereview.chromium.org/2502923003
Diffstat (limited to 'include/private')
-rw-r--r-- | include/private/GrSurfaceProxy.h | 91 |
1 files changed, 85 insertions, 6 deletions
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index dd5ece1e2c..1ff6df809d 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -50,13 +50,29 @@ public: void validate() const { #ifdef SK_DEBUG - SkASSERT(fRefCnt >= 0); + SkASSERT(fRefCnt >= 1); + SkASSERT(fPendingReads >= 0); + SkASSERT(fPendingWrites >= 0); + SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 1); + + if (fTarget) { + SkASSERT(!fPendingReads && !fPendingWrites); + // The backing GrSurface can have more refs than the proxy if the proxy + // started off wrapping an external resource (that came in with refs). + // The GrSurface should never have fewer refs than the proxy however. + SkASSERT(fTarget->fRefCnt >= fRefCnt); + } #endif } + int32_t getProxyRefCnt_TestOnly() const; + int32_t getBackingRefCnt_TestOnly() const; + int32_t getPendingReadCnt_TestOnly() const; + int32_t getPendingWriteCnt_TestOnly() const; + protected: - GrIORefProxy() : fRefCnt(1), fTarget(nullptr) {} - GrIORefProxy(sk_sp<GrSurface> surface) : fRefCnt(1) { + GrIORefProxy() : fTarget(nullptr), fRefCnt(1), fPendingReads(0), fPendingWrites(0) {} + GrIORefProxy(sk_sp<GrSurface> surface) : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { // Since we're manually forwarding on refs & unrefs we don't want sk_sp doing // anything extra. fTarget = surface.release(); @@ -66,13 +82,76 @@ protected: // have forwarded on the unref call that got use here. } - // TODO: add the IO ref counts. Although if we can delay shader creation to flush time - // we may not even need to do that. - mutable int32_t fRefCnt; + // This GrIORefProxy was deferred before but has just been instantiated. To + // make all the reffing & unreffing work out we now need to transfer any deferred + // refs & unrefs to the new GrSurface + void transferRefs() { + SkASSERT(fTarget); + + fTarget->fRefCnt += (fRefCnt-1); // don't xfer the proxy's creation ref + fTarget->fPendingReads += fPendingReads; + fTarget->fPendingWrites += fPendingWrites; + + fPendingReads = 0; + fPendingWrites = 0; + } // For deferred proxies this will be null. For wrapped proxies it will point to the // wrapped resource. GrSurface* fTarget; + +private: + // This class is used to manage conversion of refs to pending reads/writes. + friend class GrGpuResourceRef; + template <typename, GrIOType> friend class GrPendingIOResource; + + void addPendingRead() const { + this->validate(); + + if (fTarget) { + fTarget->addPendingRead(); + return; + } + + ++fPendingReads; + } + + void completedRead() const { + this->validate(); + + if (fTarget) { + fTarget->completedRead(); + return; + } + + SkFAIL("How was the read completed if the Proxy hasn't been instantiated?"); + } + + void addPendingWrite() const { + this->validate(); + + if (fTarget) { + fTarget->addPendingWrite(); + return; + } + + ++fPendingWrites; + } + + void completedWrite() const { + this->validate(); + + if (fTarget) { + fTarget->completedWrite(); + return; + } + + SkFAIL("How was the write completed if the Proxy hasn't been instantiated?"); + } + + mutable int32_t fRefCnt; + mutable int32_t fPendingReads; + mutable int32_t fPendingWrites; }; class GrSurfaceProxy : public GrIORefProxy { |