xref: /aosp_15_r20/external/angle/src/libANGLE/ResourceManager.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // ResourceManager.h : Defines the ResourceManager classes, which handle allocation and lifetime of
8 // GL objects.
9 
10 #ifndef LIBANGLE_RESOURCEMANAGER_H_
11 #define LIBANGLE_RESOURCEMANAGER_H_
12 
13 #include "angle_gl.h"
14 #include "common/angleutils.h"
15 #include "libANGLE/Error.h"
16 #include "libANGLE/HandleAllocator.h"
17 #include "libANGLE/ResourceMap.h"
18 
19 namespace rx
20 {
21 class GLImplFactory;
22 }  // namespace rx
23 
24 namespace egl
25 {
26 class ShareGroup;
27 }  // namespace egl
28 
29 namespace gl
30 {
31 class Buffer;
32 struct Caps;
33 class Context;
34 class Framebuffer;
35 struct Limitations;
36 class MemoryObject;
37 class Path;
38 class Program;
39 class ProgramPipeline;
40 class Renderbuffer;
41 class Sampler;
42 class Semaphore;
43 class Shader;
44 class Sync;
45 class Texture;
46 
47 class ResourceManagerBase : angle::NonCopyable
48 {
49   public:
50     ResourceManagerBase();
51 
52     void addRef();
53     void release(const Context *context);
54 
55   protected:
56     virtual void reset(const Context *context) = 0;
57     virtual ~ResourceManagerBase();
58 
59     HandleAllocator mHandleAllocator;
60 
61   private:
62     size_t mRefCount;
63 };
64 
65 template <typename ResourceType, typename ImplT, typename IDType>
66 class TypedResourceManager : public ResourceManagerBase
67 {
68   public:
TypedResourceManager()69     TypedResourceManager() {}
70 
71     void deleteObject(const Context *context, IDType handle);
isHandleGenerated(IDType handle)72     ANGLE_INLINE bool isHandleGenerated(IDType handle) const
73     {
74         // Zero is always assumed to have been generated implicitly.
75         return GetIDValue(handle) == 0 || mObjectMap.contains(handle);
76     }
77 
getResourcesForCapture()78     const ResourceMap<ResourceType, IDType> &getResourcesForCapture() const { return mObjectMap; }
79 
80   protected:
81     ~TypedResourceManager() override;
82 
83     // Inlined in the header for performance.
84     template <typename... ArgTypes>
checkObjectAllocation(rx::GLImplFactory * factory,IDType handle,ArgTypes...args)85     ANGLE_INLINE ResourceType *checkObjectAllocation(rx::GLImplFactory *factory,
86                                                      IDType handle,
87                                                      ArgTypes... args)
88     {
89         ResourceType *value = mObjectMap.query(handle);
90         if (value)
91         {
92             return value;
93         }
94 
95         if (GetIDValue(handle) == 0)
96         {
97             return nullptr;
98         }
99 
100         return checkObjectAllocationImpl(factory, handle, args...);
101     }
102 
103     void reset(const Context *context) override;
104 
105     ResourceMap<ResourceType, IDType> mObjectMap;
106 
107   private:
108     template <typename... ArgTypes>
checkObjectAllocationImpl(rx::GLImplFactory * factory,IDType handle,ArgTypes...args)109     ResourceType *checkObjectAllocationImpl(rx::GLImplFactory *factory,
110                                             IDType handle,
111                                             ArgTypes... args)
112     {
113         ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...);
114 
115         if (!mObjectMap.contains(handle))
116         {
117             this->mHandleAllocator.reserve(GetIDValue(handle));
118         }
119         mObjectMap.assign(handle, object);
120 
121         return object;
122     }
123 };
124 
125 class BufferManager : public TypedResourceManager<Buffer, BufferManager, BufferID>
126 {
127   public:
128     BufferID createBuffer();
129     Buffer *getBuffer(BufferID handle) const;
130 
checkBufferAllocation(rx::GLImplFactory * factory,BufferID handle)131     ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle)
132     {
133         return checkObjectAllocation(factory, handle);
134     }
135 
136     // TODO(jmadill): Investigate design which doesn't expose these methods publicly.
137     static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle);
138     static void DeleteObject(const Context *context, Buffer *buffer);
139 
140   protected:
141     ~BufferManager() override;
142 };
143 
144 class ShaderProgramManager : public ResourceManagerBase
145 {
146   public:
147     ShaderProgramManager();
148 
149     ShaderProgramID createShader(rx::GLImplFactory *factory,
150                                  const Limitations &rendererLimitations,
151                                  ShaderType type);
152     void deleteShader(const Context *context, ShaderProgramID shader);
153     Shader *getShader(ShaderProgramID handle) const;
154 
155     ShaderProgramID createProgram(rx::GLImplFactory *factory);
156     void deleteProgram(const Context *context, ShaderProgramID program);
157 
getProgram(ShaderProgramID handle)158     ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const
159     {
160         return mPrograms.query(handle);
161     }
162 
163     // For capture and performance counters only.
getShadersForCapture()164     const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; }
getProgramsForCaptureAndPerf()165     const ResourceMap<Program, ShaderProgramID> &getProgramsForCaptureAndPerf() const
166     {
167         return mPrograms;
168     }
169 
170   protected:
171     ~ShaderProgramManager() override;
172 
173   private:
174     template <typename ObjectType, typename IDType>
175     void deleteObject(const Context *context,
176                       ResourceMap<ObjectType, IDType> *objectMap,
177                       IDType id);
178 
179     void reset(const Context *context) override;
180 
181     ResourceMap<Shader, ShaderProgramID> mShaders;
182     ResourceMap<Program, ShaderProgramID> mPrograms;
183 };
184 
185 class TextureManager : public TypedResourceManager<Texture, TextureManager, TextureID>
186 {
187   public:
188     TextureID createTexture();
getTexture(TextureID handle)189     ANGLE_INLINE Texture *getTexture(TextureID handle) const
190     {
191         ASSERT(mObjectMap.query({0}) == nullptr);
192         return mObjectMap.query(handle);
193     }
194 
195     void signalAllTexturesDirty() const;
196 
checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)197     ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory,
198                                                  TextureID handle,
199                                                  TextureType type)
200     {
201         return checkObjectAllocation(factory, handle, type);
202     }
203 
204     static Texture *AllocateNewObject(rx::GLImplFactory *factory,
205                                       TextureID handle,
206                                       TextureType type);
207     static void DeleteObject(const Context *context, Texture *texture);
208 
209     void enableHandleAllocatorLogging();
210 
211   protected:
212     ~TextureManager() override;
213 };
214 
215 class RenderbufferManager
216     : public TypedResourceManager<Renderbuffer, RenderbufferManager, RenderbufferID>
217 {
218   public:
219     RenderbufferID createRenderbuffer();
220     Renderbuffer *getRenderbuffer(RenderbufferID handle) const;
221 
checkRenderbufferAllocation(rx::GLImplFactory * factory,RenderbufferID handle)222     Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle)
223     {
224         return checkObjectAllocation(factory, handle);
225     }
226 
227     static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle);
228     static void DeleteObject(const Context *context, Renderbuffer *renderbuffer);
229 
230   protected:
231     ~RenderbufferManager() override;
232 };
233 
234 class SamplerManager : public TypedResourceManager<Sampler, SamplerManager, SamplerID>
235 {
236   public:
237     SamplerID createSampler();
238     Sampler *getSampler(SamplerID handle) const;
239     bool isSampler(SamplerID sampler) const;
240 
checkSamplerAllocation(rx::GLImplFactory * factory,SamplerID handle)241     Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle)
242     {
243         return checkObjectAllocation(factory, handle);
244     }
245 
246     static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle);
247     static void DeleteObject(const Context *context, Sampler *sampler);
248 
249   protected:
250     ~SamplerManager() override;
251 };
252 
253 class SyncManager : public TypedResourceManager<Sync, SyncManager, SyncID>
254 {
255   public:
256     SyncID createSync(rx::GLImplFactory *factory);
257     Sync *getSync(SyncID handle) const;
258 
259     static void DeleteObject(const Context *context, Sync *sync);
260 
261   protected:
262     ~SyncManager() override;
263 };
264 
265 class FramebufferManager
266     : public TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID>
267 {
268   public:
269     FramebufferID createFramebuffer();
270     Framebuffer *getFramebuffer(FramebufferID handle) const;
271     void setDefaultFramebuffer(Framebuffer *framebuffer);
272     Framebuffer *getDefaultFramebuffer() const;
273 
274     void invalidateFramebufferCompletenessCache() const;
275 
checkFramebufferAllocation(rx::GLImplFactory * factory,const Context * context,FramebufferID handle)276     Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
277                                             const Context *context,
278                                             FramebufferID handle)
279     {
280         return checkObjectAllocation(factory, handle, context);
281     }
282 
283     static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
284                                           FramebufferID handle,
285                                           const Context *context);
286     static void DeleteObject(const Context *context, Framebuffer *framebuffer);
287 
288   protected:
289     ~FramebufferManager() override;
290 };
291 
292 class ProgramPipelineManager
293     : public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID>
294 {
295   public:
296     ProgramPipelineID createProgramPipeline();
297     ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const;
298 
checkProgramPipelineAllocation(rx::GLImplFactory * factory,ProgramPipelineID handle)299     ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory,
300                                                     ProgramPipelineID handle)
301     {
302         return checkObjectAllocation(factory, handle);
303     }
304 
305     static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle);
306     static void DeleteObject(const Context *context, ProgramPipeline *pipeline);
307 
308   protected:
309     ~ProgramPipelineManager() override;
310 };
311 
312 class MemoryObjectManager : public ResourceManagerBase
313 {
314   public:
315     MemoryObjectManager();
316 
317     MemoryObjectID createMemoryObject(rx::GLImplFactory *factory);
318     void deleteMemoryObject(const Context *context, MemoryObjectID handle);
319     MemoryObject *getMemoryObject(MemoryObjectID handle) const;
320 
321   protected:
322     ~MemoryObjectManager() override;
323 
324   private:
325     void reset(const Context *context) override;
326 
327     ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects;
328 };
329 
330 class SemaphoreManager : public ResourceManagerBase
331 {
332   public:
333     SemaphoreManager();
334 
335     SemaphoreID createSemaphore(rx::GLImplFactory *factory);
336     void deleteSemaphore(const Context *context, SemaphoreID handle);
337     Semaphore *getSemaphore(SemaphoreID handle) const;
338 
339   protected:
340     ~SemaphoreManager() override;
341 
342   private:
343     void reset(const Context *context) override;
344 
345     ResourceMap<Semaphore, SemaphoreID> mSemaphores;
346 };
347 }  // namespace gl
348 
349 #endif  // LIBANGLE_RESOURCEMANAGER_H_
350