• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }
23 
24 namespace gl
25 {
26 class Buffer;
27 struct Caps;
28 class Context;
29 class Sync;
30 class Framebuffer;
31 struct Limitations;
32 class MemoryObject;
33 class Path;
34 class Program;
35 class ProgramPipeline;
36 class Renderbuffer;
37 class Sampler;
38 class Shader;
39 class Semaphore;
40 class Texture;
41 
42 template <typename HandleAllocatorType>
43 class ResourceManagerBase : angle::NonCopyable
44 {
45   public:
46     ResourceManagerBase();
47 
48     void addRef();
49     void release(const Context *context);
50 
51   protected:
52     virtual void reset(const Context *context) = 0;
~ResourceManagerBase()53     virtual ~ResourceManagerBase() {}
54 
55     HandleAllocatorType mHandleAllocator;
56 
57   private:
58     size_t mRefCount;
59 };
60 
61 template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType>
62 class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType>
63 {
64   public:
TypedResourceManager()65     TypedResourceManager() {}
66 
67     void deleteObject(const Context *context, IDType handle);
isHandleGenerated(IDType handle)68     ANGLE_INLINE bool isHandleGenerated(IDType handle) const
69     {
70         // Zero is always assumed to have been generated implicitly.
71         return GetIDValue(handle) == 0 || mObjectMap.contains(handle);
72     }
73 
begin()74     typename ResourceMap<ResourceType, IDType>::Iterator begin() const
75     {
76         return mObjectMap.begin();
77     }
end()78     typename ResourceMap<ResourceType, IDType>::Iterator end() const { return mObjectMap.end(); }
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, HandleAllocator, 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:
~BufferManager()141     ~BufferManager() override {}
142 };
143 
144 class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
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 only.
getShadersForCapture()164     const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; }
getProgramsForCapture()165     const ResourceMap<Program, ShaderProgramID> &getProgramsForCapture() const { return mPrograms; }
166 
167   protected:
168     ~ShaderProgramManager() override;
169 
170   private:
171     template <typename ObjectType, typename IDType>
172     void deleteObject(const Context *context,
173                       ResourceMap<ObjectType, IDType> *objectMap,
174                       IDType id);
175 
176     void reset(const Context *context) override;
177 
178     ResourceMap<Shader, ShaderProgramID> mShaders;
179     ResourceMap<Program, ShaderProgramID> mPrograms;
180 };
181 
182 class TextureManager
183     : public TypedResourceManager<Texture, HandleAllocator, TextureManager, TextureID>
184 {
185   public:
186     TextureID createTexture();
getTexture(TextureID handle)187     ANGLE_INLINE Texture *getTexture(TextureID handle) const
188     {
189         ASSERT(mObjectMap.query({0}) == nullptr);
190         return mObjectMap.query(handle);
191     }
192 
193     void signalAllTexturesDirty() const;
194 
checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)195     ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory,
196                                                  TextureID handle,
197                                                  TextureType type)
198     {
199         return checkObjectAllocation(factory, handle, type);
200     }
201 
202     static Texture *AllocateNewObject(rx::GLImplFactory *factory,
203                                       TextureID handle,
204                                       TextureType type);
205     static void DeleteObject(const Context *context, Texture *texture);
206 
207     void enableHandleAllocatorLogging();
208 
209   protected:
~TextureManager()210     ~TextureManager() override {}
211 };
212 
213 class RenderbufferManager : public TypedResourceManager<Renderbuffer,
214                                                         HandleAllocator,
215                                                         RenderbufferManager,
216                                                         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:
~RenderbufferManager()231     ~RenderbufferManager() override {}
232 };
233 
234 class SamplerManager
235     : public TypedResourceManager<Sampler, HandleAllocator, SamplerManager, SamplerID>
236 {
237   public:
238     SamplerID createSampler();
239     Sampler *getSampler(SamplerID handle) const;
240     bool isSampler(SamplerID sampler) const;
241 
checkSamplerAllocation(rx::GLImplFactory * factory,SamplerID handle)242     Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle)
243     {
244         return checkObjectAllocation(factory, handle);
245     }
246 
247     static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle);
248     static void DeleteObject(const Context *context, Sampler *sampler);
249 
250   protected:
~SamplerManager()251     ~SamplerManager() override {}
252 };
253 
254 class SyncManager : public TypedResourceManager<Sync, HandleAllocator, SyncManager, GLuint>
255 {
256   public:
257     GLuint createSync(rx::GLImplFactory *factory);
258     Sync *getSync(GLuint handle) const;
259 
260     static void DeleteObject(const Context *context, Sync *sync);
261 
262   protected:
~SyncManager()263     ~SyncManager() override {}
264 };
265 
266 class FramebufferManager
267     : public TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager, FramebufferID>
268 {
269   public:
270     FramebufferID createFramebuffer();
271     Framebuffer *getFramebuffer(FramebufferID handle) const;
272     void setDefaultFramebuffer(Framebuffer *framebuffer);
273 
274     void invalidateFramebufferCompletenessCache() const;
275 
checkFramebufferAllocation(rx::GLImplFactory * factory,const Caps & caps,FramebufferID handle,ContextID owningContextID)276     Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
277                                             const Caps &caps,
278                                             FramebufferID handle,
279                                             ContextID owningContextID)
280     {
281         return checkObjectAllocation<const Caps &>(factory, handle, caps, owningContextID);
282     }
283 
284     static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
285                                           FramebufferID handle,
286                                           const Caps &caps,
287                                           ContextID owningContextID);
288     static void DeleteObject(const Context *context, Framebuffer *framebuffer);
289 
290   protected:
~FramebufferManager()291     ~FramebufferManager() override {}
292 };
293 
294 class ProgramPipelineManager : public TypedResourceManager<ProgramPipeline,
295                                                            HandleAllocator,
296                                                            ProgramPipelineManager,
297                                                            ProgramPipelineID>
298 {
299   public:
300     ProgramPipelineID createProgramPipeline();
301     ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const;
302 
checkProgramPipelineAllocation(rx::GLImplFactory * factory,ProgramPipelineID handle)303     ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory,
304                                                     ProgramPipelineID handle)
305     {
306         return checkObjectAllocation(factory, handle);
307     }
308 
309     static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle);
310     static void DeleteObject(const Context *context, ProgramPipeline *pipeline);
311 
312   protected:
~ProgramPipelineManager()313     ~ProgramPipelineManager() override {}
314 };
315 
316 class MemoryObjectManager : public ResourceManagerBase<HandleAllocator>
317 {
318   public:
319     MemoryObjectManager();
320 
321     MemoryObjectID createMemoryObject(rx::GLImplFactory *factory);
322     void deleteMemoryObject(const Context *context, MemoryObjectID handle);
323     MemoryObject *getMemoryObject(MemoryObjectID handle) const;
324 
325   protected:
326     ~MemoryObjectManager() override;
327 
328   private:
329     void reset(const Context *context) override;
330 
331     ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects;
332 };
333 
334 class SemaphoreManager : public ResourceManagerBase<HandleAllocator>
335 {
336   public:
337     SemaphoreManager();
338 
339     SemaphoreID createSemaphore(rx::GLImplFactory *factory);
340     void deleteSemaphore(const Context *context, SemaphoreID handle);
341     Semaphore *getSemaphore(SemaphoreID handle) const;
342 
343   protected:
344     ~SemaphoreManager() override;
345 
346   private:
347     void reset(const Context *context) override;
348 
349     ResourceMap<Semaphore, SemaphoreID> mSemaphores;
350 };
351 }  // namespace gl
352 
353 #endif  // LIBANGLE_RESOURCEMANAGER_H_
354