// Copyright 2016 The SwiftShader Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ResourceManager.cpp: Implements the ResourceManager class, which tracks and // retrieves objects which may be shared by multiple Contexts. #include "ResourceManager.h" #include "Buffer.h" #include "Program.h" #include "Renderbuffer.h" #include "Shader.h" #include "Texture.h" namespace gl { ResourceManager::ResourceManager() { mRefCount = 1; } ResourceManager::~ResourceManager() { while(!mBufferMap.empty()) { deleteBuffer(mBufferMap.begin()->first); } while(!mProgramMap.empty()) { deleteProgram(mProgramMap.begin()->first); } while(!mShaderMap.empty()) { deleteShader(mShaderMap.begin()->first); } while(!mRenderbufferMap.empty()) { deleteRenderbuffer(mRenderbufferMap.begin()->first); } while(!mTextureMap.empty()) { deleteTexture(mTextureMap.begin()->first); } } void ResourceManager::addRef() { mRefCount++; } void ResourceManager::release() { if(--mRefCount == 0) { delete this; } } // Returns an unused buffer name GLuint ResourceManager::createBuffer() { //GLuint handle = mBufferNameSpace.allocate(); unsigned int handle = 1; while (mBufferMap.find(handle) != mBufferMap.end()) { handle++; } mBufferMap[handle] = nullptr; return handle; } // Returns an unused shader/program name GLuint ResourceManager::createShader(GLenum type) { //GLuint handle = mProgramShaderNameSpace.allocate(); unsigned int handle = 1; while (mShaderMap.find(handle) != mShaderMap.end()) { handle++; } if(type == GL_VERTEX_SHADER) { mShaderMap[handle] = new VertexShader(this, handle); } else if(type == GL_FRAGMENT_SHADER) { mShaderMap[handle] = new FragmentShader(this, handle); } else UNREACHABLE(type); return handle; } // Returns an unused program/shader name GLuint ResourceManager::createProgram() { //GLuint handle = mProgramShaderNameSpace.allocate(); unsigned int handle = 1; while (mProgramMap.find(handle) != mProgramMap.end()) { handle++; } mProgramMap[handle] = new Program(this, handle); return handle; } // Returns an unused texture name GLuint ResourceManager::createTexture() { //GLuint handle = mTextureNameSpace.allocate(); unsigned int handle = 1; while (mTextureMap.find(handle) != mTextureMap.end()) { handle++; } mTextureMap[handle] = nullptr; return handle; } // Returns an unused renderbuffer name GLuint ResourceManager::createRenderbuffer() { //GLuint handle = mRenderbufferNameSpace.allocate(); unsigned int handle = 1; while (mRenderbufferMap.find(handle) != mRenderbufferMap.end()) { handle++; } mRenderbufferMap[handle] = nullptr; return handle; } void ResourceManager::deleteBuffer(GLuint buffer) { BufferMap::iterator bufferObject = mBufferMap.find(buffer); if(bufferObject != mBufferMap.end()) { //mBufferNameSpace.release(bufferObject->first); if(bufferObject->second) bufferObject->second->release(); mBufferMap.erase(bufferObject); } } void ResourceManager::deleteShader(GLuint shader) { ShaderMap::iterator shaderObject = mShaderMap.find(shader); if(shaderObject != mShaderMap.end()) { if(shaderObject->second->getRefCount() == 0) { //mProgramShaderNameSpace.release(shaderObject->first); delete shaderObject->second; mShaderMap.erase(shaderObject); } else { shaderObject->second->flagForDeletion(); } } } void ResourceManager::deleteProgram(GLuint program) { ProgramMap::iterator programObject = mProgramMap.find(program); if(programObject != mProgramMap.end()) { if(programObject->second->getRefCount() == 0) { //mProgramShaderNameSpace.release(programObject->first); delete programObject->second; mProgramMap.erase(programObject); } else { programObject->second->flagForDeletion(); } } } void ResourceManager::deleteTexture(GLuint texture) { TextureMap::iterator textureObject = mTextureMap.find(texture); if(textureObject != mTextureMap.end()) { //mTextureNameSpace.release(textureObject->first); if(textureObject->second) textureObject->second->release(); mTextureMap.erase(textureObject); } } void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) { RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer); if(renderbufferObject != mRenderbufferMap.end()) { //mRenderbufferNameSpace.release(renderbufferObject->first); if(renderbufferObject->second) renderbufferObject->second->release(); mRenderbufferMap.erase(renderbufferObject); } } Buffer *ResourceManager::getBuffer(unsigned int handle) { BufferMap::iterator buffer = mBufferMap.find(handle); if(buffer == mBufferMap.end()) { return nullptr; } else { return buffer->second; } } Shader *ResourceManager::getShader(unsigned int handle) { ShaderMap::iterator shader = mShaderMap.find(handle); if(shader == mShaderMap.end()) { return nullptr; } else { return shader->second; } } Texture *ResourceManager::getTexture(unsigned int handle) { if(handle == 0) return nullptr; TextureMap::iterator texture = mTextureMap.find(handle); if(texture == mTextureMap.end()) { return nullptr; } else { return texture->second; } } Program *ResourceManager::getProgram(unsigned int handle) { ProgramMap::iterator program = mProgramMap.find(handle); if(program == mProgramMap.end()) { return nullptr; } else { return program->second; } } Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) { RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle); if(renderbuffer == mRenderbufferMap.end()) { return nullptr; } else { return renderbuffer->second; } } void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) { mRenderbufferMap[handle] = buffer; } void ResourceManager::checkBufferAllocation(unsigned int buffer) { if(buffer != 0 && !getBuffer(buffer)) { Buffer *bufferObject = new Buffer(buffer); mBufferMap[buffer] = bufferObject; bufferObject->addRef(); } } void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) { if(!getTexture(texture) && texture != 0) { Texture *textureObject; if(type == TEXTURE_2D) { textureObject = new Texture2D(texture); } else if(type == TEXTURE_CUBE) { textureObject = new TextureCubeMap(texture); } else { UNREACHABLE(type); return; } mTextureMap[texture] = textureObject; textureObject->addRef(); } } void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer) { if(renderbuffer != 0 && !getRenderbuffer(renderbuffer)) { Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0)); mRenderbufferMap[renderbuffer] = renderbufferObject; renderbufferObject->addRef(); } } }