1 // 2 // Copyright (c) 2002-2013 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 #include "libGLESv2/Sampler.h" 18 #include "libGLESv2/Fence.h" 19 #include "libGLESv2/renderer/Renderer.h" 20 21 namespace gl 22 { 23 ResourceManager::ResourceManager(rx::Renderer *renderer) 24 { 25 mRefCount = 1; 26 mRenderer = renderer; 27 } 28 29 ResourceManager::~ResourceManager() 30 { 31 while (!mBufferMap.empty()) 32 { 33 deleteBuffer(mBufferMap.begin()->first); 34 } 35 36 while (!mProgramMap.empty()) 37 { 38 deleteProgram(mProgramMap.begin()->first); 39 } 40 41 while (!mShaderMap.empty()) 42 { 43 deleteShader(mShaderMap.begin()->first); 44 } 45 46 while (!mRenderbufferMap.empty()) 47 { 48 deleteRenderbuffer(mRenderbufferMap.begin()->first); 49 } 50 51 while (!mTextureMap.empty()) 52 { 53 deleteTexture(mTextureMap.begin()->first); 54 } 55 56 while (!mSamplerMap.empty()) 57 { 58 deleteSampler(mSamplerMap.begin()->first); 59 } 60 61 while (!mFenceSyncMap.empty()) 62 { 63 deleteFenceSync(mFenceSyncMap.begin()->first); 64 } 65 } 66 67 void ResourceManager::addRef() 68 { 69 mRefCount++; 70 } 71 72 void ResourceManager::release() 73 { 74 if (--mRefCount == 0) 75 { 76 delete this; 77 } 78 } 79 80 // Returns an unused buffer name 81 GLuint ResourceManager::createBuffer() 82 { 83 GLuint handle = mBufferHandleAllocator.allocate(); 84 85 mBufferMap[handle] = NULL; 86 87 return handle; 88 } 89 90 // Returns an unused shader/program name 91 GLuint ResourceManager::createShader(GLenum type) 92 { 93 GLuint handle = mProgramShaderHandleAllocator.allocate(); 94 95 if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER) 96 { 97 mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle); 98 } 99 else UNREACHABLE(); 100 101 return handle; 102 } 103 104 // Returns an unused program/shader name 105 GLuint ResourceManager::createProgram() 106 { 107 GLuint handle = mProgramShaderHandleAllocator.allocate(); 108 109 mProgramMap[handle] = new Program(mRenderer, this, handle); 110 111 return handle; 112 } 113 114 // Returns an unused texture name 115 GLuint ResourceManager::createTexture() 116 { 117 GLuint handle = mTextureHandleAllocator.allocate(); 118 119 mTextureMap[handle] = NULL; 120 121 return handle; 122 } 123 124 // Returns an unused renderbuffer name 125 GLuint ResourceManager::createRenderbuffer() 126 { 127 GLuint handle = mRenderbufferHandleAllocator.allocate(); 128 129 mRenderbufferMap[handle] = NULL; 130 131 return handle; 132 } 133 134 // Returns an unused sampler name 135 GLuint ResourceManager::createSampler() 136 { 137 GLuint handle = mSamplerHandleAllocator.allocate(); 138 139 mSamplerMap[handle] = NULL; 140 141 return handle; 142 } 143 144 // Returns the next unused fence name, and allocates the fence 145 GLuint ResourceManager::createFenceSync() 146 { 147 GLuint handle = mFenceSyncHandleAllocator.allocate(); 148 149 FenceSync *fenceSync = new FenceSync(mRenderer, handle); 150 fenceSync->addRef(); 151 mFenceSyncMap[handle] = fenceSync; 152 153 return handle; 154 } 155 156 void ResourceManager::deleteBuffer(GLuint buffer) 157 { 158 BufferMap::iterator bufferObject = mBufferMap.find(buffer); 159 160 if (bufferObject != mBufferMap.end()) 161 { 162 mBufferHandleAllocator.release(bufferObject->first); 163 if (bufferObject->second) bufferObject->second->release(); 164 mBufferMap.erase(bufferObject); 165 } 166 } 167 168 void ResourceManager::deleteShader(GLuint shader) 169 { 170 ShaderMap::iterator shaderObject = mShaderMap.find(shader); 171 172 if (shaderObject != mShaderMap.end()) 173 { 174 if (shaderObject->second->getRefCount() == 0) 175 { 176 mProgramShaderHandleAllocator.release(shaderObject->first); 177 delete shaderObject->second; 178 mShaderMap.erase(shaderObject); 179 } 180 else 181 { 182 shaderObject->second->flagForDeletion(); 183 } 184 } 185 } 186 187 void ResourceManager::deleteProgram(GLuint program) 188 { 189 ProgramMap::iterator programObject = mProgramMap.find(program); 190 191 if (programObject != mProgramMap.end()) 192 { 193 if (programObject->second->getRefCount() == 0) 194 { 195 mProgramShaderHandleAllocator.release(programObject->first); 196 delete programObject->second; 197 mProgramMap.erase(programObject); 198 } 199 else 200 { 201 programObject->second->flagForDeletion(); 202 } 203 } 204 } 205 206 void ResourceManager::deleteTexture(GLuint texture) 207 { 208 TextureMap::iterator textureObject = mTextureMap.find(texture); 209 210 if (textureObject != mTextureMap.end()) 211 { 212 mTextureHandleAllocator.release(textureObject->first); 213 if (textureObject->second) textureObject->second->release(); 214 mTextureMap.erase(textureObject); 215 } 216 } 217 218 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) 219 { 220 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer); 221 222 if (renderbufferObject != mRenderbufferMap.end()) 223 { 224 mRenderbufferHandleAllocator.release(renderbufferObject->first); 225 if (renderbufferObject->second) renderbufferObject->second->release(); 226 mRenderbufferMap.erase(renderbufferObject); 227 } 228 } 229 230 void ResourceManager::deleteSampler(GLuint sampler) 231 { 232 auto samplerObject = mSamplerMap.find(sampler); 233 234 if (samplerObject != mSamplerMap.end()) 235 { 236 mSamplerHandleAllocator.release(samplerObject->first); 237 if (samplerObject->second) samplerObject->second->release(); 238 mSamplerMap.erase(samplerObject); 239 } 240 } 241 242 void ResourceManager::deleteFenceSync(GLuint fenceSync) 243 { 244 auto fenceObjectIt = mFenceSyncMap.find(fenceSync); 245 246 if (fenceObjectIt != mFenceSyncMap.end()) 247 { 248 mFenceSyncHandleAllocator.release(fenceObjectIt->first); 249 if (fenceObjectIt->second) fenceObjectIt->second->release(); 250 mFenceSyncMap.erase(fenceObjectIt); 251 } 252 } 253 254 Buffer *ResourceManager::getBuffer(unsigned int handle) 255 { 256 BufferMap::iterator buffer = mBufferMap.find(handle); 257 258 if (buffer == mBufferMap.end()) 259 { 260 return NULL; 261 } 262 else 263 { 264 return buffer->second; 265 } 266 } 267 268 Shader *ResourceManager::getShader(unsigned int handle) 269 { 270 ShaderMap::iterator shader = mShaderMap.find(handle); 271 272 if (shader == mShaderMap.end()) 273 { 274 return NULL; 275 } 276 else 277 { 278 return shader->second; 279 } 280 } 281 282 Texture *ResourceManager::getTexture(unsigned int handle) 283 { 284 if (handle == 0) return NULL; 285 286 TextureMap::iterator texture = mTextureMap.find(handle); 287 288 if (texture == mTextureMap.end()) 289 { 290 return NULL; 291 } 292 else 293 { 294 return texture->second; 295 } 296 } 297 298 Program *ResourceManager::getProgram(unsigned int handle) 299 { 300 ProgramMap::iterator program = mProgramMap.find(handle); 301 302 if (program == mProgramMap.end()) 303 { 304 return NULL; 305 } 306 else 307 { 308 return program->second; 309 } 310 } 311 312 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) 313 { 314 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle); 315 316 if (renderbuffer == mRenderbufferMap.end()) 317 { 318 return NULL; 319 } 320 else 321 { 322 return renderbuffer->second; 323 } 324 } 325 326 Sampler *ResourceManager::getSampler(unsigned int handle) 327 { 328 auto sampler = mSamplerMap.find(handle); 329 330 if (sampler == mSamplerMap.end()) 331 { 332 return NULL; 333 } 334 else 335 { 336 return sampler->second; 337 } 338 } 339 340 FenceSync *ResourceManager::getFenceSync(unsigned int handle) 341 { 342 auto fenceObjectIt = mFenceSyncMap.find(handle); 343 344 if (fenceObjectIt == mFenceSyncMap.end()) 345 { 346 return NULL; 347 } 348 else 349 { 350 return fenceObjectIt->second; 351 } 352 } 353 354 void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) 355 { 356 mRenderbufferMap[handle] = buffer; 357 } 358 359 void ResourceManager::checkBufferAllocation(unsigned int buffer) 360 { 361 if (buffer != 0 && !getBuffer(buffer)) 362 { 363 Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer); 364 mBufferMap[buffer] = bufferObject; 365 bufferObject->addRef(); 366 } 367 } 368 369 void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type) 370 { 371 if (!getTexture(texture) && texture != 0) 372 { 373 Texture *textureObject; 374 375 if (type == GL_TEXTURE_2D) 376 { 377 textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture); 378 } 379 else if (type == GL_TEXTURE_CUBE_MAP) 380 { 381 textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture); 382 } 383 else if (type == GL_TEXTURE_3D) 384 { 385 textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture); 386 } 387 else if (type == GL_TEXTURE_2D_ARRAY) 388 { 389 textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture); 390 } 391 else 392 { 393 UNREACHABLE(); 394 return; 395 } 396 397 mTextureMap[texture] = textureObject; 398 textureObject->addRef(); 399 } 400 } 401 402 void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer) 403 { 404 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer)) 405 { 406 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0)); 407 mRenderbufferMap[renderbuffer] = renderbufferObject; 408 renderbufferObject->addRef(); 409 } 410 } 411 412 void ResourceManager::checkSamplerAllocation(GLuint sampler) 413 { 414 if (sampler != 0 && !getSampler(sampler)) 415 { 416 Sampler *samplerObject = new Sampler(sampler); 417 mSamplerMap[sampler] = samplerObject; 418 samplerObject->addRef(); 419 } 420 } 421 422 bool ResourceManager::isSampler(GLuint sampler) 423 { 424 return mSamplerMap.find(sampler) != mSamplerMap.end(); 425 } 426 427 } 428