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 26 namespace gl 27 { 28 ResourceManager::ResourceManager() 29 { 30 mRefCount = 1; 31 } 32 33 ResourceManager::~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 61 void ResourceManager::addRef() 62 { 63 mRefCount++; 64 } 65 66 void ResourceManager::release() 67 { 68 if(--mRefCount == 0) 69 { 70 delete this; 71 } 72 } 73 74 // Returns an unused buffer name 75 GLuint 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 91 GLuint 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 115 GLuint 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 131 GLuint 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 147 GLuint 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 162 void 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 174 void 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 193 void 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 212 void 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 224 void 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 236 Buffer *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 250 Shader *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 264 Texture *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 280 Program *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 294 Renderbuffer *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 308 void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) 309 { 310 mRenderbufferMap[handle] = buffer; 311 } 312 313 void 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 323 void 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 348 void 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