Skip to content

Commit 4061859

Browse files
committed
Implement functions for managing Graphite memory budget.
The main fix in this change is to make sure we are actually setting the memory budget when using Graphite. Previously we were using the default Graphite budget which was much higher than what we would normally want. Additionally, this implemented the purgeUnlcokedScratchResources() call. This is called when switching between protected and non-protected contexts. Finally this fixed dumpMemoryStatistics to also dump memory held by the Recorder. Bug: b/293371537, b/385380555 Test: manual comparison of memory metric Flag: com.android.graphics.surfaceflinger.flags.graphite_renderengine Change-Id: I02befd7caa0b9eeb90316a082425a9905d91c57b
1 parent d77e913 commit 4061859

2 files changed

Lines changed: 35 additions & 9 deletions

File tree

libs/renderengine/skia/compat/GraphiteGpuContext.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,40 @@ bool GraphiteGpuContext::isAbandonedOrDeviceLost() {
110110
return mContext->isDeviceLost();
111111
}
112112

113+
void GraphiteGpuContext::setResourceCacheLimit(size_t maxResourceBytes) {
114+
// Graphite has a separate budget for its Context and its Recorder. For now the majority of
115+
// memory that Graphite will allocate will be on the Recorder and minimal amount on the Context.
116+
// The main allocations on the Context are MSAA buffers (not often, if ever used in
117+
// RenderEngine) and stencil buffers. However, both of these should be "memoryless" in Vulkan on
118+
// tiled GPUs, so they don't actually use GPU memory. However, in Vulkan there are scenarios
119+
// where Vulkan could end up using real memory for them. Skia will regularly query the device to
120+
// get the real memory usage and update the budgeted appropriately. Though for all real usage
121+
// patterns we don't expect to ever trigger the device to allocate real memory.
122+
//
123+
// Therefore, we set the full maxResourceBytes budget on the Recorder. However, in the rare
124+
// chance that the devcies does allocate real memory we don't want to immediately kill device
125+
// performance by constantly trashing allocations on the Context. Thus we set the Context's
126+
// budget to be 50% of the total budget to make sure we allow the MSAA or Stencil buffers to be
127+
// allocated in Skia and not immediately discarded. But even with this extra 50% budget, as
128+
// described above, this shouldn't result in actual GPU memory usage.
129+
//
130+
// TODO: We will need to revise this strategy for GLES which does not have the same memoryless
131+
// textures.
132+
// TODO: Work in Graphite has started to move a lot more of its scratch resources to be owned
133+
// by the Context and not on Recorders. This will mean most memory is actually owned by the
134+
// Context and thus the budgeting here will need to be updated.
135+
mContext->setMaxBudgetedBytes(maxResourceBytes / 2);
136+
mRecorder->setMaxBudgetedBytes(maxResourceBytes);
137+
}
138+
139+
void GraphiteGpuContext::purgeUnlockedScratchResources() {
140+
mContext->freeGpuResources();
141+
mRecorder->freeGpuResources();
142+
}
143+
113144
void GraphiteGpuContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
114145
mContext->dumpMemoryStatistics(traceMemoryDump);
146+
mRecorder->dumpMemoryStatistics(traceMemoryDump);
115147
}
116148

117149
} // namespace android::renderengine::skia

libs/renderengine/skia/compat/GraphiteGpuContext.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,10 @@ class GraphiteGpuContext : public SkiaGpuContext {
3939
size_t getMaxRenderTargetSize() const override;
4040
size_t getMaxTextureSize() const override;
4141
bool isAbandonedOrDeviceLost() override;
42-
// No-op (large resources like textures, surfaces, images, etc. created by clients don't count
43-
// towards Graphite's internal caching budgets, so adjusting its limits based on display change
44-
// events should be unnecessary. Additionally, Graphite doesn't expose many cache tweaking
45-
// functions yet, as its design may evolve.)
46-
void setResourceCacheLimit(size_t maxResourceBytes) override{};
4742

48-
// TODO: b/293371537 - Triple-check and validate that no cleanup is necessary when switching
49-
// contexts.
50-
// No-op (unnecessary during context switch for Graphite's client-budgeted memory model).
51-
void purgeUnlockedScratchResources() override{};
43+
void setResourceCacheLimit(size_t maxResourceBytes) override;
44+
void purgeUnlockedScratchResources() override;
45+
5246
// No-op (only applicable to GL).
5347
void resetContextIfApplicable() override{};
5448

0 commit comments

Comments
 (0)