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 21namespace gl 22{ 23ResourceManager::ResourceManager(rx::Renderer *renderer) 24{ 25 mRefCount = 1; 26 mRenderer = renderer; 27} 28 29ResourceManager::~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 67void ResourceManager::addRef() 68{ 69 mRefCount++; 70} 71 72void ResourceManager::release() 73{ 74 if (--mRefCount == 0) 75 { 76 delete this; 77 } 78} 79 80// Returns an unused buffer name 81GLuint 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 91GLuint 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 109GLuint 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 119GLuint 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 129GLuint 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 139GLuint 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 149GLuint ResourceManager::createFenceSync() 150{ 151 GLuint handle = mFenceSyncHandleAllocator.allocate(); 152 153 mFenceSyncMap[handle] = new FenceSync(mRenderer, handle); 154 155 return handle; 156} 157 158void 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 170void 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 189void 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 208void 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 220void 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 232void 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 244void 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 256Buffer *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 270Shader *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 284Texture *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 300Program *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 314FramebufferAttachment *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 328Sampler *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 342FenceSync *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 356void ResourceManager::setRenderbuffer(GLuint handle, FramebufferAttachment *buffer) 357{ 358 mRenderbufferMap[handle] = buffer; 359} 360 361void 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 371void 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 404void 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 414void 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 424bool ResourceManager::isSampler(GLuint sampler) 425{ 426 return mSamplerMap.find(sampler) != mSamplerMap.end(); 427} 428 429} 430