2 // Copyright (c) 2002-2013 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.
7 // ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and
8 // retrieves objects which may be shared by multiple Contexts.
10 #include "libGLESv2/ResourceManager.h"
12 #include "libGLESv2/Buffer.h"
13 #include "libGLESv2/Program.h"
14 #include "libGLESv2/Renderbuffer.h"
15 #include "libGLESv2/Shader.h"
16 #include "libGLESv2/Texture.h"
17 #include "libGLESv2/Sampler.h"
18 #include "libGLESv2/Fence.h"
19 #include "libGLESv2/renderer/Renderer.h"
23 ResourceManager::ResourceManager(rx::Renderer *renderer)
29 ResourceManager::~ResourceManager()
31 while (!mBufferMap.empty())
33 deleteBuffer(mBufferMap.begin()->first);
36 while (!mProgramMap.empty())
38 deleteProgram(mProgramMap.begin()->first);
41 while (!mShaderMap.empty())
43 deleteShader(mShaderMap.begin()->first);
46 while (!mRenderbufferMap.empty())
48 deleteRenderbuffer(mRenderbufferMap.begin()->first);
51 while (!mTextureMap.empty())
53 deleteTexture(mTextureMap.begin()->first);
56 while (!mSamplerMap.empty())
58 deleteSampler(mSamplerMap.begin()->first);
61 while (!mFenceSyncMap.empty())
63 deleteFenceSync(mFenceSyncMap.begin()->first);
67 void ResourceManager::addRef()
72 void ResourceManager::release()
80 // Returns an unused buffer name
81 GLuint ResourceManager::createBuffer()
83 GLuint handle = mBufferHandleAllocator.allocate();
85 mBufferMap[handle] = NULL;
90 // Returns an unused shader/program name
91 GLuint ResourceManager::createShader(GLenum type)
93 GLuint handle = mProgramShaderHandleAllocator.allocate();
95 if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
97 mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
104 // Returns an unused program/shader name
105 GLuint ResourceManager::createProgram()
107 GLuint handle = mProgramShaderHandleAllocator.allocate();
109 mProgramMap[handle] = new Program(mRenderer, this, handle);
114 // Returns an unused texture name
115 GLuint ResourceManager::createTexture()
117 GLuint handle = mTextureHandleAllocator.allocate();
119 mTextureMap[handle] = NULL;
124 // Returns an unused renderbuffer name
125 GLuint ResourceManager::createRenderbuffer()
127 GLuint handle = mRenderbufferHandleAllocator.allocate();
129 mRenderbufferMap[handle] = NULL;
134 // Returns an unused sampler name
135 GLuint ResourceManager::createSampler()
137 GLuint handle = mSamplerHandleAllocator.allocate();
139 mSamplerMap[handle] = NULL;
144 // Returns the next unused fence name, and allocates the fence
145 GLuint ResourceManager::createFenceSync()
147 GLuint handle = mFenceSyncHandleAllocator.allocate();
149 FenceSync *fenceSync = new FenceSync(mRenderer->createFenceSync(), handle);
151 mFenceSyncMap[handle] = fenceSync;
156 void ResourceManager::deleteBuffer(GLuint buffer)
158 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
160 if (bufferObject != mBufferMap.end())
162 mBufferHandleAllocator.release(bufferObject->first);
163 if (bufferObject->second) bufferObject->second->release();
164 mBufferMap.erase(bufferObject);
168 void ResourceManager::deleteShader(GLuint shader)
170 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
172 if (shaderObject != mShaderMap.end())
174 if (shaderObject->second->getRefCount() == 0)
176 mProgramShaderHandleAllocator.release(shaderObject->first);
177 delete shaderObject->second;
178 mShaderMap.erase(shaderObject);
182 shaderObject->second->flagForDeletion();
187 void ResourceManager::deleteProgram(GLuint program)
189 ProgramMap::iterator programObject = mProgramMap.find(program);
191 if (programObject != mProgramMap.end())
193 if (programObject->second->getRefCount() == 0)
195 mProgramShaderHandleAllocator.release(programObject->first);
196 delete programObject->second;
197 mProgramMap.erase(programObject);
201 programObject->second->flagForDeletion();
206 void ResourceManager::deleteTexture(GLuint texture)
208 TextureMap::iterator textureObject = mTextureMap.find(texture);
210 if (textureObject != mTextureMap.end())
212 mTextureHandleAllocator.release(textureObject->first);
213 if (textureObject->second) textureObject->second->release();
214 mTextureMap.erase(textureObject);
218 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
220 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
222 if (renderbufferObject != mRenderbufferMap.end())
224 mRenderbufferHandleAllocator.release(renderbufferObject->first);
225 if (renderbufferObject->second) renderbufferObject->second->release();
226 mRenderbufferMap.erase(renderbufferObject);
230 void ResourceManager::deleteSampler(GLuint sampler)
232 auto samplerObject = mSamplerMap.find(sampler);
234 if (samplerObject != mSamplerMap.end())
236 mSamplerHandleAllocator.release(samplerObject->first);
237 if (samplerObject->second) samplerObject->second->release();
238 mSamplerMap.erase(samplerObject);
242 void ResourceManager::deleteFenceSync(GLuint fenceSync)
244 auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
246 if (fenceObjectIt != mFenceSyncMap.end())
248 mFenceSyncHandleAllocator.release(fenceObjectIt->first);
249 if (fenceObjectIt->second) fenceObjectIt->second->release();
250 mFenceSyncMap.erase(fenceObjectIt);
254 Buffer *ResourceManager::getBuffer(unsigned int handle)
256 BufferMap::iterator buffer = mBufferMap.find(handle);
258 if (buffer == mBufferMap.end())
264 return buffer->second;
268 Shader *ResourceManager::getShader(unsigned int handle)
270 ShaderMap::iterator shader = mShaderMap.find(handle);
272 if (shader == mShaderMap.end())
278 return shader->second;
282 Texture *ResourceManager::getTexture(unsigned int handle)
284 if (handle == 0) return NULL;
286 TextureMap::iterator texture = mTextureMap.find(handle);
288 if (texture == mTextureMap.end())
294 return texture->second;
298 Program *ResourceManager::getProgram(unsigned int handle)
300 ProgramMap::iterator program = mProgramMap.find(handle);
302 if (program == mProgramMap.end())
308 return program->second;
312 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
314 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
316 if (renderbuffer == mRenderbufferMap.end())
322 return renderbuffer->second;
326 Sampler *ResourceManager::getSampler(unsigned int handle)
328 auto sampler = mSamplerMap.find(handle);
330 if (sampler == mSamplerMap.end())
336 return sampler->second;
340 FenceSync *ResourceManager::getFenceSync(unsigned int handle)
342 auto fenceObjectIt = mFenceSyncMap.find(handle);
344 if (fenceObjectIt == mFenceSyncMap.end())
350 return fenceObjectIt->second;
354 void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
356 mRenderbufferMap[handle] = buffer;
359 void ResourceManager::checkBufferAllocation(unsigned int buffer)
361 if (buffer != 0 && !getBuffer(buffer))
363 Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
364 mBufferMap[buffer] = bufferObject;
365 bufferObject->addRef();
369 void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type)
371 if (!getTexture(texture) && texture != 0)
373 Texture *textureObject;
375 if (type == GL_TEXTURE_2D)
377 textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
379 else if (type == GL_TEXTURE_CUBE_MAP)
381 textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
383 else if (type == GL_TEXTURE_3D)
385 textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
387 else if (type == GL_TEXTURE_2D_ARRAY)
389 textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
397 mTextureMap[texture] = textureObject;
398 textureObject->addRef();
402 void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
404 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
406 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
407 mRenderbufferMap[renderbuffer] = renderbufferObject;
408 renderbufferObject->addRef();
412 void ResourceManager::checkSamplerAllocation(GLuint sampler)
414 if (sampler != 0 && !getSampler(sampler))
416 Sampler *samplerObject = new Sampler(sampler);
417 mSamplerMap[sampler] = samplerObject;
418 samplerObject->addRef();
422 bool ResourceManager::isSampler(GLuint sampler)
424 return mSamplerMap.find(sampler) != mSamplerMap.end();