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, GLuint> 258 { 259 public: 260 GLuint createSync(rx::GLImplFactory *factory); 261 Sync *getSync(GLuint 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 Caps & caps,FramebufferID handle,egl::ShareGroup * shareGroup)280 Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, 281 const Caps &caps, 282 FramebufferID handle, 283 egl::ShareGroup *shareGroup) 284 { 285 return checkObjectAllocation<const Caps &>(factory, handle, caps, shareGroup); 286 } 287 288 static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, 289 FramebufferID handle, 290 const Caps &caps, 291 egl::ShareGroup *shareGroup); 292 static void DeleteObject(const Context *context, Framebuffer *framebuffer); 293 294 protected: 295 ~FramebufferManager() override; 296 }; 297 298 class ProgramPipelineManager 299 : public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID> 300 { 301 public: 302 ProgramPipelineID createProgramPipeline(); 303 ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; 304 checkProgramPipelineAllocation(rx::GLImplFactory * factory,ProgramPipelineID handle)305 ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, 306 ProgramPipelineID handle) 307 { 308 return checkObjectAllocation(factory, handle); 309 } 310 311 static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle); 312 static void DeleteObject(const Context *context, ProgramPipeline *pipeline); 313 314 protected: 315 ~ProgramPipelineManager() override; 316 }; 317 318 class MemoryObjectManager : public ResourceManagerBase 319 { 320 public: 321 MemoryObjectManager(); 322 323 MemoryObjectID createMemoryObject(rx::GLImplFactory *factory); 324 void deleteMemoryObject(const Context *context, MemoryObjectID handle); 325 MemoryObject *getMemoryObject(MemoryObjectID handle) const; 326 327 protected: 328 ~MemoryObjectManager() override; 329 330 private: 331 void reset(const Context *context) override; 332 333 ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects; 334 }; 335 336 class SemaphoreManager : public ResourceManagerBase 337 { 338 public: 339 SemaphoreManager(); 340 341 SemaphoreID createSemaphore(rx::GLImplFactory *factory); 342 void deleteSemaphore(const Context *context, SemaphoreID handle); 343 Semaphore *getSemaphore(SemaphoreID handle) const; 344 345 protected: 346 ~SemaphoreManager() override; 347 348 private: 349 void reset(const Context *context) override; 350 351 ResourceMap<Semaphore, SemaphoreID> mSemaphores; 352 }; 353 } // namespace gl 354 355 #endif // LIBANGLE_RESOURCEMANAGER_H_ 356