• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.cpp: Implements the the ResourceManager classes, which handle allocation and
8 // lifetime of GL objects.
9 
10 #include "libANGLE/ResourceManager.h"
11 
12 #include "libANGLE/Buffer.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/Fence.h"
15 #include "libANGLE/MemoryObject.h"
16 #include "libANGLE/Program.h"
17 #include "libANGLE/ProgramPipeline.h"
18 #include "libANGLE/Query.h"
19 #include "libANGLE/Renderbuffer.h"
20 #include "libANGLE/Sampler.h"
21 #include "libANGLE/Semaphore.h"
22 #include "libANGLE/Shader.h"
23 #include "libANGLE/Texture.h"
24 #include "libANGLE/renderer/ContextImpl.h"
25 
26 namespace gl
27 {
28 
29 namespace
30 {
31 
32 template <typename ResourceType, typename IDType>
AllocateEmptyObject(HandleAllocator * handleAllocator,ResourceMap<ResourceType,IDType> * objectMap)33 IDType AllocateEmptyObject(HandleAllocator *handleAllocator,
34                            ResourceMap<ResourceType, IDType> *objectMap)
35 {
36     IDType handle = FromGL<IDType>(handleAllocator->allocate());
37     objectMap->assign(handle, nullptr);
38     return handle;
39 }
40 
41 }  // anonymous namespace
42 
43 template <typename HandleAllocatorType>
ResourceManagerBase()44 ResourceManagerBase<HandleAllocatorType>::ResourceManagerBase() : mRefCount(1)
45 {}
46 
47 template <typename HandleAllocatorType>
addRef()48 void ResourceManagerBase<HandleAllocatorType>::addRef()
49 {
50     mRefCount++;
51 }
52 
53 template <typename HandleAllocatorType>
release(const Context * context)54 void ResourceManagerBase<HandleAllocatorType>::release(const Context *context)
55 {
56     if (--mRefCount == 0)
57     {
58         reset(context);
59         delete this;
60     }
61 }
62 
63 template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType>
~TypedResourceManager()64 TypedResourceManager<ResourceType, HandleAllocatorType, ImplT, IDType>::~TypedResourceManager()
65 {
66     ASSERT(mObjectMap.empty());
67 }
68 
69 template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType>
reset(const Context * context)70 void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT, IDType>::reset(
71     const Context *context)
72 {
73     this->mHandleAllocator.reset();
74     for (const auto &resource : mObjectMap)
75     {
76         if (resource.second)
77         {
78             ImplT::DeleteObject(context, resource.second);
79         }
80     }
81     mObjectMap.clear();
82 }
83 
84 template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType>
deleteObject(const Context * context,IDType handle)85 void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT, IDType>::deleteObject(
86     const Context *context,
87     IDType handle)
88 {
89     ResourceType *resource = nullptr;
90     if (!mObjectMap.erase(handle, &resource))
91     {
92         return;
93     }
94 
95     // Requires an explicit this-> because of C++ template rules.
96     this->mHandleAllocator.release(GetIDValue(handle));
97 
98     if (resource)
99     {
100         ImplT::DeleteObject(context, resource);
101     }
102 }
103 
104 template class ResourceManagerBase<HandleAllocator>;
105 template class TypedResourceManager<Buffer, HandleAllocator, BufferManager, BufferID>;
106 template class TypedResourceManager<Texture, HandleAllocator, TextureManager, TextureID>;
107 template class TypedResourceManager<Renderbuffer,
108                                     HandleAllocator,
109                                     RenderbufferManager,
110                                     RenderbufferID>;
111 template class TypedResourceManager<Sampler, HandleAllocator, SamplerManager, SamplerID>;
112 template class TypedResourceManager<Sync, HandleAllocator, SyncManager, GLuint>;
113 template class TypedResourceManager<Framebuffer,
114                                     HandleAllocator,
115                                     FramebufferManager,
116                                     FramebufferID>;
117 template class TypedResourceManager<ProgramPipeline,
118                                     HandleAllocator,
119                                     ProgramPipelineManager,
120                                     ProgramPipelineID>;
121 
122 // BufferManager Implementation.
123 
124 // static
AllocateNewObject(rx::GLImplFactory * factory,BufferID handle)125 Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, BufferID handle)
126 {
127     Buffer *buffer = new Buffer(factory, handle);
128     buffer->addRef();
129     return buffer;
130 }
131 
132 // static
DeleteObject(const Context * context,Buffer * buffer)133 void BufferManager::DeleteObject(const Context *context, Buffer *buffer)
134 {
135     buffer->release(context);
136 }
137 
createBuffer()138 BufferID BufferManager::createBuffer()
139 {
140     return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
141 }
142 
getBuffer(BufferID handle) const143 Buffer *BufferManager::getBuffer(BufferID handle) const
144 {
145     return mObjectMap.query(handle);
146 }
147 
148 // ShaderProgramManager Implementation.
149 
ShaderProgramManager()150 ShaderProgramManager::ShaderProgramManager() {}
151 
~ShaderProgramManager()152 ShaderProgramManager::~ShaderProgramManager()
153 {
154     ASSERT(mPrograms.empty());
155     ASSERT(mShaders.empty());
156 }
157 
reset(const Context * context)158 void ShaderProgramManager::reset(const Context *context)
159 {
160     while (!mPrograms.empty())
161     {
162         deleteProgram(context, {mPrograms.begin()->first});
163     }
164     mPrograms.clear();
165     while (!mShaders.empty())
166     {
167         deleteShader(context, {mShaders.begin()->first});
168     }
169     mShaders.clear();
170 }
171 
createShader(rx::GLImplFactory * factory,const gl::Limitations & rendererLimitations,ShaderType type)172 ShaderProgramID ShaderProgramManager::createShader(rx::GLImplFactory *factory,
173                                                    const gl::Limitations &rendererLimitations,
174                                                    ShaderType type)
175 {
176     ASSERT(type != ShaderType::InvalidEnum);
177     ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()};
178     mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle));
179     return handle;
180 }
181 
deleteShader(const Context * context,ShaderProgramID shader)182 void ShaderProgramManager::deleteShader(const Context *context, ShaderProgramID shader)
183 {
184     deleteObject(context, &mShaders, shader);
185 }
186 
getShader(ShaderProgramID handle) const187 Shader *ShaderProgramManager::getShader(ShaderProgramID handle) const
188 {
189     return mShaders.query(handle);
190 }
191 
createProgram(rx::GLImplFactory * factory)192 ShaderProgramID ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
193 {
194     ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()};
195     mPrograms.assign(handle, new Program(factory, this, handle));
196     return handle;
197 }
198 
deleteProgram(const gl::Context * context,ShaderProgramID program)199 void ShaderProgramManager::deleteProgram(const gl::Context *context, ShaderProgramID program)
200 {
201     deleteObject(context, &mPrograms, program);
202 }
203 
204 template <typename ObjectType, typename IDType>
deleteObject(const Context * context,ResourceMap<ObjectType,IDType> * objectMap,IDType id)205 void ShaderProgramManager::deleteObject(const Context *context,
206                                         ResourceMap<ObjectType, IDType> *objectMap,
207                                         IDType id)
208 {
209     ObjectType *object = objectMap->query(id);
210     if (!object)
211     {
212         return;
213     }
214 
215     if (object->getRefCount() == 0)
216     {
217         mHandleAllocator.release(id.value);
218         object->onDestroy(context);
219         objectMap->erase(id, &object);
220     }
221     else
222     {
223         object->flagForDeletion();
224     }
225 }
226 
227 // TextureManager Implementation.
228 
229 // static
AllocateNewObject(rx::GLImplFactory * factory,TextureID handle,TextureType type)230 Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory,
231                                            TextureID handle,
232                                            TextureType type)
233 {
234     Texture *texture = new Texture(factory, handle, type);
235     texture->addRef();
236     return texture;
237 }
238 
239 // static
DeleteObject(const Context * context,Texture * texture)240 void TextureManager::DeleteObject(const Context *context, Texture *texture)
241 {
242     texture->release(context);
243 }
244 
createTexture()245 TextureID TextureManager::createTexture()
246 {
247     return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
248 }
249 
signalAllTexturesDirty() const250 void TextureManager::signalAllTexturesDirty() const
251 {
252     for (const auto &texture : mObjectMap)
253     {
254         if (texture.second)
255         {
256             // We don't know if the Texture needs init, but that's ok, since it will only force
257             // a re-check, and will not initialize the pixels if it's not needed.
258             texture.second->signalDirtyStorage(InitState::MayNeedInit);
259         }
260     }
261 }
262 
enableHandleAllocatorLogging()263 void TextureManager::enableHandleAllocatorLogging()
264 {
265     mHandleAllocator.enableLogging(true);
266 }
267 
268 // RenderbufferManager Implementation.
269 
270 // static
AllocateNewObject(rx::GLImplFactory * factory,RenderbufferID handle)271 Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory,
272                                                      RenderbufferID handle)
273 {
274     Renderbuffer *renderbuffer = new Renderbuffer(factory, handle);
275     renderbuffer->addRef();
276     return renderbuffer;
277 }
278 
279 // static
DeleteObject(const Context * context,Renderbuffer * renderbuffer)280 void RenderbufferManager::DeleteObject(const Context *context, Renderbuffer *renderbuffer)
281 {
282     renderbuffer->release(context);
283 }
284 
createRenderbuffer()285 RenderbufferID RenderbufferManager::createRenderbuffer()
286 {
287     return {AllocateEmptyObject(&mHandleAllocator, &mObjectMap)};
288 }
289 
getRenderbuffer(RenderbufferID handle) const290 Renderbuffer *RenderbufferManager::getRenderbuffer(RenderbufferID handle) const
291 {
292     return mObjectMap.query(handle);
293 }
294 
295 // SamplerManager Implementation.
296 
297 // static
AllocateNewObject(rx::GLImplFactory * factory,SamplerID handle)298 Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle)
299 {
300     Sampler *sampler = new Sampler(factory, handle);
301     sampler->addRef();
302     return sampler;
303 }
304 
305 // static
DeleteObject(const Context * context,Sampler * sampler)306 void SamplerManager::DeleteObject(const Context *context, Sampler *sampler)
307 {
308     sampler->release(context);
309 }
310 
createSampler()311 SamplerID SamplerManager::createSampler()
312 {
313     return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
314 }
315 
getSampler(SamplerID handle) const316 Sampler *SamplerManager::getSampler(SamplerID handle) const
317 {
318     return mObjectMap.query(handle);
319 }
320 
isSampler(SamplerID sampler) const321 bool SamplerManager::isSampler(SamplerID sampler) const
322 {
323     return mObjectMap.contains(sampler);
324 }
325 
326 // SyncManager Implementation.
327 
328 // static
DeleteObject(const Context * context,Sync * sync)329 void SyncManager::DeleteObject(const Context *context, Sync *sync)
330 {
331     sync->release(context);
332 }
333 
createSync(rx::GLImplFactory * factory)334 GLuint SyncManager::createSync(rx::GLImplFactory *factory)
335 {
336     GLuint handle = mHandleAllocator.allocate();
337     Sync *sync    = new Sync(factory, handle);
338     sync->addRef();
339     mObjectMap.assign(handle, sync);
340     return handle;
341 }
342 
getSync(GLuint handle) const343 Sync *SyncManager::getSync(GLuint handle) const
344 {
345     return mObjectMap.query(handle);
346 }
347 
348 // FramebufferManager Implementation.
349 
350 // static
AllocateNewObject(rx::GLImplFactory * factory,FramebufferID handle,const Caps & caps,ContextID owningContextID)351 Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
352                                                    FramebufferID handle,
353                                                    const Caps &caps,
354                                                    ContextID owningContextID)
355 {
356     // Make sure the caller isn't using a reserved handle.
357     ASSERT(handle != Framebuffer::kDefaultDrawFramebufferHandle);
358     return new Framebuffer(caps, factory, handle, owningContextID);
359 }
360 
361 // static
DeleteObject(const Context * context,Framebuffer * framebuffer)362 void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer)
363 {
364     framebuffer->onDestroy(context);
365     delete framebuffer;
366 }
367 
createFramebuffer()368 FramebufferID FramebufferManager::createFramebuffer()
369 {
370     return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
371 }
372 
getFramebuffer(FramebufferID handle) const373 Framebuffer *FramebufferManager::getFramebuffer(FramebufferID handle) const
374 {
375     return mObjectMap.query(handle);
376 }
377 
setDefaultFramebuffer(Framebuffer * framebuffer)378 void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer)
379 {
380     ASSERT(framebuffer == nullptr || framebuffer->isDefault());
381     mObjectMap.assign(Framebuffer::kDefaultDrawFramebufferHandle, framebuffer);
382 }
383 
invalidateFramebufferCompletenessCache() const384 void FramebufferManager::invalidateFramebufferCompletenessCache() const
385 {
386     for (const auto &framebuffer : mObjectMap)
387     {
388         if (framebuffer.second)
389         {
390             framebuffer.second->invalidateCompletenessCache();
391         }
392     }
393 }
394 
395 // ProgramPipelineManager Implementation.
396 
397 // static
AllocateNewObject(rx::GLImplFactory * factory,ProgramPipelineID handle)398 ProgramPipeline *ProgramPipelineManager::AllocateNewObject(rx::GLImplFactory *factory,
399                                                            ProgramPipelineID handle)
400 {
401     ProgramPipeline *pipeline = new ProgramPipeline(factory, handle);
402     pipeline->addRef();
403     return pipeline;
404 }
405 
406 // static
DeleteObject(const Context * context,ProgramPipeline * pipeline)407 void ProgramPipelineManager::DeleteObject(const Context *context, ProgramPipeline *pipeline)
408 {
409     pipeline->release(context);
410 }
411 
createProgramPipeline()412 ProgramPipelineID ProgramPipelineManager::createProgramPipeline()
413 {
414     return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
415 }
416 
getProgramPipeline(ProgramPipelineID handle) const417 ProgramPipeline *ProgramPipelineManager::getProgramPipeline(ProgramPipelineID handle) const
418 {
419     return mObjectMap.query(handle);
420 }
421 
422 // MemoryObjectManager Implementation.
423 
MemoryObjectManager()424 MemoryObjectManager::MemoryObjectManager() {}
425 
~MemoryObjectManager()426 MemoryObjectManager::~MemoryObjectManager()
427 {
428     ASSERT(mMemoryObjects.empty());
429 }
430 
reset(const Context * context)431 void MemoryObjectManager::reset(const Context *context)
432 {
433     while (!mMemoryObjects.empty())
434     {
435         deleteMemoryObject(context, {mMemoryObjects.begin()->first});
436     }
437     mMemoryObjects.clear();
438 }
439 
createMemoryObject(rx::GLImplFactory * factory)440 MemoryObjectID MemoryObjectManager::createMemoryObject(rx::GLImplFactory *factory)
441 {
442     MemoryObjectID handle      = MemoryObjectID{mHandleAllocator.allocate()};
443     MemoryObject *memoryObject = new MemoryObject(factory, handle);
444     memoryObject->addRef();
445     mMemoryObjects.assign(handle, memoryObject);
446     return handle;
447 }
448 
deleteMemoryObject(const Context * context,MemoryObjectID handle)449 void MemoryObjectManager::deleteMemoryObject(const Context *context, MemoryObjectID handle)
450 {
451     MemoryObject *memoryObject = nullptr;
452     if (!mMemoryObjects.erase(handle, &memoryObject))
453     {
454         return;
455     }
456 
457     // Requires an explicit this-> because of C++ template rules.
458     this->mHandleAllocator.release(handle.value);
459 
460     if (memoryObject)
461     {
462         memoryObject->release(context);
463     }
464 }
465 
getMemoryObject(MemoryObjectID handle) const466 MemoryObject *MemoryObjectManager::getMemoryObject(MemoryObjectID handle) const
467 {
468     return mMemoryObjects.query(handle);
469 }
470 
471 // SemaphoreManager Implementation.
472 
SemaphoreManager()473 SemaphoreManager::SemaphoreManager() {}
474 
~SemaphoreManager()475 SemaphoreManager::~SemaphoreManager()
476 {
477     ASSERT(mSemaphores.empty());
478 }
479 
reset(const Context * context)480 void SemaphoreManager::reset(const Context *context)
481 {
482     while (!mSemaphores.empty())
483     {
484         deleteSemaphore(context, {mSemaphores.begin()->first});
485     }
486     mSemaphores.clear();
487 }
488 
createSemaphore(rx::GLImplFactory * factory)489 SemaphoreID SemaphoreManager::createSemaphore(rx::GLImplFactory *factory)
490 {
491     SemaphoreID handle   = SemaphoreID{mHandleAllocator.allocate()};
492     Semaphore *semaphore = new Semaphore(factory, handle);
493     semaphore->addRef();
494     mSemaphores.assign(handle, semaphore);
495     return handle;
496 }
497 
deleteSemaphore(const Context * context,SemaphoreID handle)498 void SemaphoreManager::deleteSemaphore(const Context *context, SemaphoreID handle)
499 {
500     Semaphore *semaphore = nullptr;
501     if (!mSemaphores.erase(handle, &semaphore))
502     {
503         return;
504     }
505 
506     // Requires an explicit this-> because of C++ template rules.
507     this->mHandleAllocator.release(handle.value);
508 
509     if (semaphore)
510     {
511         semaphore->release(context);
512     }
513 }
514 
getSemaphore(SemaphoreID handle) const515 Semaphore *SemaphoreManager::getSemaphore(SemaphoreID handle) const
516 {
517     return mSemaphores.query(handle);
518 }
519 }  // namespace gl
520