michael@0: #include "precompiled.h" michael@0: // michael@0: // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and michael@0: // retrieves objects which may be shared by multiple Contexts. michael@0: michael@0: #include "libGLESv2/ResourceManager.h" michael@0: michael@0: #include "libGLESv2/Buffer.h" michael@0: #include "libGLESv2/Program.h" michael@0: #include "libGLESv2/Renderbuffer.h" michael@0: #include "libGLESv2/Shader.h" michael@0: #include "libGLESv2/Texture.h" michael@0: michael@0: namespace gl michael@0: { michael@0: ResourceManager::ResourceManager(rx::Renderer *renderer) michael@0: { michael@0: mRefCount = 1; michael@0: mRenderer = renderer; michael@0: } michael@0: michael@0: ResourceManager::~ResourceManager() michael@0: { michael@0: while (!mBufferMap.empty()) michael@0: { michael@0: deleteBuffer(mBufferMap.begin()->first); michael@0: } michael@0: michael@0: while (!mProgramMap.empty()) michael@0: { michael@0: deleteProgram(mProgramMap.begin()->first); michael@0: } michael@0: michael@0: while (!mShaderMap.empty()) michael@0: { michael@0: deleteShader(mShaderMap.begin()->first); michael@0: } michael@0: michael@0: while (!mRenderbufferMap.empty()) michael@0: { michael@0: deleteRenderbuffer(mRenderbufferMap.begin()->first); michael@0: } michael@0: michael@0: while (!mTextureMap.empty()) michael@0: { michael@0: deleteTexture(mTextureMap.begin()->first); michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::addRef() michael@0: { michael@0: mRefCount++; michael@0: } michael@0: michael@0: void ResourceManager::release() michael@0: { michael@0: if (--mRefCount == 0) michael@0: { michael@0: delete this; michael@0: } michael@0: } michael@0: michael@0: // Returns an unused buffer name michael@0: GLuint ResourceManager::createBuffer() michael@0: { michael@0: GLuint handle = mBufferHandleAllocator.allocate(); michael@0: michael@0: mBufferMap[handle] = NULL; michael@0: michael@0: return handle; michael@0: } michael@0: michael@0: // Returns an unused shader/program name michael@0: GLuint ResourceManager::createShader(GLenum type) michael@0: { michael@0: GLuint handle = mProgramShaderHandleAllocator.allocate(); michael@0: michael@0: if (type == GL_VERTEX_SHADER) michael@0: { michael@0: mShaderMap[handle] = new VertexShader(this, mRenderer, handle); michael@0: } michael@0: else if (type == GL_FRAGMENT_SHADER) michael@0: { michael@0: mShaderMap[handle] = new FragmentShader(this, mRenderer, handle); michael@0: } michael@0: else UNREACHABLE(); michael@0: michael@0: return handle; michael@0: } michael@0: michael@0: // Returns an unused program/shader name michael@0: GLuint ResourceManager::createProgram() michael@0: { michael@0: GLuint handle = mProgramShaderHandleAllocator.allocate(); michael@0: michael@0: mProgramMap[handle] = new Program(mRenderer, this, handle); michael@0: michael@0: return handle; michael@0: } michael@0: michael@0: // Returns an unused texture name michael@0: GLuint ResourceManager::createTexture() michael@0: { michael@0: GLuint handle = mTextureHandleAllocator.allocate(); michael@0: michael@0: mTextureMap[handle] = NULL; michael@0: michael@0: return handle; michael@0: } michael@0: michael@0: // Returns an unused renderbuffer name michael@0: GLuint ResourceManager::createRenderbuffer() michael@0: { michael@0: GLuint handle = mRenderbufferHandleAllocator.allocate(); michael@0: michael@0: mRenderbufferMap[handle] = NULL; michael@0: michael@0: return handle; michael@0: } michael@0: michael@0: void ResourceManager::deleteBuffer(GLuint buffer) michael@0: { michael@0: BufferMap::iterator bufferObject = mBufferMap.find(buffer); michael@0: michael@0: if (bufferObject != mBufferMap.end()) michael@0: { michael@0: mBufferHandleAllocator.release(bufferObject->first); michael@0: if (bufferObject->second) bufferObject->second->release(); michael@0: mBufferMap.erase(bufferObject); michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::deleteShader(GLuint shader) michael@0: { michael@0: ShaderMap::iterator shaderObject = mShaderMap.find(shader); michael@0: michael@0: if (shaderObject != mShaderMap.end()) michael@0: { michael@0: if (shaderObject->second->getRefCount() == 0) michael@0: { michael@0: mProgramShaderHandleAllocator.release(shaderObject->first); michael@0: delete shaderObject->second; michael@0: mShaderMap.erase(shaderObject); michael@0: } michael@0: else michael@0: { michael@0: shaderObject->second->flagForDeletion(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::deleteProgram(GLuint program) michael@0: { michael@0: ProgramMap::iterator programObject = mProgramMap.find(program); michael@0: michael@0: if (programObject != mProgramMap.end()) michael@0: { michael@0: if (programObject->second->getRefCount() == 0) michael@0: { michael@0: mProgramShaderHandleAllocator.release(programObject->first); michael@0: delete programObject->second; michael@0: mProgramMap.erase(programObject); michael@0: } michael@0: else michael@0: { michael@0: programObject->second->flagForDeletion(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::deleteTexture(GLuint texture) michael@0: { michael@0: TextureMap::iterator textureObject = mTextureMap.find(texture); michael@0: michael@0: if (textureObject != mTextureMap.end()) michael@0: { michael@0: mTextureHandleAllocator.release(textureObject->first); michael@0: if (textureObject->second) textureObject->second->release(); michael@0: mTextureMap.erase(textureObject); michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) michael@0: { michael@0: RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer); michael@0: michael@0: if (renderbufferObject != mRenderbufferMap.end()) michael@0: { michael@0: mRenderbufferHandleAllocator.release(renderbufferObject->first); michael@0: if (renderbufferObject->second) renderbufferObject->second->release(); michael@0: mRenderbufferMap.erase(renderbufferObject); michael@0: } michael@0: } michael@0: michael@0: Buffer *ResourceManager::getBuffer(unsigned int handle) michael@0: { michael@0: BufferMap::iterator buffer = mBufferMap.find(handle); michael@0: michael@0: if (buffer == mBufferMap.end()) michael@0: { michael@0: return NULL; michael@0: } michael@0: else michael@0: { michael@0: return buffer->second; michael@0: } michael@0: } michael@0: michael@0: Shader *ResourceManager::getShader(unsigned int handle) michael@0: { michael@0: ShaderMap::iterator shader = mShaderMap.find(handle); michael@0: michael@0: if (shader == mShaderMap.end()) michael@0: { michael@0: return NULL; michael@0: } michael@0: else michael@0: { michael@0: return shader->second; michael@0: } michael@0: } michael@0: michael@0: Texture *ResourceManager::getTexture(unsigned int handle) michael@0: { michael@0: if (handle == 0) return NULL; michael@0: michael@0: TextureMap::iterator texture = mTextureMap.find(handle); michael@0: michael@0: if (texture == mTextureMap.end()) michael@0: { michael@0: return NULL; michael@0: } michael@0: else michael@0: { michael@0: return texture->second; michael@0: } michael@0: } michael@0: michael@0: Program *ResourceManager::getProgram(unsigned int handle) michael@0: { michael@0: ProgramMap::iterator program = mProgramMap.find(handle); michael@0: michael@0: if (program == mProgramMap.end()) michael@0: { michael@0: return NULL; michael@0: } michael@0: else michael@0: { michael@0: return program->second; michael@0: } michael@0: } michael@0: michael@0: Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) michael@0: { michael@0: RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle); michael@0: michael@0: if (renderbuffer == mRenderbufferMap.end()) michael@0: { michael@0: return NULL; michael@0: } michael@0: else michael@0: { michael@0: return renderbuffer->second; michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) michael@0: { michael@0: mRenderbufferMap[handle] = buffer; michael@0: } michael@0: michael@0: void ResourceManager::checkBufferAllocation(unsigned int buffer) michael@0: { michael@0: if (buffer != 0 && !getBuffer(buffer)) michael@0: { michael@0: Buffer *bufferObject = new Buffer(mRenderer, buffer); michael@0: mBufferMap[buffer] = bufferObject; michael@0: bufferObject->addRef(); michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) michael@0: { michael@0: if (!getTexture(texture) && texture != 0) michael@0: { michael@0: Texture *textureObject; michael@0: michael@0: if (type == TEXTURE_2D) michael@0: { michael@0: textureObject = new Texture2D(mRenderer, texture); michael@0: } michael@0: else if (type == TEXTURE_CUBE) michael@0: { michael@0: textureObject = new TextureCubeMap(mRenderer, texture); michael@0: } michael@0: else michael@0: { michael@0: UNREACHABLE(); michael@0: return; michael@0: } michael@0: michael@0: mTextureMap[texture] = textureObject; michael@0: textureObject->addRef(); michael@0: } michael@0: } michael@0: michael@0: void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer) michael@0: { michael@0: if (renderbuffer != 0 && !getRenderbuffer(renderbuffer)) michael@0: { michael@0: Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0)); michael@0: mRenderbufferMap[renderbuffer] = renderbufferObject; michael@0: renderbufferObject->addRef(); michael@0: } michael@0: } michael@0: michael@0: }