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