• 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 }  // 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 template <typename ResourceType, typename ImplT, typename IDType>
126 class TypedResourceManagerWithTotalMemorySize
127     : public TypedResourceManager<ResourceType, ImplT, IDType>
128 {
129   public:
getTotalMemorySize()130     size_t getTotalMemorySize() const
131     {
132         size_t totalBytes = 0;
133 
134         for (const auto &rb : UnsafeResourceMapIter(this->mObjectMap))
135         {
136             totalBytes += static_cast<size_t>(rb.second->getMemorySize());
137         }
138         return totalBytes;
139     }
140 };
141 
142 class BufferManager
143     : public TypedResourceManagerWithTotalMemorySize<Buffer, BufferManager, BufferID>
144 {
145   public:
146     BufferID createBuffer();
147     Buffer *getBuffer(BufferID handle) const;
148 
checkBufferAllocation(rx::GLImplFactory * factory,BufferID handle)149     ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle)
150     {
151         return checkObjectAllocation(factory, handle);
152     }
153 
154     // TODO(jmadill): Investigate design which doesn't expose these methods publicly.
155     static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle);
156     static void DeleteObject(const Context *context, Buffer *buffer);
157 
158   protected:
159     ~BufferManager() override;
160 };
161 
162 class ShaderProgramManager : public ResourceManagerBase
163 {
164   public:
165     ShaderProgramManager();
166 
167     ShaderProgramID createShader(rx::GLImplFactory *factory,
168                                  const Limitations &rendererLimitations,
169                                  ShaderType type);
170     void deleteShader(const Context *context, ShaderProgramID shader);
171     Shader *getShader(ShaderProgramID handle) const;
172 
173     ShaderProgramID createProgram(rx::GLImplFactory *factory);
174     void deleteProgram(const Context *context, ShaderProgramID program);
175 
getProgram(ShaderProgramID handle)176     ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const
177     {
178         return mPrograms.query(handle);
179     }
180 
181     // For capture and performance counters only.
getShadersForCapture()182     const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; }
getProgramsForCaptureAndPerf()183     const ResourceMap<Program, ShaderProgramID> &getProgramsForCaptureAndPerf() const
184     {
185         return mPrograms;
186     }
187 
188   protected:
189     ~ShaderProgramManager() override;
190 
191   private:
192     template <typename ObjectType, typename IDType>
193     void deleteObject(const Context *context,
194                       ResourceMap<ObjectType, IDType> *objectMap,
195                       IDType id);
196 
197     void reset(const Context *context) override;
198 
199     ResourceMap<Shader, ShaderProgramID> mShaders;
200     ResourceMap<Program, ShaderProgramID> mPrograms;
201 };
202 
203 class TextureManager : public TypedResourceManager<Texture, TextureManager, TextureID>
204 {
205   public:
206     TextureID createTexture();
getTexture(TextureID handle)207     ANGLE_INLINE Texture *getTexture(TextureID handle) const
208     {
209         ASSERT(mObjectMap.query({0}) == nullptr);
210         return mObjectMap.query(handle);
211     }
212 
213     void signalAllTexturesDirty() const;
214 
checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)215     ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory,
216                                                  TextureID handle,
217                                                  TextureType type)
218     {
219         return checkObjectAllocation(factory, handle, type);
220     }
221 
222     static Texture *AllocateNewObject(rx::GLImplFactory *factory,
223                                       TextureID handle,
224                                       TextureType type);
225     static void DeleteObject(const Context *context, Texture *texture);
226 
227     void enableHandleAllocatorLogging();
228 
229     size_t getTotalMemorySize() const;
230 
231   protected:
232     ~TextureManager() override;
233 };
234 
235 class RenderbufferManager : public TypedResourceManagerWithTotalMemorySize<Renderbuffer,
236                                                                            RenderbufferManager,
237                                                                            RenderbufferID>
238 {
239   public:
240     RenderbufferID createRenderbuffer();
241     Renderbuffer *getRenderbuffer(RenderbufferID handle) const;
242 
checkRenderbufferAllocation(rx::GLImplFactory * factory,RenderbufferID handle)243     Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle)
244     {
245         return checkObjectAllocation(factory, handle);
246     }
247 
248     static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle);
249     static void DeleteObject(const Context *context, Renderbuffer *renderbuffer);
250 
251   protected:
252     ~RenderbufferManager() override;
253 };
254 
255 class SamplerManager : public TypedResourceManager<Sampler, SamplerManager, SamplerID>
256 {
257   public:
258     SamplerID createSampler();
getSampler(SamplerID handle)259     Sampler *getSampler(SamplerID handle) const { return mObjectMap.query(handle); }
isSampler(SamplerID sampler)260     bool isSampler(SamplerID sampler) const { return mObjectMap.contains(sampler); }
261 
checkSamplerAllocation(rx::GLImplFactory * factory,SamplerID handle)262     Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle)
263     {
264         return checkObjectAllocation(factory, handle);
265     }
266 
267     static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle);
268     static void DeleteObject(const Context *context, Sampler *sampler);
269 
270   protected:
271     ~SamplerManager() override;
272 };
273 
274 class SyncManager : public TypedResourceManager<Sync, SyncManager, SyncID>
275 {
276   public:
277     SyncID createSync(rx::GLImplFactory *factory);
278     Sync *getSync(SyncID handle) const;
279 
280     static void DeleteObject(const Context *context, Sync *sync);
281 
282   protected:
283     ~SyncManager() override;
284 };
285 
286 class FramebufferManager
287     : public TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID>
288 {
289   public:
290     FramebufferID createFramebuffer();
291     Framebuffer *getFramebuffer(FramebufferID handle) const;
292     void setDefaultFramebuffer(Framebuffer *framebuffer);
293     Framebuffer *getDefaultFramebuffer() const;
294 
295     void invalidateFramebufferCompletenessCache() const;
296 
checkFramebufferAllocation(rx::GLImplFactory * factory,const Context * context,FramebufferID handle)297     Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
298                                             const Context *context,
299                                             FramebufferID handle)
300     {
301         return checkObjectAllocation(factory, handle, context);
302     }
303 
304     static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
305                                           FramebufferID handle,
306                                           const Context *context);
307     static void DeleteObject(const Context *context, Framebuffer *framebuffer);
308 
309   protected:
310     ~FramebufferManager() override;
311 };
312 
313 class ProgramPipelineManager
314     : public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID>
315 {
316   public:
317     ProgramPipelineID createProgramPipeline();
318     ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const;
319 
checkProgramPipelineAllocation(rx::GLImplFactory * factory,ProgramPipelineID handle)320     ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory,
321                                                     ProgramPipelineID handle)
322     {
323         return checkObjectAllocation(factory, handle);
324     }
325 
326     static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle);
327     static void DeleteObject(const Context *context, ProgramPipeline *pipeline);
328 
329   protected:
330     ~ProgramPipelineManager() override;
331 };
332 
333 class MemoryObjectManager : public ResourceManagerBase
334 {
335   public:
336     MemoryObjectManager();
337 
338     MemoryObjectID createMemoryObject(rx::GLImplFactory *factory);
339     void deleteMemoryObject(const Context *context, MemoryObjectID handle);
340     MemoryObject *getMemoryObject(MemoryObjectID handle) const;
341 
342   protected:
343     ~MemoryObjectManager() override;
344 
345   private:
346     void reset(const Context *context) override;
347 
348     ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects;
349 };
350 
351 class SemaphoreManager : public ResourceManagerBase
352 {
353   public:
354     SemaphoreManager();
355 
356     SemaphoreID createSemaphore(rx::GLImplFactory *factory);
357     void deleteSemaphore(const Context *context, SemaphoreID handle);
358     Semaphore *getSemaphore(SemaphoreID handle) const;
359 
360   protected:
361     ~SemaphoreManager() override;
362 
363   private:
364     void reset(const Context *context) override;
365 
366     ResourceMap<Semaphore, SemaphoreID> mSemaphores;
367 };
368 }  // namespace gl
369 
370 #endif  // LIBANGLE_RESOURCEMANAGER_H_
371