|  | // 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(); | 
|  | } | 
|  | } | 
|  |  | 
|  | } |