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