Flutter Engine
The Flutter Engine
Resource.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
12
13namespace skgpu::graphite {
14
15namespace {
16uint32_t create_unique_id() {
17 static std::atomic<uint32_t> nextID{1};
18 uint32_t id;
19 do {
20 id = nextID.fetch_add(1, std::memory_order_relaxed);
21 } while (id == SK_InvalidUniqueID);
22 return id;
23}
24} // namespace anonymous
25
26Resource::Resource(const SharedContext* sharedContext,
27 Ownership ownership,
28 skgpu::Budgeted budgeted,
29 size_t gpuMemorySize,
30 bool commandBufferRefsAsUsageRefs)
31 : fSharedContext(sharedContext)
32 , fUsageRefCnt(1)
33 , fCommandBufferRefCnt(0)
34 , fCacheRefCnt(0)
35 , fCommandBufferRefsAsUsageRefs(commandBufferRefsAsUsageRefs)
36 , fOwnership(ownership)
37 , fGpuMemorySize(gpuMemorySize)
38 , fBudgeted(budgeted)
39 , fUniqueID(create_unique_id()) {
40 // If we don't own the resource that must mean its wrapped in a client object. Thus we should
41 // not be budgeted
42 SkASSERT(fOwnership == Ownership::kOwned || fBudgeted == skgpu::Budgeted::kNo);
43}
44
46 // The cache should have released or destroyed this resource.
47 SkASSERT(this->wasDestroyed());
48}
49
50void Resource::registerWithCache(sk_sp<ResourceCache> returnCache) {
51 SkASSERT(!fReturnCache);
52 SkASSERT(returnCache);
53
54 fReturnCache = std::move(returnCache);
55}
56
57bool Resource::notifyARefIsZero(LastRemovedRef removedRef) const {
58 // No resource should have been destroyed if there was still any sort of ref on it.
59 SkASSERT(!this->wasDestroyed());
60
61 Resource* mutableThis = const_cast<Resource*>(this);
62
63 // TODO: We have not switched all resources to use the ResourceCache yet. Once we do we should
64 // be able to assert that we have an fCacheReturn.
65 // SkASSERT(fReturnCache);
66 if (removedRef != LastRemovedRef::kCache &&
67 fReturnCache &&
68 fReturnCache->returnResource(mutableThis, removedRef)) {
69 return false;
70 }
71
72 if (!this->hasAnyRefs()) {
73 return true;
74 }
75 return false;
76}
77
78void Resource::internalDispose() {
79 SkASSERT(fSharedContext);
80 this->invokeReleaseProc();
81 this->freeGpuData();
82 fSharedContext = nullptr;
83 // TODO: If we ever support freeing all the backend objects without deleting the object, we'll
84 // need to add a hasAnyRefs() check here.
85 delete this;
86}
87
88bool Resource::isPurgeable() const {
89 // For being purgeable we don't care if there are cacheRefs on the object since the cacheRef
90 // will always be greater than 1 since we add one on insert and don't remove that ref until
91 // the Resource is removed from the cache.
92 return !(this->hasUsageRef() || this->hasCommandBufferRef());
93}
94
96 if (this->ownership() == Ownership::kWrapped && !traceMemoryDump->shouldDumpWrappedObjects()) {
97 return;
98 }
99
100 if (this->budgeted() == skgpu::Budgeted::kNo &&
101 !traceMemoryDump->shouldDumpUnbudgetedObjects()) {
102 return;
103 }
104
105 size_t size = this->gpuMemorySize();
106
107 // Avoid dumping objects without a size (e.g. Samplers, pipelines, etc).
108 // TODO: Would a client ever actually want to see all of this? Wouldn't be hard to add it as an
109 // option.
110 if (size == 0) {
111 return;
112 }
113
114 SkString resourceName("skia/gpu_resources/resource_");
115 resourceName.appendU32(this->uniqueID().asUInt());
116
117 traceMemoryDump->dumpNumericValue(resourceName.c_str(), "size", "bytes", size);
118 traceMemoryDump->dumpStringValue(resourceName.c_str(), "type", this->getResourceType());
119 traceMemoryDump->dumpStringValue(resourceName.c_str(), "label", this->getLabel().c_str());
120 if (this->isPurgeable()) {
121 traceMemoryDump->dumpNumericValue(resourceName.c_str(), "purgeable_size", "bytes", size);
122 }
123 if (traceMemoryDump->shouldDumpWrappedObjects()) {
124 traceMemoryDump->dumpWrappedState(resourceName.c_str(),
125 this->ownership() == Ownership::kWrapped);
126 }
127 if (traceMemoryDump->shouldDumpUnbudgetedObjects()) {
128 traceMemoryDump->dumpBudgetedState(resourceName.c_str(),
129 this->budgeted() == skgpu::Budgeted::kYes);
130 }
131
132 this->onDumpMemoryStatistics(traceMemoryDump, resourceName.c_str());
133
134 // TODO: implement this to report real gpu id backing the resource. Will be virtual implemented
135 // by backend specific resource subclasses.
136 //this->setMemoryBacking(traceMemoryDump, resourceName);
137}
138
139} // namespace skgpu::graphite
140
#define SkASSERT(cond)
Definition: SkAssert.h:116
static constexpr uint32_t SK_InvalidUniqueID
Definition: SkTypes.h:196
void appendU32(uint32_t value)
Definition: SkString.h:210
const char * c_str() const
Definition: SkString.h:133
virtual bool shouldDumpUnbudgetedObjects() const
virtual void dumpWrappedState(const char *, bool)
virtual void dumpStringValue(const char *, const char *, const char *)
virtual void dumpBudgetedState(const char *, bool)
virtual bool shouldDumpWrappedObjects() const
virtual void dumpNumericValue(const char *dumpName, const char *valueName, const char *units, uint64_t value)=0
bool wasDestroyed() const
Definition: Resource.h:154
skgpu::Budgeted budgeted() const
Definition: Resource.h:100
virtual void invokeReleaseProc()
Definition: Resource.h:211
Resource(const Resource &)=delete
virtual void onDumpMemoryStatistics(SkTraceMemoryDump *traceMemoryDump, const char *dumpName) const
Definition: Resource.h:192
size_t gpuMemorySize() const
Definition: Resource.h:104
UniqueID uniqueID() const
Definition: Resource.h:123
Ownership ownership() const
Definition: Resource.h:98
virtual void freeGpuData()=0
void dumpMemoryStatistics(SkTraceMemoryDump *traceMemoryDump) const
Definition: Resource.cpp:95
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Budgeted
Definition: GpuTypes.h:35
const uintptr_t id