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