1// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// ResourceManager.cpp: Implements the ResourceManager class, which tracks and 16// retrieves objects which may be shared by multiple Contexts. 17 18#include "ResourceManager.h" 19 20#include "Buffer.h" 21#include "Program.h" 22#include "Renderbuffer.h" 23#include "Shader.h" 24#include "Texture.h" 25 26namespace gl 27{ 28ResourceManager::ResourceManager() 29{ 30 mRefCount = 1; 31} 32 33ResourceManager::~ResourceManager() 34{ 35 while(!mBufferMap.empty()) 36 { 37 deleteBuffer(mBufferMap.begin()->first); 38 } 39 40 while(!mProgramMap.empty()) 41 { 42 deleteProgram(mProgramMap.begin()->first); 43 } 44 45 while(!mShaderMap.empty()) 46 { 47 deleteShader(mShaderMap.begin()->first); 48 } 49 50 while(!mRenderbufferMap.empty()) 51 { 52 deleteRenderbuffer(mRenderbufferMap.begin()->first); 53 } 54 55 while(!mTextureMap.empty()) 56 { 57 deleteTexture(mTextureMap.begin()->first); 58 } 59} 60 61void ResourceManager::addRef() 62{ 63 mRefCount++; 64} 65 66void ResourceManager::release() 67{ 68 if(--mRefCount == 0) 69 { 70 delete this; 71 } 72} 73 74// Returns an unused buffer name 75GLuint ResourceManager::createBuffer() 76{ 77 //GLuint handle = mBufferNameSpace.allocate(); 78 unsigned int handle = 1; 79 80 while (mBufferMap.find(handle) != mBufferMap.end()) 81 { 82 handle++; 83 } 84 85 mBufferMap[handle] = nullptr; 86 87 return handle; 88} 89 90// Returns an unused shader/program name 91GLuint ResourceManager::createShader(GLenum type) 92{ 93 //GLuint handle = mProgramShaderNameSpace.allocate(); 94 unsigned int handle = 1; 95 96 while (mShaderMap.find(handle) != mShaderMap.end()) 97 { 98 handle++; 99 } 100 101 if(type == GL_VERTEX_SHADER) 102 { 103 mShaderMap[handle] = new VertexShader(this, handle); 104 } 105 else if(type == GL_FRAGMENT_SHADER) 106 { 107 mShaderMap[handle] = new FragmentShader(this, handle); 108 } 109 else UNREACHABLE(type); 110 111 return handle; 112} 113 114// Returns an unused program/shader name 115GLuint ResourceManager::createProgram() 116{ 117 //GLuint handle = mProgramShaderNameSpace.allocate(); 118 unsigned int handle = 1; 119 120 while (mProgramMap.find(handle) != mProgramMap.end()) 121 { 122 handle++; 123 } 124 125 mProgramMap[handle] = new Program(this, handle); 126 127 return handle; 128} 129 130// Returns an unused texture name 131GLuint ResourceManager::createTexture() 132{ 133 //GLuint handle = mTextureNameSpace.allocate(); 134 unsigned int handle = 1; 135 136 while (mTextureMap.find(handle) != mTextureMap.end()) 137 { 138 handle++; 139 } 140 141 mTextureMap[handle] = nullptr; 142 143 return handle; 144} 145 146// Returns an unused renderbuffer name 147GLuint ResourceManager::createRenderbuffer() 148{ 149 //GLuint handle = mRenderbufferNameSpace.allocate(); 150 unsigned int handle = 1; 151 152 while (mRenderbufferMap.find(handle) != mRenderbufferMap.end()) 153 { 154 handle++; 155 } 156 157 mRenderbufferMap[handle] = nullptr; 158 159 return handle; 160} 161 162void ResourceManager::deleteBuffer(GLuint buffer) 163{ 164 BufferMap::iterator bufferObject = mBufferMap.find(buffer); 165 166 if(bufferObject != mBufferMap.end()) 167 { 168 //mBufferNameSpace.release(bufferObject->first); 169 if(bufferObject->second) bufferObject->second->release(); 170 mBufferMap.erase(bufferObject); 171 } 172} 173 174void ResourceManager::deleteShader(GLuint shader) 175{ 176 ShaderMap::iterator shaderObject = mShaderMap.find(shader); 177 178 if(shaderObject != mShaderMap.end()) 179 { 180 if(shaderObject->second->getRefCount() == 0) 181 { 182 //mProgramShaderNameSpace.release(shaderObject->first); 183 delete shaderObject->second; 184 mShaderMap.erase(shaderObject); 185 } 186 else 187 { 188 shaderObject->second->flagForDeletion(); 189 } 190 } 191} 192 193void ResourceManager::deleteProgram(GLuint program) 194{ 195 ProgramMap::iterator programObject = mProgramMap.find(program); 196 197 if(programObject != mProgramMap.end()) 198 { 199 if(programObject->second->getRefCount() == 0) 200 { 201 //mProgramShaderNameSpace.release(programObject->first); 202 delete programObject->second; 203 mProgramMap.erase(programObject); 204 } 205 else 206 { 207 programObject->second->flagForDeletion(); 208 } 209 } 210} 211 212void ResourceManager::deleteTexture(GLuint texture) 213{ 214 TextureMap::iterator textureObject = mTextureMap.find(texture); 215 216 if(textureObject != mTextureMap.end()) 217 { 218 //mTextureNameSpace.release(textureObject->first); 219 if(textureObject->second) textureObject->second->release(); 220 mTextureMap.erase(textureObject); 221 } 222} 223 224void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) 225{ 226 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer); 227 228 if(renderbufferObject != mRenderbufferMap.end()) 229 { 230 //mRenderbufferNameSpace.release(renderbufferObject->first); 231 if(renderbufferObject->second) renderbufferObject->second->release(); 232 mRenderbufferMap.erase(renderbufferObject); 233 } 234} 235 236Buffer *ResourceManager::getBuffer(unsigned int handle) 237{ 238 BufferMap::iterator buffer = mBufferMap.find(handle); 239 240 if(buffer == mBufferMap.end()) 241 { 242 return nullptr; 243 } 244 else 245 { 246 return buffer->second; 247 } 248} 249 250Shader *ResourceManager::getShader(unsigned int handle) 251{ 252 ShaderMap::iterator shader = mShaderMap.find(handle); 253 254 if(shader == mShaderMap.end()) 255 { 256 return nullptr; 257 } 258 else 259 { 260 return shader->second; 261 } 262} 263 264Texture *ResourceManager::getTexture(unsigned int handle) 265{ 266 if(handle == 0) return nullptr; 267 268 TextureMap::iterator texture = mTextureMap.find(handle); 269 270 if(texture == mTextureMap.end()) 271 { 272 return nullptr; 273 } 274 else 275 { 276 return texture->second; 277 } 278} 279 280Program *ResourceManager::getProgram(unsigned int handle) 281{ 282 ProgramMap::iterator program = mProgramMap.find(handle); 283 284 if(program == mProgramMap.end()) 285 { 286 return nullptr; 287 } 288 else 289 { 290 return program->second; 291 } 292} 293 294Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) 295{ 296 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle); 297 298 if(renderbuffer == mRenderbufferMap.end()) 299 { 300 return nullptr; 301 } 302 else 303 { 304 return renderbuffer->second; 305 } 306} 307 308void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) 309{ 310 mRenderbufferMap[handle] = buffer; 311} 312 313void ResourceManager::checkBufferAllocation(unsigned int buffer) 314{ 315 if(buffer != 0 && !getBuffer(buffer)) 316 { 317 Buffer *bufferObject = new Buffer(buffer); 318 mBufferMap[buffer] = bufferObject; 319 bufferObject->addRef(); 320 } 321} 322 323void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) 324{ 325 if(!getTexture(texture) && texture != 0) 326 { 327 Texture *textureObject; 328 329 if(type == TEXTURE_2D) 330 { 331 textureObject = new Texture2D(texture); 332 } 333 else if(type == TEXTURE_CUBE) 334 { 335 textureObject = new TextureCubeMap(texture); 336 } 337 else 338 { 339 UNREACHABLE(type); 340 return; 341 } 342 343 mTextureMap[texture] = textureObject; 344 textureObject->addRef(); 345 } 346} 347 348void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer) 349{ 350 if(renderbuffer != 0 && !getRenderbuffer(renderbuffer)) 351 { 352 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0)); 353 mRenderbufferMap[renderbuffer] = renderbufferObject; 354 renderbufferObject->addRef(); 355 } 356} 357 358} 359