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 template <typename ResourceType, typename ImplT, typename IDType> 126 class TypedResourceManagerWithTotalMemorySize 127 : public TypedResourceManager<ResourceType, ImplT, IDType> 128 { 129 public: getTotalMemorySize()130 size_t getTotalMemorySize() const 131 { 132 size_t totalBytes = 0; 133 134 for (const auto &rb : UnsafeResourceMapIter(this->mObjectMap)) 135 { 136 totalBytes += static_cast<size_t>(rb.second->getMemorySize()); 137 } 138 return totalBytes; 139 } 140 }; 141 142 class BufferManager 143 : public TypedResourceManagerWithTotalMemorySize<Buffer, BufferManager, BufferID> 144 { 145 public: 146 BufferID createBuffer(); 147 Buffer *getBuffer(BufferID handle) const; 148 checkBufferAllocation(rx::GLImplFactory * factory,BufferID handle)149 ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle) 150 { 151 return checkObjectAllocation(factory, handle); 152 } 153 154 // TODO(jmadill): Investigate design which doesn't expose these methods publicly. 155 static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle); 156 static void DeleteObject(const Context *context, Buffer *buffer); 157 158 protected: 159 ~BufferManager() override; 160 }; 161 162 class ShaderProgramManager : public ResourceManagerBase 163 { 164 public: 165 ShaderProgramManager(); 166 167 ShaderProgramID createShader(rx::GLImplFactory *factory, 168 const Limitations &rendererLimitations, 169 ShaderType type); 170 void deleteShader(const Context *context, ShaderProgramID shader); 171 Shader *getShader(ShaderProgramID handle) const; 172 173 ShaderProgramID createProgram(rx::GLImplFactory *factory); 174 void deleteProgram(const Context *context, ShaderProgramID program); 175 getProgram(ShaderProgramID handle)176 ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const 177 { 178 return mPrograms.query(handle); 179 } 180 181 // For capture and performance counters only. getShadersForCapture()182 const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; } getProgramsForCaptureAndPerf()183 const ResourceMap<Program, ShaderProgramID> &getProgramsForCaptureAndPerf() const 184 { 185 return mPrograms; 186 } 187 188 protected: 189 ~ShaderProgramManager() override; 190 191 private: 192 template <typename ObjectType, typename IDType> 193 void deleteObject(const Context *context, 194 ResourceMap<ObjectType, IDType> *objectMap, 195 IDType id); 196 197 void reset(const Context *context) override; 198 199 ResourceMap<Shader, ShaderProgramID> mShaders; 200 ResourceMap<Program, ShaderProgramID> mPrograms; 201 }; 202 203 class TextureManager : public TypedResourceManager<Texture, TextureManager, TextureID> 204 { 205 public: 206 TextureID createTexture(); getTexture(TextureID handle)207 ANGLE_INLINE Texture *getTexture(TextureID handle) const 208 { 209 ASSERT(mObjectMap.query({0}) == nullptr); 210 return mObjectMap.query(handle); 211 } 212 213 void signalAllTexturesDirty() const; 214 checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)215 ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory, 216 TextureID handle, 217 TextureType type) 218 { 219 return checkObjectAllocation(factory, handle, type); 220 } 221 222 static Texture *AllocateNewObject(rx::GLImplFactory *factory, 223 TextureID handle, 224 TextureType type); 225 static void DeleteObject(const Context *context, Texture *texture); 226 227 void enableHandleAllocatorLogging(); 228 229 size_t getTotalMemorySize() const; 230 231 protected: 232 ~TextureManager() override; 233 }; 234 235 class RenderbufferManager : public TypedResourceManagerWithTotalMemorySize<Renderbuffer, 236 RenderbufferManager, 237 RenderbufferID> 238 { 239 public: 240 RenderbufferID createRenderbuffer(); 241 Renderbuffer *getRenderbuffer(RenderbufferID handle) const; 242 checkRenderbufferAllocation(rx::GLImplFactory * factory,RenderbufferID handle)243 Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle) 244 { 245 return checkObjectAllocation(factory, handle); 246 } 247 248 static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle); 249 static void DeleteObject(const Context *context, Renderbuffer *renderbuffer); 250 251 protected: 252 ~RenderbufferManager() override; 253 }; 254 255 class SamplerManager : public TypedResourceManager<Sampler, SamplerManager, SamplerID> 256 { 257 public: 258 SamplerID createSampler(); getSampler(SamplerID handle)259 Sampler *getSampler(SamplerID handle) const { return mObjectMap.query(handle); } isSampler(SamplerID sampler)260 bool isSampler(SamplerID sampler) const { return mObjectMap.contains(sampler); } 261 checkSamplerAllocation(rx::GLImplFactory * factory,SamplerID handle)262 Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle) 263 { 264 return checkObjectAllocation(factory, handle); 265 } 266 267 static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle); 268 static void DeleteObject(const Context *context, Sampler *sampler); 269 270 protected: 271 ~SamplerManager() override; 272 }; 273 274 class SyncManager : public TypedResourceManager<Sync, SyncManager, SyncID> 275 { 276 public: 277 SyncID createSync(rx::GLImplFactory *factory); 278 Sync *getSync(SyncID handle) const; 279 280 static void DeleteObject(const Context *context, Sync *sync); 281 282 protected: 283 ~SyncManager() override; 284 }; 285 286 class FramebufferManager 287 : public TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID> 288 { 289 public: 290 FramebufferID createFramebuffer(); 291 Framebuffer *getFramebuffer(FramebufferID handle) const; 292 void setDefaultFramebuffer(Framebuffer *framebuffer); 293 Framebuffer *getDefaultFramebuffer() const; 294 295 void invalidateFramebufferCompletenessCache() const; 296 checkFramebufferAllocation(rx::GLImplFactory * factory,const Context * context,FramebufferID handle)297 Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, 298 const Context *context, 299 FramebufferID handle) 300 { 301 return checkObjectAllocation(factory, handle, context); 302 } 303 304 static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, 305 FramebufferID handle, 306 const Context *context); 307 static void DeleteObject(const Context *context, Framebuffer *framebuffer); 308 309 protected: 310 ~FramebufferManager() override; 311 }; 312 313 class ProgramPipelineManager 314 : public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID> 315 { 316 public: 317 ProgramPipelineID createProgramPipeline(); 318 ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; 319 checkProgramPipelineAllocation(rx::GLImplFactory * factory,ProgramPipelineID handle)320 ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, 321 ProgramPipelineID handle) 322 { 323 return checkObjectAllocation(factory, handle); 324 } 325 326 static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle); 327 static void DeleteObject(const Context *context, ProgramPipeline *pipeline); 328 329 protected: 330 ~ProgramPipelineManager() override; 331 }; 332 333 class MemoryObjectManager : public ResourceManagerBase 334 { 335 public: 336 MemoryObjectManager(); 337 338 MemoryObjectID createMemoryObject(rx::GLImplFactory *factory); 339 void deleteMemoryObject(const Context *context, MemoryObjectID handle); 340 MemoryObject *getMemoryObject(MemoryObjectID handle) const; 341 342 protected: 343 ~MemoryObjectManager() override; 344 345 private: 346 void reset(const Context *context) override; 347 348 ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects; 349 }; 350 351 class SemaphoreManager : public ResourceManagerBase 352 { 353 public: 354 SemaphoreManager(); 355 356 SemaphoreID createSemaphore(rx::GLImplFactory *factory); 357 void deleteSemaphore(const Context *context, SemaphoreID handle); 358 Semaphore *getSemaphore(SemaphoreID handle) const; 359 360 protected: 361 ~SemaphoreManager() override; 362 363 private: 364 void reset(const Context *context) override; 365 366 ResourceMap<Semaphore, SemaphoreID> mSemaphores; 367 }; 368 } // namespace gl 369 370 #endif // LIBANGLE_RESOURCEMANAGER_H_ 371