• 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/HandleRangeAllocator.h"
18 #include "libANGLE/ResourceMap.h"
19 
20 namespace rx
21 {
22 class GLImplFactory;
23 }
24 
25 namespace gl
26 {
27 class Buffer;
28 struct Caps;
29 class Context;
30 class Sync;
31 class Framebuffer;
32 struct Limitations;
33 class MemoryObject;
34 class Path;
35 class Program;
36 class ProgramPipeline;
37 class Renderbuffer;
38 class Sampler;
39 class Shader;
40 class Semaphore;
41 class Texture;
42 
43 template <typename HandleAllocatorType>
44 class ResourceManagerBase : angle::NonCopyable
45 {
46   public:
47     ResourceManagerBase();
48 
49     void addRef();
50     void release(const Context *context);
51 
52   protected:
53     virtual void reset(const Context *context) = 0;
~ResourceManagerBase()54     virtual ~ResourceManagerBase() {}
55 
56     HandleAllocatorType mHandleAllocator;
57 
58   private:
59     size_t mRefCount;
60 };
61 
62 template <typename ResourceType,
63           typename HandleAllocatorType,
64           typename ImplT,
65           typename IDType = GLuint>
66 class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType>
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 
78   protected:
79     ~TypedResourceManager() override;
80 
81     // Inlined in the header for performance.
82     template <typename... ArgTypes>
checkObjectAllocation(rx::GLImplFactory * factory,IDType handle,ArgTypes...args)83     ANGLE_INLINE ResourceType *checkObjectAllocation(rx::GLImplFactory *factory,
84                                                      IDType handle,
85                                                      ArgTypes... args)
86     {
87         ResourceType *value = mObjectMap.query(handle);
88         if (value)
89         {
90             return value;
91         }
92 
93         if (GetIDValue(handle) == 0)
94         {
95             return nullptr;
96         }
97 
98         return checkObjectAllocationImpl(factory, handle, args...);
99     }
100 
101     void reset(const Context *context) override;
102 
103     ResourceMap<ResourceType, IDType> mObjectMap;
104 
105   private:
106     template <typename... ArgTypes>
checkObjectAllocationImpl(rx::GLImplFactory * factory,IDType handle,ArgTypes...args)107     ResourceType *checkObjectAllocationImpl(rx::GLImplFactory *factory,
108                                             IDType handle,
109                                             ArgTypes... args)
110     {
111         ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...);
112 
113         if (!mObjectMap.contains(handle))
114         {
115             this->mHandleAllocator.reserve(GetIDValue(handle));
116         }
117         mObjectMap.assign(handle, object);
118 
119         return object;
120     }
121 };
122 
123 class BufferManager : public TypedResourceManager<Buffer, HandleAllocator, BufferManager, BufferID>
124 {
125   public:
126     BufferID createBuffer();
127     Buffer *getBuffer(BufferID handle) const;
128 
checkBufferAllocation(rx::GLImplFactory * factory,BufferID handle)129     ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle)
130     {
131         return checkObjectAllocation(factory, handle);
132     }
133 
134     // TODO(jmadill): Investigate design which doesn't expose these methods publicly.
135     static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle);
136     static void DeleteObject(const Context *context, Buffer *buffer);
137 
138   protected:
~BufferManager()139     ~BufferManager() override {}
140 };
141 
142 class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
143 {
144   public:
145     ShaderProgramManager();
146 
147     GLuint createShader(rx::GLImplFactory *factory,
148                         const Limitations &rendererLimitations,
149                         ShaderType type);
150     void deleteShader(const Context *context, GLuint shader);
151     Shader *getShader(GLuint handle) const;
152 
153     GLuint createProgram(rx::GLImplFactory *factory);
154     void deleteProgram(const Context *context, GLuint program);
155 
getProgram(GLuint handle)156     ANGLE_INLINE Program *getProgram(GLuint handle) const { return mPrograms.query(handle); }
157 
158   protected:
159     ~ShaderProgramManager() override;
160 
161   private:
162     template <typename ObjectType>
163     void deleteObject(const Context *context, ResourceMap<ObjectType> *objectMap, GLuint id);
164 
165     void reset(const Context *context) override;
166 
167     ResourceMap<Shader> mShaders;
168     ResourceMap<Program> mPrograms;
169 };
170 
171 class TextureManager
172     : public TypedResourceManager<Texture, HandleAllocator, TextureManager, TextureID>
173 {
174   public:
175     TextureID createTexture();
getTexture(TextureID handle)176     ANGLE_INLINE Texture *getTexture(TextureID handle) const
177     {
178         ASSERT(mObjectMap.query({0}) == nullptr);
179         return mObjectMap.query(handle);
180     }
181 
182     void signalAllTexturesDirty() const;
183 
checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)184     ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory,
185                                                  TextureID handle,
186                                                  TextureType type)
187     {
188         return checkObjectAllocation(factory, handle, type);
189     }
190 
191     static Texture *AllocateNewObject(rx::GLImplFactory *factory,
192                                       TextureID handle,
193                                       TextureType type);
194     static void DeleteObject(const Context *context, Texture *texture);
195 
196     void enableHandleAllocatorLogging();
197 
198   protected:
~TextureManager()199     ~TextureManager() override {}
200 };
201 
202 class RenderbufferManager : public TypedResourceManager<Renderbuffer,
203                                                         HandleAllocator,
204                                                         RenderbufferManager,
205                                                         RenderbufferID>
206 {
207   public:
208     RenderbufferID createRenderbuffer();
209     Renderbuffer *getRenderbuffer(RenderbufferID handle) const;
210 
checkRenderbufferAllocation(rx::GLImplFactory * factory,RenderbufferID handle)211     Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle)
212     {
213         return checkObjectAllocation(factory, handle);
214     }
215 
216     static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle);
217     static void DeleteObject(const Context *context, Renderbuffer *renderbuffer);
218 
219   protected:
~RenderbufferManager()220     ~RenderbufferManager() override {}
221 };
222 
223 class SamplerManager : public TypedResourceManager<Sampler, HandleAllocator, SamplerManager>
224 {
225   public:
226     GLuint createSampler();
227     Sampler *getSampler(GLuint handle) const;
228     bool isSampler(GLuint sampler) const;
229 
checkSamplerAllocation(rx::GLImplFactory * factory,GLuint handle)230     Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, GLuint handle)
231     {
232         return checkObjectAllocation(factory, handle);
233     }
234 
235     static Sampler *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle);
236     static void DeleteObject(const Context *context, Sampler *sampler);
237 
238   protected:
~SamplerManager()239     ~SamplerManager() override {}
240 };
241 
242 class SyncManager : public TypedResourceManager<Sync, HandleAllocator, SyncManager>
243 {
244   public:
245     GLuint createSync(rx::GLImplFactory *factory);
246     Sync *getSync(GLuint handle) const;
247 
248     static void DeleteObject(const Context *context, Sync *sync);
249 
250   protected:
~SyncManager()251     ~SyncManager() override {}
252 };
253 
254 class PathManager : public ResourceManagerBase<HandleRangeAllocator>
255 {
256   public:
257     PathManager();
258 
259     angle::Result createPaths(Context *context, GLsizei range, GLuint *numCreated);
260     void deletePaths(GLuint first, GLsizei range);
261     Path *getPath(GLuint handle) const;
262     bool hasPath(GLuint handle) const;
263 
264   protected:
265     ~PathManager() override;
266     void reset(const Context *context) override;
267 
268   private:
269     ResourceMap<Path> mPaths;
270 };
271 
272 class FramebufferManager
273     : public TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager>
274 {
275   public:
276     GLuint createFramebuffer();
277     Framebuffer *getFramebuffer(GLuint handle) const;
278     void setDefaultFramebuffer(Framebuffer *framebuffer);
279 
280     void invalidateFramebufferComplenessCache() const;
281 
checkFramebufferAllocation(rx::GLImplFactory * factory,const Caps & caps,GLuint handle)282     Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
283                                             const Caps &caps,
284                                             GLuint handle)
285     {
286         return checkObjectAllocation<const Caps &>(factory, handle, caps);
287     }
288 
289     static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
290                                           GLuint handle,
291                                           const Caps &caps);
292     static void DeleteObject(const Context *context, Framebuffer *framebuffer);
293 
294   protected:
~FramebufferManager()295     ~FramebufferManager() override {}
296 };
297 
298 class ProgramPipelineManager
299     : public TypedResourceManager<ProgramPipeline, HandleAllocator, ProgramPipelineManager>
300 {
301   public:
302     GLuint createProgramPipeline();
303     ProgramPipeline *getProgramPipeline(GLuint handle) const;
304 
checkProgramPipelineAllocation(rx::GLImplFactory * factory,GLuint handle)305     ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, GLuint handle)
306     {
307         return checkObjectAllocation(factory, handle);
308     }
309 
310     static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle);
311     static void DeleteObject(const Context *context, ProgramPipeline *pipeline);
312 
313   protected:
~ProgramPipelineManager()314     ~ProgramPipelineManager() override {}
315 };
316 
317 class MemoryObjectManager : public ResourceManagerBase<HandleAllocator>
318 {
319   public:
320     MemoryObjectManager();
321 
322     GLuint createMemoryObject(rx::GLImplFactory *factory);
323     void deleteMemoryObject(const Context *context, GLuint handle);
324     MemoryObject *getMemoryObject(GLuint handle) const;
325 
326   protected:
327     ~MemoryObjectManager() override;
328 
329   private:
330     void reset(const Context *context) override;
331 
332     ResourceMap<MemoryObject> mMemoryObjects;
333 };
334 
335 class SemaphoreManager : public ResourceManagerBase<HandleAllocator>
336 {
337   public:
338     SemaphoreManager();
339 
340     GLuint createSemaphore(rx::GLImplFactory *factory);
341     void deleteSemaphore(const Context *context, GLuint handle);
342     Semaphore *getSemaphore(GLuint handle) const;
343 
344   protected:
345     ~SemaphoreManager() override;
346 
347   private:
348     void reset(const Context *context) override;
349 
350     ResourceMap<Semaphore> mSemaphores;
351 };
352 
353 }  // namespace gl
354 
355 #endif  // LIBANGLE_RESOURCEMANAGER_H_
356