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 } 23 24 namespace gl 25 { 26 class Buffer; 27 struct Caps; 28 class Context; 29 class Sync; 30 class Framebuffer; 31 struct Limitations; 32 class MemoryObject; 33 class Path; 34 class Program; 35 class ProgramPipeline; 36 class Renderbuffer; 37 class Sampler; 38 class Shader; 39 class Semaphore; 40 class Texture; 41 42 template <typename HandleAllocatorType> 43 class ResourceManagerBase : angle::NonCopyable 44 { 45 public: 46 ResourceManagerBase(); 47 48 void addRef(); 49 void release(const Context *context); 50 51 protected: 52 virtual void reset(const Context *context) = 0; ~ResourceManagerBase()53 virtual ~ResourceManagerBase() {} 54 55 HandleAllocatorType mHandleAllocator; 56 57 private: 58 size_t mRefCount; 59 }; 60 61 template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType> 62 class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType> 63 { 64 public: TypedResourceManager()65 TypedResourceManager() {} 66 67 void deleteObject(const Context *context, IDType handle); isHandleGenerated(IDType handle)68 ANGLE_INLINE bool isHandleGenerated(IDType handle) const 69 { 70 // Zero is always assumed to have been generated implicitly. 71 return GetIDValue(handle) == 0 || mObjectMap.contains(handle); 72 } 73 begin()74 typename ResourceMap<ResourceType, IDType>::Iterator begin() const 75 { 76 return mObjectMap.begin(); 77 } end()78 typename ResourceMap<ResourceType, IDType>::Iterator end() const { return mObjectMap.end(); } 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 class BufferManager : public TypedResourceManager<Buffer, HandleAllocator, BufferManager, BufferID> 126 { 127 public: 128 BufferID createBuffer(); 129 Buffer *getBuffer(BufferID handle) const; 130 checkBufferAllocation(rx::GLImplFactory * factory,BufferID handle)131 ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle) 132 { 133 return checkObjectAllocation(factory, handle); 134 } 135 136 // TODO(jmadill): Investigate design which doesn't expose these methods publicly. 137 static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle); 138 static void DeleteObject(const Context *context, Buffer *buffer); 139 140 protected: ~BufferManager()141 ~BufferManager() override {} 142 }; 143 144 class ShaderProgramManager : public ResourceManagerBase<HandleAllocator> 145 { 146 public: 147 ShaderProgramManager(); 148 149 ShaderProgramID createShader(rx::GLImplFactory *factory, 150 const Limitations &rendererLimitations, 151 ShaderType type); 152 void deleteShader(const Context *context, ShaderProgramID shader); 153 Shader *getShader(ShaderProgramID handle) const; 154 155 ShaderProgramID createProgram(rx::GLImplFactory *factory); 156 void deleteProgram(const Context *context, ShaderProgramID program); 157 getProgram(ShaderProgramID handle)158 ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const 159 { 160 return mPrograms.query(handle); 161 } 162 163 // For capture only. getShadersForCapture()164 const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; } getProgramsForCapture()165 const ResourceMap<Program, ShaderProgramID> &getProgramsForCapture() const { return mPrograms; } 166 167 protected: 168 ~ShaderProgramManager() override; 169 170 private: 171 template <typename ObjectType, typename IDType> 172 void deleteObject(const Context *context, 173 ResourceMap<ObjectType, IDType> *objectMap, 174 IDType id); 175 176 void reset(const Context *context) override; 177 178 ResourceMap<Shader, ShaderProgramID> mShaders; 179 ResourceMap<Program, ShaderProgramID> mPrograms; 180 }; 181 182 class TextureManager 183 : public TypedResourceManager<Texture, HandleAllocator, TextureManager, TextureID> 184 { 185 public: 186 TextureID createTexture(); getTexture(TextureID handle)187 ANGLE_INLINE Texture *getTexture(TextureID handle) const 188 { 189 ASSERT(mObjectMap.query({0}) == nullptr); 190 return mObjectMap.query(handle); 191 } 192 193 void signalAllTexturesDirty() const; 194 checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)195 ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory, 196 TextureID handle, 197 TextureType type) 198 { 199 return checkObjectAllocation(factory, handle, type); 200 } 201 202 static Texture *AllocateNewObject(rx::GLImplFactory *factory, 203 TextureID handle, 204 TextureType type); 205 static void DeleteObject(const Context *context, Texture *texture); 206 207 void enableHandleAllocatorLogging(); 208 209 protected: ~TextureManager()210 ~TextureManager() override {} 211 }; 212 213 class RenderbufferManager : public TypedResourceManager<Renderbuffer, 214 HandleAllocator, 215 RenderbufferManager, 216 RenderbufferID> 217 { 218 public: 219 RenderbufferID createRenderbuffer(); 220 Renderbuffer *getRenderbuffer(RenderbufferID handle) const; 221 checkRenderbufferAllocation(rx::GLImplFactory * factory,RenderbufferID handle)222 Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle) 223 { 224 return checkObjectAllocation(factory, handle); 225 } 226 227 static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle); 228 static void DeleteObject(const Context *context, Renderbuffer *renderbuffer); 229 230 protected: ~RenderbufferManager()231 ~RenderbufferManager() override {} 232 }; 233 234 class SamplerManager 235 : public TypedResourceManager<Sampler, HandleAllocator, SamplerManager, SamplerID> 236 { 237 public: 238 SamplerID createSampler(); 239 Sampler *getSampler(SamplerID handle) const; 240 bool isSampler(SamplerID sampler) const; 241 checkSamplerAllocation(rx::GLImplFactory * factory,SamplerID handle)242 Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle) 243 { 244 return checkObjectAllocation(factory, handle); 245 } 246 247 static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle); 248 static void DeleteObject(const Context *context, Sampler *sampler); 249 250 protected: ~SamplerManager()251 ~SamplerManager() override {} 252 }; 253 254 class SyncManager : public TypedResourceManager<Sync, HandleAllocator, SyncManager, GLuint> 255 { 256 public: 257 GLuint createSync(rx::GLImplFactory *factory); 258 Sync *getSync(GLuint handle) const; 259 260 static void DeleteObject(const Context *context, Sync *sync); 261 262 protected: ~SyncManager()263 ~SyncManager() override {} 264 }; 265 266 class FramebufferManager 267 : public TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager, FramebufferID> 268 { 269 public: 270 FramebufferID createFramebuffer(); 271 Framebuffer *getFramebuffer(FramebufferID handle) const; 272 void setDefaultFramebuffer(Framebuffer *framebuffer); 273 274 void invalidateFramebufferCompletenessCache() const; 275 checkFramebufferAllocation(rx::GLImplFactory * factory,const Caps & caps,FramebufferID handle,ContextID owningContextID)276 Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, 277 const Caps &caps, 278 FramebufferID handle, 279 ContextID owningContextID) 280 { 281 return checkObjectAllocation<const Caps &>(factory, handle, caps, owningContextID); 282 } 283 284 static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, 285 FramebufferID handle, 286 const Caps &caps, 287 ContextID owningContextID); 288 static void DeleteObject(const Context *context, Framebuffer *framebuffer); 289 290 protected: ~FramebufferManager()291 ~FramebufferManager() override {} 292 }; 293 294 class ProgramPipelineManager : public TypedResourceManager<ProgramPipeline, 295 HandleAllocator, 296 ProgramPipelineManager, 297 ProgramPipelineID> 298 { 299 public: 300 ProgramPipelineID createProgramPipeline(); 301 ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; 302 checkProgramPipelineAllocation(rx::GLImplFactory * factory,ProgramPipelineID handle)303 ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, 304 ProgramPipelineID handle) 305 { 306 return checkObjectAllocation(factory, handle); 307 } 308 309 static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle); 310 static void DeleteObject(const Context *context, ProgramPipeline *pipeline); 311 312 protected: ~ProgramPipelineManager()313 ~ProgramPipelineManager() override {} 314 }; 315 316 class MemoryObjectManager : public ResourceManagerBase<HandleAllocator> 317 { 318 public: 319 MemoryObjectManager(); 320 321 MemoryObjectID createMemoryObject(rx::GLImplFactory *factory); 322 void deleteMemoryObject(const Context *context, MemoryObjectID handle); 323 MemoryObject *getMemoryObject(MemoryObjectID handle) const; 324 325 protected: 326 ~MemoryObjectManager() override; 327 328 private: 329 void reset(const Context *context) override; 330 331 ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects; 332 }; 333 334 class SemaphoreManager : public ResourceManagerBase<HandleAllocator> 335 { 336 public: 337 SemaphoreManager(); 338 339 SemaphoreID createSemaphore(rx::GLImplFactory *factory); 340 void deleteSemaphore(const Context *context, SemaphoreID handle); 341 Semaphore *getSemaphore(SemaphoreID handle) const; 342 343 protected: 344 ~SemaphoreManager() override; 345 346 private: 347 void reset(const Context *context) override; 348 349 ResourceMap<Semaphore, SemaphoreID> mSemaphores; 350 }; 351 } // namespace gl 352 353 #endif // LIBANGLE_RESOURCEMANAGER_H_ 354