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