1 //
2 // Copyright (c) 2002-2016 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 Path;
34 class Program;
35 class ProgramPipeline;
36 class Renderbuffer;
37 class Sampler;
38 class Shader;
39 class Texture;
40 
41 template <typename HandleAllocatorType>
42 class ResourceManagerBase : angle::NonCopyable
43 {
44   public:
45     ResourceManagerBase();
46 
47     void addRef();
48     void release(const Context *context);
49 
50   protected:
51     virtual void reset(const Context *context) = 0;
~ResourceManagerBase()52     virtual ~ResourceManagerBase() {}
53 
54     HandleAllocatorType mHandleAllocator;
55 
56   private:
57     size_t mRefCount;
58 };
59 
60 template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
61 class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType>
62 {
63   public:
TypedResourceManager()64     TypedResourceManager() {}
65 
66     void deleteObject(const Context *context, GLuint handle);
isHandleGenerated(GLuint handle)67     bool isHandleGenerated(GLuint handle) const
68     {
69         // Zero is always assumed to have been generated implicitly.
70         return handle == 0 || mObjectMap.contains(handle);
71     }
72 
73   protected:
74     ~TypedResourceManager() override;
75 
76     // Inlined in the header for performance.
77     template <typename... ArgTypes>
checkObjectAllocation(rx::GLImplFactory * factory,GLuint handle,ArgTypes...args)78     ResourceType *checkObjectAllocation(rx::GLImplFactory *factory, GLuint handle, ArgTypes... args)
79     {
80         ResourceType *value = mObjectMap.query(handle);
81         if (value)
82         {
83             return value;
84         }
85 
86         if (handle == 0)
87         {
88             return nullptr;
89         }
90 
91         ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...);
92 
93         if (!mObjectMap.contains(handle))
94         {
95             this->mHandleAllocator.reserve(handle);
96         }
97         mObjectMap.assign(handle, object);
98 
99         return object;
100     }
101 
102     void reset(const Context *context) override;
103 
104     ResourceMap<ResourceType> mObjectMap;
105 };
106 
107 class BufferManager : public TypedResourceManager<Buffer, HandleAllocator, BufferManager>
108 {
109   public:
110     GLuint createBuffer();
111     Buffer *getBuffer(GLuint handle) const;
112 
checkBufferAllocation(rx::GLImplFactory * factory,GLuint handle)113     Buffer *checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle)
114     {
115         return checkObjectAllocation(factory, handle);
116     }
117 
118     // TODO(jmadill): Investigate design which doesn't expose these methods publicly.
119     static Buffer *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle);
120     static void DeleteObject(const Context *context, Buffer *buffer);
121 
122   protected:
~BufferManager()123     ~BufferManager() override {}
124 };
125 
126 class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
127 {
128   public:
129     ShaderProgramManager();
130 
131     GLuint createShader(rx::GLImplFactory *factory,
132                         const Limitations &rendererLimitations,
133                         GLenum type);
134     void deleteShader(const Context *context, GLuint shader);
135     Shader *getShader(GLuint handle) const;
136 
137     GLuint createProgram(rx::GLImplFactory *factory);
138     void deleteProgram(const Context *context, GLuint program);
139     Program *getProgram(GLuint handle) const;
140 
141   protected:
142     ~ShaderProgramManager() override;
143 
144   private:
145     template <typename ObjectType>
146     void deleteObject(const Context *context, ResourceMap<ObjectType> *objectMap, GLuint id);
147 
148     void reset(const Context *context) override;
149 
150     ResourceMap<Shader> mShaders;
151     ResourceMap<Program> mPrograms;
152 };
153 
154 class TextureManager : public TypedResourceManager<Texture, HandleAllocator, TextureManager>
155 {
156   public:
157     GLuint createTexture();
158     Texture *getTexture(GLuint handle) const;
159 
160     void signalAllTexturesDirty(const Context *context) const;
161 
checkTextureAllocation(rx::GLImplFactory * factory,GLuint handle,GLenum target)162     Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, GLenum target)
163     {
164         return checkObjectAllocation(factory, handle, target);
165     }
166 
167     static Texture *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target);
168     static void DeleteObject(const Context *context, Texture *texture);
169 
170     void enableHandleAllocatorLogging();
171 
172   protected:
~TextureManager()173     ~TextureManager() override {}
174 };
175 
176 class RenderbufferManager
177     : public TypedResourceManager<Renderbuffer, HandleAllocator, RenderbufferManager>
178 {
179   public:
180     GLuint createRenderbuffer();
181     Renderbuffer *getRenderbuffer(GLuint handle) const;
182 
checkRenderbufferAllocation(rx::GLImplFactory * factory,GLuint handle)183     Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, GLuint handle)
184     {
185         return checkObjectAllocation(factory, handle);
186     }
187 
188     static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle);
189     static void DeleteObject(const Context *context, Renderbuffer *renderbuffer);
190 
191   protected:
~RenderbufferManager()192     ~RenderbufferManager() override {}
193 };
194 
195 class SamplerManager : public TypedResourceManager<Sampler, HandleAllocator, SamplerManager>
196 {
197   public:
198     GLuint createSampler();
199     Sampler *getSampler(GLuint handle) const;
200     bool isSampler(GLuint sampler) const;
201 
checkSamplerAllocation(rx::GLImplFactory * factory,GLuint handle)202     Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, GLuint handle)
203     {
204         return checkObjectAllocation(factory, handle);
205     }
206 
207     static Sampler *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle);
208     static void DeleteObject(const Context *context, Sampler *sampler);
209 
210   protected:
~SamplerManager()211     ~SamplerManager() override {}
212 };
213 
214 class SyncManager : public TypedResourceManager<Sync, HandleAllocator, SyncManager>
215 {
216   public:
217     GLuint createSync(rx::GLImplFactory *factory);
218     Sync *getSync(GLuint handle) const;
219 
220     static void DeleteObject(const Context *context, Sync *sync);
221 
222   protected:
~SyncManager()223     ~SyncManager() override {}
224 };
225 
226 class PathManager : public ResourceManagerBase<HandleRangeAllocator>
227 {
228   public:
229     PathManager();
230 
231     ErrorOrResult<GLuint> createPaths(rx::GLImplFactory *factory, GLsizei range);
232     void deletePaths(GLuint first, GLsizei range);
233     Path *getPath(GLuint handle) const;
234     bool hasPath(GLuint handle) const;
235 
236   protected:
237     ~PathManager() override;
238     void reset(const Context *context) override;
239 
240   private:
241     ResourceMap<Path> mPaths;
242 };
243 
244 class FramebufferManager
245     : public TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager>
246 {
247   public:
248     GLuint createFramebuffer();
249     Framebuffer *getFramebuffer(GLuint handle) const;
250     void setDefaultFramebuffer(Framebuffer *framebuffer);
251 
252     void invalidateFramebufferComplenessCache() const;
253 
checkFramebufferAllocation(rx::GLImplFactory * factory,const Caps & caps,GLuint handle)254     Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
255                                             const Caps &caps,
256                                             GLuint handle)
257     {
258         return checkObjectAllocation<const Caps &>(factory, handle, caps);
259     }
260 
261     static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
262                                           GLuint handle,
263                                           const Caps &caps);
264     static void DeleteObject(const Context *context, Framebuffer *framebuffer);
265 
266   protected:
~FramebufferManager()267     ~FramebufferManager() override {}
268 };
269 
270 class ProgramPipelineManager
271     : public TypedResourceManager<ProgramPipeline, HandleAllocator, ProgramPipelineManager>
272 {
273   public:
274     GLuint createProgramPipeline();
275     ProgramPipeline *getProgramPipeline(GLuint handle) const;
276 
checkProgramPipelineAllocation(rx::GLImplFactory * factory,GLuint handle)277     ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, GLuint handle)
278     {
279         return checkObjectAllocation(factory, handle);
280     }
281 
282     static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle);
283     static void DeleteObject(const Context *context, ProgramPipeline *pipeline);
284 
285   protected:
~ProgramPipelineManager()286     ~ProgramPipelineManager() override {}
287 };
288 
289 }  // namespace gl
290 
291 #endif // LIBANGLE_RESOURCEMANAGER_H_
292