1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
gpu / command_buffer / service / service_discardable_manager.h [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GPU_COMMAND_BUFFER_SERVICE_SERVICE_DISCARDABLE_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_SERVICE_DISCARDABLE_MANAGER_H_
#include <vector>
#include "base/containers/lru_cache.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/raw_ptr.h"
#include "base/trace_event/memory_dump_provider.h"
#include "gpu/command_buffer/common/discardable_handle.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/gpu_gles2_export.h"
namespace gpu {
struct GpuPreferences;
namespace gles2 {
class TextureManager;
class TextureRef;
}
GPU_GLES2_EXPORT size_t DiscardableCacheSizeLimit();
GPU_GLES2_EXPORT size_t DiscardableCacheSizeLimitForPressure(
size_t base_cache_limit,
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
class GPU_GLES2_EXPORT ServiceDiscardableManager
: public base::trace_event::MemoryDumpProvider {
public:
explicit ServiceDiscardableManager(const GpuPreferences& preferences);
ServiceDiscardableManager(const ServiceDiscardableManager&) = delete;
ServiceDiscardableManager& operator=(const ServiceDiscardableManager&) =
delete;
~ServiceDiscardableManager() override;
// base::trace_event::MemoryDumpProvider implementation.
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
void InsertLockedTexture(uint32_t texture_id,
size_t texture_size,
gles2::TextureManager* texture_manager,
ServiceDiscardableHandle handle);
// Unlocks the indicated texture. If *|texture_to_unbind| is not nullptr,
// ServiceDiscardableManager has taken ownership of the given texture, and
// it is the callers responsibility to unbind it from any other objects.
// Returns false if the given texture_id has not been initialized for use
// with discardable.
bool UnlockTexture(uint32_t texture_id,
gles2::TextureManager* texture_manager,
gles2::TextureRef** texture_to_unbind);
// Locks the indicated texture, allowing it to be used in future GL commands.
// Returns false if the given texture_id has not been initialized for use
// with discardable.
bool LockTexture(uint32_t texture_id, gles2::TextureManager* texture_manager);
// Returns all unlocked texture refs to the texture_manager for deletion.
// After this point, this class will have no references to the given
// |texture_manager|.
void OnTextureManagerDestruction(gles2::TextureManager* texture_manager);
// Called when a texture is deleted, to clean up state.
void OnTextureDeleted(uint32_t texture_id,
gles2::TextureManager* texture_manager);
// Called by the TextureManager when a texture's size changes.
void OnTextureSizeChanged(uint32_t texture_id,
gles2::TextureManager* texture_manager,
size_t new_size);
// Called when all contexts with cached textures in this manager are lost.
void OnContextLost();
// Test only functions:
size_t NumCacheEntriesForTesting() const { return entries_.size(); }
bool IsEntryLockedForTesting(uint32_t texture_id,
gles2::TextureManager* texture_manager) const;
size_t TotalSizeForTesting() const { return total_size_; }
gles2::TextureRef* UnlockedTextureRefForTesting(
uint32_t texture_id,
gles2::TextureManager* texture_manager) const;
void SetCacheSizeLimitForTesting(size_t cache_size_limit) {
cache_size_limit_ = cache_size_limit;
}
void HandleMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
private:
void EnforceCacheSizeLimit(size_t limit);
struct GpuDiscardableEntry {
public:
GpuDiscardableEntry(ServiceDiscardableHandle handle, size_t size);
GpuDiscardableEntry(const GpuDiscardableEntry& other);
GpuDiscardableEntry(GpuDiscardableEntry&& other);
~GpuDiscardableEntry();
ServiceDiscardableHandle handle;
scoped_refptr<gles2::TextureRef> unlocked_texture_ref;
// The current ref count of this object with regards to command buffer
// execution. May be out of sync with the handle's refcount, as the handle
// can be locked out of band with the command buffer.
uint32_t service_ref_count_ = 1;
size_t size;
};
struct GpuDiscardableEntryKey {
uint32_t texture_id;
raw_ptr<gles2::TextureManager> texture_manager;
};
struct GpuDiscardableEntryKeyCompare {
bool operator()(const GpuDiscardableEntryKey& lhs,
const GpuDiscardableEntryKey& rhs) const {
return std::tie(lhs.texture_manager, lhs.texture_id) <
std::tie(rhs.texture_manager, rhs.texture_id);
}
};
using EntryCache = base::LRUCache<GpuDiscardableEntryKey,
GpuDiscardableEntry,
GpuDiscardableEntryKeyCompare>;
EntryCache entries_;
// Total size of all |entries_|. The same as summing
// GpuDiscardableEntry::size for each entry.
size_t total_size_ = 0;
// The limit above which the cache will start evicting resources.
size_t cache_size_limit_ = 0;
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_SERVICE_DISCARDABLE_MANAGER_H_