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 begin()78 typename ResourceMap<ResourceType, IDType>::Iterator begin() const 79 { 80 return mObjectMap.begin(); 81 } end()82 typename ResourceMap<ResourceType, IDType>::Iterator end() const { return mObjectMap.end(); } 83 84 protected: 85 ~TypedResourceManager() override; 86 87 // Inlined in the header for performance. 88 template <typename... ArgTypes> checkObjectAllocation(rx::GLImplFactory * factory,IDType handle,ArgTypes...args)89 ANGLE_INLINE ResourceType *checkObjectAllocation(rx::GLImplFactory *factory, 90 IDType handle, 91 ArgTypes... args) 92 { 93 ResourceType *value = mObjectMap.query(handle); 94 if (value) 95 { 96 return value; 97 } 98 99 if (GetIDValue(handle) == 0) 100 { 101 return nullptr; 102 } 103 104 return checkObjectAllocationImpl(factory, handle, args...); 105 } 106 107 void reset(const Context *context) override; 108 109 ResourceMap<ResourceType, IDType> mObjectMap; 110 111 private: 112 template <typename... ArgTypes> checkObjectAllocationImpl(rx::GLImplFactory * factory,IDType handle,ArgTypes...args)113 ResourceType *checkObjectAllocationImpl(rx::GLImplFactory *factory, 114 IDType handle, 115 ArgTypes... args) 116 { 117 ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...); 118 119 if (!mObjectMap.contains(handle)) 120 { 121 this->mHandleAllocator.reserve(GetIDValue(handle)); 122 } 123 mObjectMap.assign(handle, object); 124 125 return object; 126 } 127 }; 128 129 class BufferManager : public TypedResourceManager<Buffer, BufferManager, BufferID> 130 { 131 public: 132 BufferID createBuffer(); 133 Buffer *getBuffer(BufferID handle) const; 134 checkBufferAllocation(rx::GLImplFactory * factory,BufferID handle)135 ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle) 136 { 137 return checkObjectAllocation(factory, handle); 138 } 139 140 // TODO(jmadill): Investigate design which doesn't expose these methods publicly. 141 static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle); 142 static void DeleteObject(const Context *context, Buffer *buffer); 143 144 protected: 145 ~BufferManager() override; 146 }; 147 148 class ShaderProgramManager : public ResourceManagerBase 149 { 150 public: 151 ShaderProgramManager(); 152 153 ShaderProgramID createShader(rx::GLImplFactory *factory, 154 const Limitations &rendererLimitations, 155 ShaderType type); 156 void deleteShader(const Context *context, ShaderProgramID shader); 157 Shader *getShader(ShaderProgramID handle) const; 158 159 ShaderProgramID createProgram(rx::GLImplFactory *factory); 160 void deleteProgram(const Context *context, ShaderProgramID program); 161 getProgram(ShaderProgramID handle)162 ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const 163 { 164 return mPrograms.query(handle); 165 } 166 167 // For capture and performance counters only. getShadersForCapture()168 const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; } getProgramsForCaptureAndPerf()169 const ResourceMap<Program, ShaderProgramID> &getProgramsForCaptureAndPerf() const 170 { 171 return mPrograms; 172 } 173 174 protected: 175 ~ShaderProgramManager() override; 176 177 private: 178 template <typename ObjectType, typename IDType> 179 void deleteObject(const Context *context, 180 ResourceMap<ObjectType, IDType> *objectMap, 181 IDType id); 182 183 void reset(const Context *context) override; 184 185 ResourceMap<Shader, ShaderProgramID> mShaders; 186 ResourceMap<Program, ShaderProgramID> mPrograms; 187 }; 188 189 class TextureManager : public TypedResourceManager<Texture, TextureManager, TextureID> 190 { 191 public: 192 TextureID createTexture(); getTexture(TextureID handle)193 ANGLE_INLINE Texture *getTexture(TextureID handle) const 194 { 195 ASSERT(mObjectMap.query({0}) == nullptr); 196 return mObjectMap.query(handle); 197 } 198 199 void signalAllTexturesDirty() const; 200 checkTextureAllocation(rx::GLImplFactory * factory,TextureID handle,TextureType type)201 ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory, 202 TextureID handle, 203 TextureType type) 204 { 205 return checkObjectAllocation(factory, handle, type); 206 } 207 208 static Texture *AllocateNewObject(rx::GLImplFactory *factory, 209 TextureID handle, 210 TextureType type); 211 static void DeleteObject(const Context *context, Texture *texture); 212 213 void enableHandleAllocatorLogging(); 214 215 protected: 216 ~TextureManager() override; 217 }; 218 219 class RenderbufferManager 220 : public TypedResourceManager<Renderbuffer, RenderbufferManager, RenderbufferID> 221 { 222 public: 223 RenderbufferID createRenderbuffer(); 224 Renderbuffer *getRenderbuffer(RenderbufferID handle) const; 225 checkRenderbufferAllocation(rx::GLImplFactory * factory,RenderbufferID handle)226 Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle) 227 { 228 return checkObjectAllocation(factory, handle); 229 } 230 231 static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle); 232 static void DeleteObject(const Context *context, Renderbuffer *renderbuffer); 233 234 protected: 235 ~RenderbufferManager() override; 236 }; 237 238 class SamplerManager : public TypedResourceManager<Sampler, SamplerManager, SamplerID> 239 { 240 public: 241 SamplerID createSampler(); 242 Sampler *getSampler(SamplerID handle) const; 243 bool isSampler(SamplerID sampler) const; 244 checkSamplerAllocation(rx::GLImplFactory * factory,SamplerID handle)245 Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle) 246 { 247 return checkObjectAllocation(factory, handle); 248 } 249 250 static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle); 251 static void DeleteObject(const Context *context, Sampler *sampler); 252 253 protected: 254 ~SamplerManager() override; 255 }; 256 257 class SyncManager : public TypedResourceManager<Sync, SyncManager, SyncID> 258 { 259 public: 260 SyncID createSync(rx::GLImplFactory *factory); 261 Sync *getSync(SyncID handle) const; 262 263 static void DeleteObject(const Context *context, Sync *sync); 264 265 protected: 266 ~SyncManager() override; 267 }; 268 269 class FramebufferManager 270 : public TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID> 271 { 272 public: 273 FramebufferID createFramebuffer(); 274 Framebuffer *getFramebuffer(FramebufferID handle) const; 275 void setDefaultFramebuffer(Framebuffer *framebuffer); 276 Framebuffer *getDefaultFramebuffer() const; 277 278 void invalidateFramebufferCompletenessCache() const; 279 checkFramebufferAllocation(rx::GLImplFactory * factory,const Context * context,FramebufferID handle)280 Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, 281 const Context *context, 282 FramebufferID handle) 283 { 284 return checkObjectAllocation(factory, handle, context); 285 } 286 287 static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, 288 FramebufferID handle, 289 const Context *context); 290 static void DeleteObject(const Context *context, Framebuffer *framebuffer); 291 292 protected: 293 ~FramebufferManager() override; 294 }; 295 296 class ProgramPipelineManager 297 : public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, 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: 313 ~ProgramPipelineManager() override; 314 }; 315 316 class MemoryObjectManager : public ResourceManagerBase 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 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