Home | History | Annotate | Download | only in libGLESv2
      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