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