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