blob: e64339bacbee94581a63bd70b3cafedc3ae8120c [file] [log] [blame]
bsalomon@google.com8fe72472011-03-30 21:26:44 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
bsalomon@google.com8fe72472011-03-30 21:26:44 +00006 */
7
bsalomon6d3fe022014-07-25 08:35:45 -07008#include "GrGpuResource.h"
kkinnunencabe20c2015-06-01 01:37:26 -07009#include "GrContext.h"
bsalomon0ea80f42015-02-11 10:49:59 -080010#include "GrResourceCache.h"
bsalomon@google.com8fe72472011-03-30 21:26:44 +000011#include "GrGpu.h"
bsalomon3582d3e2015-02-13 14:20:05 -080012#include "GrGpuResourcePriv.h"
ericrk0a5fa482015-09-15 14:16:10 -070013#include "SkTraceMemoryDump.h"
bsalomon@google.com8fe72472011-03-30 21:26:44 +000014
bsalomon0ea80f42015-02-11 10:49:59 -080015static inline GrResourceCache* get_resource_cache(GrGpu* gpu) {
bsalomon49f085d2014-09-05 13:34:00 -070016 SkASSERT(gpu);
17 SkASSERT(gpu->getContext());
bsalomon0ea80f42015-02-11 10:49:59 -080018 SkASSERT(gpu->getContext()->getResourceCache());
19 return gpu->getContext()->getResourceCache();
bsalomonc8dc1f72014-08-21 13:02:13 -070020}
21
kkinnunen2e6055b2016-04-22 01:48:29 -070022GrGpuResource::GrGpuResource(GrGpu* gpu)
bsalomon7775c852014-12-30 12:50:52 -080023 : fGpu(gpu)
bsalomon69ed47f2014-11-12 11:13:39 -080024 , fGpuMemorySize(kInvalidGpuMemorySize)
kkinnunen2e6055b2016-04-22 01:48:29 -070025 , fBudgeted(SkBudgeted::kNo)
26 , fRefsWrappedObjects(false)
bsalomon84c8e622014-11-17 09:33:27 -080027 , fUniqueID(CreateUniqueID()) {
bsalomon9f2d1572015-02-17 11:47:40 -080028 SkDEBUGCODE(fCacheArrayIndex = -1);
bsalomon16961262014-08-26 14:01:07 -070029}
30
kkinnunen2e6055b2016-04-22 01:48:29 -070031void GrGpuResource::registerWithCache(SkBudgeted budgeted) {
32 SkASSERT(fBudgeted == SkBudgeted::kNo);
33 fBudgeted = budgeted;
34 this->computeScratchKey(&fScratchKey);
35 get_resource_cache(fGpu)->resourceAccess().insertResource(this);
36}
37
38void GrGpuResource::registerWithCacheWrapped() {
39 SkASSERT(fBudgeted == SkBudgeted::kNo);
40 // Currently resources referencing wrapped objects are not budgeted.
41 fRefsWrappedObjects = true;
bsalomon0ea80f42015-02-11 10:49:59 -080042 get_resource_cache(fGpu)->resourceAccess().insertResource(this);
bsalomon@google.com8fe72472011-03-30 21:26:44 +000043}
44
bsalomon6d3fe022014-07-25 08:35:45 -070045GrGpuResource::~GrGpuResource() {
bsalomon12299ab2014-11-14 13:33:09 -080046 // The cache should have released or destroyed this resource.
commit-bot@chromium.org089a7802014-05-02 21:38:22 +000047 SkASSERT(this->wasDestroyed());
bsalomon@google.com76b7fcc2012-04-27 17:24:09 +000048}
49
halcanary9d524f22016-03-29 09:03:52 -070050void GrGpuResource::release() {
bsalomon12299ab2014-11-14 13:33:09 -080051 SkASSERT(fGpu);
52 this->onRelease();
bsalomon0ea80f42015-02-11 10:49:59 -080053 get_resource_cache(fGpu)->resourceAccess().removeResource(this);
halcanary96fcdcc2015-08-27 07:41:13 -070054 fGpu = nullptr;
bsalomon12299ab2014-11-14 13:33:09 -080055 fGpuMemorySize = 0;
bsalomon@google.com8fe72472011-03-30 21:26:44 +000056}
57
bsalomon6d3fe022014-07-25 08:35:45 -070058void GrGpuResource::abandon() {
bsalomonc6363ef2015-09-24 07:07:40 -070059 if (this->wasDestroyed()) {
60 return;
61 }
bsalomon12299ab2014-11-14 13:33:09 -080062 SkASSERT(fGpu);
63 this->onAbandon();
bsalomon0ea80f42015-02-11 10:49:59 -080064 get_resource_cache(fGpu)->resourceAccess().removeResource(this);
halcanary96fcdcc2015-08-27 07:41:13 -070065 fGpu = nullptr;
bsalomon12299ab2014-11-14 13:33:09 -080066 fGpuMemorySize = 0;
bsalomon@google.com8fe72472011-03-30 21:26:44 +000067}
bsalomon@google.comf7b5c1e2011-11-15 19:42:07 +000068
ericrk0a5fa482015-09-15 14:16:10 -070069void GrGpuResource::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
70 // Dump resource as "skia/gpu_resources/resource_#".
71 SkString dumpName("skia/gpu_resources/resource_");
robertphillips8abb3702016-08-31 14:04:06 -070072 dumpName.appendS32(this->uniqueID());
ericrk0a5fa482015-09-15 14:16:10 -070073
74 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "size", "bytes", this->gpuMemorySize());
75
76 if (this->isPurgeable()) {
77 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "purgeable_size", "bytes",
78 this->gpuMemorySize());
79 }
80
81 // Call setMemoryBacking to allow sub-classes with implementation specific backings (such as GL
82 // objects) to provide additional information.
83 this->setMemoryBacking(traceMemoryDump, dumpName);
84}
85
bsalomon6d3fe022014-07-25 08:35:45 -070086const GrContext* GrGpuResource::getContext() const {
bsalomon49f085d2014-09-05 13:34:00 -070087 if (fGpu) {
bsalomon@google.comf7b5c1e2011-11-15 19:42:07 +000088 return fGpu->getContext();
89 } else {
halcanary96fcdcc2015-08-27 07:41:13 -070090 return nullptr;
bsalomon@google.comf7b5c1e2011-11-15 19:42:07 +000091 }
92}
93
bsalomon6d3fe022014-07-25 08:35:45 -070094GrContext* GrGpuResource::getContext() {
bsalomon49f085d2014-09-05 13:34:00 -070095 if (fGpu) {
bsalomon@google.comf7b5c1e2011-11-15 19:42:07 +000096 return fGpu->getContext();
97 } else {
halcanary96fcdcc2015-08-27 07:41:13 -070098 return nullptr;
bsalomon@google.comf7b5c1e2011-11-15 19:42:07 +000099 }
100}
bsalomonc44be0e2014-07-25 07:32:33 -0700101
bsalomon71cb0c22014-11-14 12:10:14 -0800102void GrGpuResource::didChangeGpuMemorySize() const {
103 if (this->wasDestroyed()) {
104 return;
105 }
106
107 size_t oldSize = fGpuMemorySize;
108 SkASSERT(kInvalidGpuMemorySize != oldSize);
109 fGpuMemorySize = kInvalidGpuMemorySize;
bsalomon0ea80f42015-02-11 10:49:59 -0800110 get_resource_cache(fGpu)->resourceAccess().didChangeGpuMemorySize(this, oldSize);
bsalomon71cb0c22014-11-14 12:10:14 -0800111}
112
bsalomon8718aaf2015-02-19 07:24:21 -0800113void GrGpuResource::removeUniqueKey() {
bsalomonc6363ef2015-09-24 07:07:40 -0700114 if (this->wasDestroyed()) {
115 return;
116 }
bsalomon8718aaf2015-02-19 07:24:21 -0800117 SkASSERT(fUniqueKey.isValid());
bsalomonf99e9612015-02-19 08:24:16 -0800118 get_resource_cache(fGpu)->resourceAccess().removeUniqueKey(this);
bsalomon23e619c2015-02-06 11:54:28 -0800119}
120
bsalomonf99e9612015-02-19 08:24:16 -0800121void GrGpuResource::setUniqueKey(const GrUniqueKey& key) {
bsalomon6d4488c2014-11-11 07:27:16 -0800122 SkASSERT(this->internalHasRef());
bsalomon23e619c2015-02-06 11:54:28 -0800123 SkASSERT(key.isValid());
bsalomondace19e2014-11-17 07:34:06 -0800124
bsalomon8718aaf2015-02-19 07:24:21 -0800125 // Wrapped and uncached resources can never have a unique key.
bsalomon5ec26ae2016-02-25 08:33:02 -0800126 if (SkBudgeted::kNo == this->resourcePriv().isBudgeted()) {
bsalomonf99e9612015-02-19 08:24:16 -0800127 return;
bsalomondace19e2014-11-17 07:34:06 -0800128 }
bsalomon84c8e622014-11-17 09:33:27 -0800129
bsalomonf99e9612015-02-19 08:24:16 -0800130 if (this->wasDestroyed()) {
131 return;
bsalomon8b79d232014-11-10 10:19:06 -0800132 }
133
bsalomonf99e9612015-02-19 08:24:16 -0800134 get_resource_cache(fGpu)->resourceAccess().changeUniqueKey(this, key);
bsalomon8b79d232014-11-10 10:19:06 -0800135}
136
bsalomon3f324322015-04-08 11:01:54 -0700137void GrGpuResource::notifyAllCntsAreZero(CntType lastCntTypeToReachZero) const {
bsalomon12299ab2014-11-14 13:33:09 -0800138 if (this->wasDestroyed()) {
139 // We've already been removed from the cache. Goodbye cruel world!
halcanary385fe4d2015-08-26 13:07:48 -0700140 delete this;
bsalomon3f324322015-04-08 11:01:54 -0700141 return;
bsalomonbcf0a522014-10-08 08:40:09 -0700142 }
bsalomon3f324322015-04-08 11:01:54 -0700143
144 // We should have already handled this fully in notifyRefCntIsZero().
145 SkASSERT(kRef_CntType != lastCntTypeToReachZero);
146
147 GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this);
148 static const uint32_t kFlag =
149 GrResourceCache::ResourceAccess::kAllCntsReachedZero_RefNotificationFlag;
150 get_resource_cache(fGpu)->resourceAccess().notifyCntReachedZero(mutableThis, kFlag);
151}
152
153bool GrGpuResource::notifyRefCountIsZero() const {
154 if (this->wasDestroyed()) {
155 // handle this in notifyAllCntsAreZero().
156 return true;
157 }
158
159 GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this);
160 uint32_t flags =
161 GrResourceCache::ResourceAccess::kRefCntReachedZero_RefNotificationFlag;
162 if (!this->internalHasPendingIO()) {
163 flags |= GrResourceCache::ResourceAccess::kAllCntsReachedZero_RefNotificationFlag;
164 }
165 get_resource_cache(fGpu)->resourceAccess().notifyCntReachedZero(mutableThis, flags);
166
167 // There is no need to call our notifyAllCntsAreZero function at this point since we already
168 // told the cache about the state of cnts.
169 return false;
bsalomonbcf0a522014-10-08 08:40:09 -0700170}
171
bsalomon10e23ca2014-11-25 05:52:06 -0800172void GrGpuResource::removeScratchKey() {
bsalomon7775c852014-12-30 12:50:52 -0800173 if (!this->wasDestroyed() && fScratchKey.isValid()) {
bsalomon0ea80f42015-02-11 10:49:59 -0800174 get_resource_cache(fGpu)->resourceAccess().willRemoveScratchKey(this);
bsalomon7775c852014-12-30 12:50:52 -0800175 fScratchKey.reset();
bsalomon10e23ca2014-11-25 05:52:06 -0800176 }
177}
178
bsalomonafe30052015-01-16 07:32:33 -0800179void GrGpuResource::makeBudgeted() {
kkinnunen2e6055b2016-04-22 01:48:29 -0700180 if (!this->wasDestroyed() && SkBudgeted::kNo == fBudgeted) {
181 // Currently resources referencing wrapped objects are not budgeted.
182 SkASSERT(!fRefsWrappedObjects);
183 fBudgeted = SkBudgeted::kYes;
bsalomon0ea80f42015-02-11 10:49:59 -0800184 get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this);
bsalomonafe30052015-01-16 07:32:33 -0800185 }
186}
187
bsalomonc2f35b72015-01-23 07:19:22 -0800188void GrGpuResource::makeUnbudgeted() {
kkinnunen2e6055b2016-04-22 01:48:29 -0700189 if (!this->wasDestroyed() && SkBudgeted::kYes == fBudgeted &&
bsalomonc6363ef2015-09-24 07:07:40 -0700190 !fUniqueKey.isValid()) {
kkinnunen2e6055b2016-04-22 01:48:29 -0700191 fBudgeted = SkBudgeted::kNo;
bsalomon0ea80f42015-02-11 10:49:59 -0800192 get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this);
bsalomonc2f35b72015-01-23 07:19:22 -0800193 }
194}
195
bsalomon6d3fe022014-07-25 08:35:45 -0700196uint32_t GrGpuResource::CreateUniqueID() {
bsalomonc44be0e2014-07-25 07:32:33 -0700197 static int32_t gUniqueID = SK_InvalidUniqueID;
198 uint32_t id;
199 do {
200 id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
201 } while (id == SK_InvalidUniqueID);
202 return id;
203}