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 class BufferManager : public TypedResourceManager<Buffer, 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: 141 ~BufferManager() override; 142 }; 143 144 class ShaderProgramManager : public ResourceManagerBase 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 and performance counters only. getShadersForCapture()164 const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; } getProgramsForCaptureAndPerf()165 const ResourceMap<Program, ShaderProgramID> &getProgramsForCaptureAndPerf() const 166 { 167 return mPrograms; 168 } 169 170 protected: 171 ~ShaderProgramManager() override; 172 173 private: 174 template <typename ObjectType, typename IDType> 175 void deleteObject(const Context *context, 176 ResourceMap<ObjectType, IDType> *objectMap, 177 IDType id); 178 179 void reset(const Context *context) override; 180 181 ResourceMap<Shader, ShaderProgramID> mShaders; 182 ResourceMap<Program, ShaderProgramID> mPrograms; 183 }; 184 185 class TextureManager : public TypedResourceManager<Texture, TextureManager, TextureID> 186 { 187 public: 188 TextureID createTexture(); getTexture(TextureID handle)189 ANGLE_INLINE Texture *getTexture(TextureID handle) const 190 { 191 ASSERT(mObjectMap.query({0}) == nullptr); 192 return mObjectMap.query(handle); 193 } 194 195 void signalAllTexturesDirty() const; 196 checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)197 ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory, 198 TextureID handle, 199 TextureType type) 200 { 201 return checkObjectAllocation(factory, handle, type); 202 } 203 204 static Texture *AllocateNewObject(rx::GLImplFactory *factory, 205 TextureID handle, 206 TextureType type); 207 static void DeleteObject(const Context *context, Texture *texture); 208 209 void enableHandleAllocatorLogging(); 210 211 protected: 212 ~TextureManager() override; 213 }; 214 215 class RenderbufferManager 216 : public TypedResourceManager<Renderbuffer, RenderbufferManager, 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: 231 ~RenderbufferManager() override; 232 }; 233 234 class SamplerManager : public TypedResourceManager<Sampler, SamplerManager, SamplerID> 235 { 236 public: 237 SamplerID createSampler(); 238 Sampler *getSampler(SamplerID handle) const; 239 bool isSampler(SamplerID sampler) const; 240 checkSamplerAllocation(rx::GLImplFactory * factory,SamplerID handle)241 Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle) 242 { 243 return checkObjectAllocation(factory, handle); 244 } 245 246 static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle); 247 static void DeleteObject(const Context *context, Sampler *sampler); 248 249 protected: 250 ~SamplerManager() override; 251 }; 252 253 class SyncManager : public TypedResourceManager<Sync, SyncManager, SyncID> 254 { 255 public: 256 SyncID createSync(rx::GLImplFactory *factory); 257 Sync *getSync(SyncID handle) const; 258 259 static void DeleteObject(const Context *context, Sync *sync); 260 261 protected: 262 ~SyncManager() override; 263 }; 264 265 class FramebufferManager 266 : public TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID> 267 { 268 public: 269 FramebufferID createFramebuffer(); 270 Framebuffer *getFramebuffer(FramebufferID handle) const; 271 void setDefaultFramebuffer(Framebuffer *framebuffer); 272 Framebuffer *getDefaultFramebuffer() const; 273 274 void invalidateFramebufferCompletenessCache() const; 275 checkFramebufferAllocation(rx::GLImplFactory * factory,const Context * context,FramebufferID handle)276 Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, 277 const Context *context, 278 FramebufferID handle) 279 { 280 return checkObjectAllocation(factory, handle, context); 281 } 282 283 static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, 284 FramebufferID handle, 285 const Context *context); 286 static void DeleteObject(const Context *context, Framebuffer *framebuffer); 287 288 protected: 289 ~FramebufferManager() override; 290 }; 291 292 class ProgramPipelineManager 293 : public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID> 294 { 295 public: 296 ProgramPipelineID createProgramPipeline(); 297 ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; 298 checkProgramPipelineAllocation(rx::GLImplFactory * factory,ProgramPipelineID handle)299 ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, 300 ProgramPipelineID handle) 301 { 302 return checkObjectAllocation(factory, handle); 303 } 304 305 static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle); 306 static void DeleteObject(const Context *context, ProgramPipeline *pipeline); 307 308 protected: 309 ~ProgramPipelineManager() override; 310 }; 311 312 class MemoryObjectManager : public ResourceManagerBase 313 { 314 public: 315 MemoryObjectManager(); 316 317 MemoryObjectID createMemoryObject(rx::GLImplFactory *factory); 318 void deleteMemoryObject(const Context *context, MemoryObjectID handle); 319 MemoryObject *getMemoryObject(MemoryObjectID handle) const; 320 321 protected: 322 ~MemoryObjectManager() override; 323 324 private: 325 void reset(const Context *context) override; 326 327 ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects; 328 }; 329 330 class SemaphoreManager : public ResourceManagerBase 331 { 332 public: 333 SemaphoreManager(); 334 335 SemaphoreID createSemaphore(rx::GLImplFactory *factory); 336 void deleteSemaphore(const Context *context, SemaphoreID handle); 337 Semaphore *getSemaphore(SemaphoreID handle) const; 338 339 protected: 340 ~SemaphoreManager() override; 341 342 private: 343 void reset(const Context *context) override; 344 345 ResourceMap<Semaphore, SemaphoreID> mSemaphores; 346 }; 347 } // namespace gl 348 349 #endif // LIBANGLE_RESOURCEMANAGER_H_ 350