| // 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 "Fence.h" | |
| #include "Program.h" | |
| #include "Renderbuffer.h" | |
| #include "Sampler.h" | |
| #include "Shader.h" | |
| #include "Texture.h" | |
| namespace es2 | |
| { | |
| ResourceManager::ResourceManager() | |
| { | |
| mRefCount = 1; | |
| } | |
| ResourceManager::~ResourceManager() | |
| { | |
| while(!mBufferNameSpace.empty()) | |
| { | |
| deleteBuffer(mBufferNameSpace.firstName()); | |
| } | |
| while(!mProgramNameSpace.empty()) | |
| { | |
| deleteProgram(mProgramNameSpace.firstName()); | |
| } | |
| while(!mShaderNameSpace.empty()) | |
| { | |
| deleteShader(mShaderNameSpace.firstName()); | |
| } | |
| while(!mRenderbufferNameSpace.empty()) | |
| { | |
| deleteRenderbuffer(mRenderbufferNameSpace.firstName()); | |
| } | |
| while(!mTextureNameSpace.empty()) | |
| { | |
| deleteTexture(mTextureNameSpace.firstName()); | |
| } | |
| while(!mSamplerNameSpace.empty()) | |
| { | |
| deleteSampler(mSamplerNameSpace.firstName()); | |
| } | |
| while(!mFenceSyncNameSpace.empty()) | |
| { | |
| deleteFenceSync(mFenceSyncNameSpace.firstName()); | |
| } | |
| } | |
| void ResourceManager::addRef() | |
| { | |
| mRefCount++; | |
| } | |
| void ResourceManager::release() | |
| { | |
| if(--mRefCount == 0) | |
| { | |
| delete this; | |
| } | |
| } | |
| // Returns an unused buffer name | |
| GLuint ResourceManager::createBuffer() | |
| { | |
| return mBufferNameSpace.allocate(); | |
| } | |
| // Returns an unused shader name | |
| GLuint ResourceManager::createShader(GLenum type) | |
| { | |
| GLuint name = mProgramShaderNameSpace.allocate(); | |
| if(type == GL_VERTEX_SHADER) | |
| { | |
| mShaderNameSpace.insert(name, new VertexShader(this, name)); | |
| } | |
| else if(type == GL_FRAGMENT_SHADER) | |
| { | |
| mShaderNameSpace.insert(name, new FragmentShader(this, name)); | |
| } | |
| else UNREACHABLE(type); | |
| return name; | |
| } | |
| // Returns an unused program name | |
| GLuint ResourceManager::createProgram() | |
| { | |
| GLuint name = mProgramShaderNameSpace.allocate(); | |
| mProgramNameSpace.insert(name, new Program(this, name)); | |
| return name; | |
| } | |
| // Returns an unused texture name | |
| GLuint ResourceManager::createTexture() | |
| { | |
| return mTextureNameSpace.allocate(); | |
| } | |
| // Returns an unused renderbuffer name | |
| GLuint ResourceManager::createRenderbuffer() | |
| { | |
| return mRenderbufferNameSpace.allocate(); | |
| } | |
| // Returns an unused sampler name | |
| GLuint ResourceManager::createSampler() | |
| { | |
| return mSamplerNameSpace.allocate(); | |
| } | |
| // Returns the next unused fence name, and allocates the fence | |
| GLuint ResourceManager::createFenceSync(GLenum condition, GLbitfield flags) | |
| { | |
| GLuint name = mFenceSyncNameSpace.allocate(); | |
| FenceSync *fenceSync = new FenceSync(name, condition, flags); | |
| fenceSync->addRef(); | |
| mFenceSyncNameSpace.insert(name, fenceSync); | |
| return name; | |
| } | |
| void ResourceManager::deleteBuffer(GLuint buffer) | |
| { | |
| Buffer *bufferObject = mBufferNameSpace.remove(buffer); | |
| if(bufferObject) | |
| { | |
| bufferObject->release(); | |
| } | |
| } | |
| void ResourceManager::deleteShader(GLuint shader) | |
| { | |
| Shader *shaderObject = mShaderNameSpace.find(shader); | |
| if(shaderObject) | |
| { | |
| if(shaderObject->getRefCount() == 0) | |
| { | |
| delete shaderObject; | |
| mShaderNameSpace.remove(shader); | |
| mProgramShaderNameSpace.remove(shader); | |
| } | |
| else | |
| { | |
| shaderObject->flagForDeletion(); | |
| } | |
| } | |
| } | |
| void ResourceManager::deleteProgram(GLuint program) | |
| { | |
| Program *programObject = mProgramNameSpace.find(program); | |
| if(programObject) | |
| { | |
| if(programObject->getRefCount() == 0) | |
| { | |
| delete programObject; | |
| mProgramNameSpace.remove(program); | |
| mProgramShaderNameSpace.remove(program); | |
| } | |
| else | |
| { | |
| programObject->flagForDeletion(); | |
| } | |
| } | |
| } | |
| void ResourceManager::deleteTexture(GLuint texture) | |
| { | |
| Texture *textureObject = mTextureNameSpace.remove(texture); | |
| if(textureObject) | |
| { | |
| textureObject->release(); | |
| } | |
| } | |
| void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) | |
| { | |
| Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer); | |
| if(renderbufferObject) | |
| { | |
| renderbufferObject->release(); | |
| } | |
| } | |
| void ResourceManager::deleteSampler(GLuint sampler) | |
| { | |
| Sampler *samplerObject = mSamplerNameSpace.remove(sampler); | |
| if(samplerObject) | |
| { | |
| samplerObject->release(); | |
| } | |
| } | |
| void ResourceManager::deleteFenceSync(GLuint fenceSync) | |
| { | |
| FenceSync *fenceObject = mFenceSyncNameSpace.remove(fenceSync); | |
| if(fenceObject) | |
| { | |
| fenceObject->release(); | |
| } | |
| } | |
| Buffer *ResourceManager::getBuffer(unsigned int handle) | |
| { | |
| return mBufferNameSpace.find(handle); | |
| } | |
| Shader *ResourceManager::getShader(unsigned int handle) | |
| { | |
| return mShaderNameSpace.find(handle); | |
| } | |
| Texture *ResourceManager::getTexture(unsigned int handle) | |
| { | |
| return mTextureNameSpace.find(handle); | |
| } | |
| Program *ResourceManager::getProgram(unsigned int handle) | |
| { | |
| return mProgramNameSpace.find(handle); | |
| } | |
| Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) | |
| { | |
| return mRenderbufferNameSpace.find(handle); | |
| } | |
| Sampler *ResourceManager::getSampler(unsigned int handle) | |
| { | |
| return mSamplerNameSpace.find(handle); | |
| } | |
| FenceSync *ResourceManager::getFenceSync(unsigned int handle) | |
| { | |
| return mFenceSyncNameSpace.find(handle); | |
| } | |
| void ResourceManager::checkBufferAllocation(unsigned int buffer) | |
| { | |
| if(buffer != 0 && !getBuffer(buffer)) | |
| { | |
| Buffer *bufferObject = new Buffer(buffer); | |
| bufferObject->addRef(); | |
| mBufferNameSpace.insert(buffer, bufferObject); | |
| } | |
| } | |
| 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 if(type == TEXTURE_EXTERNAL) | |
| { | |
| textureObject = new TextureExternal(texture); | |
| } | |
| else if(type == TEXTURE_3D) | |
| { | |
| textureObject = new Texture3D(texture); | |
| } | |
| else if(type == TEXTURE_2D_ARRAY) | |
| { | |
| textureObject = new Texture2DArray(texture); | |
| } | |
| else if(type == TEXTURE_2D_RECT) | |
| { | |
| textureObject = new Texture2DRect(texture); | |
| } | |
| else | |
| { | |
| UNREACHABLE(type); | |
| return; | |
| } | |
| textureObject->addRef(); | |
| mTextureNameSpace.insert(texture, textureObject); | |
| } | |
| } | |
| void ResourceManager::checkRenderbufferAllocation(GLuint handle) | |
| { | |
| if(handle != 0 && !getRenderbuffer(handle)) | |
| { | |
| Renderbuffer *renderbufferObject = new Renderbuffer(handle, new Colorbuffer(0, 0, GL_NONE, 0)); | |
| renderbufferObject->addRef(); | |
| mRenderbufferNameSpace.insert(handle, renderbufferObject); | |
| } | |
| } | |
| void ResourceManager::checkSamplerAllocation(GLuint sampler) | |
| { | |
| if(sampler != 0 && !getSampler(sampler)) | |
| { | |
| Sampler *samplerObject = new Sampler(sampler); | |
| samplerObject->addRef(); | |
| mSamplerNameSpace.insert(sampler, samplerObject); | |
| } | |
| } | |
| bool ResourceManager::isSampler(GLuint sampler) | |
| { | |
| return mSamplerNameSpace.isReserved(sampler); | |
| } | |
| } |