1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // ResourceManager.cpp: Implements the ResourceManager class, which tracks and 16 // retrieves objects which may be shared by multiple Contexts. 17 18 #include "ResourceManager.h" 19 20 #include "Buffer.h" 21 #include "Fence.h" 22 #include "Program.h" 23 #include "Renderbuffer.h" 24 #include "Sampler.h" 25 #include "Shader.h" 26 #include "Texture.h" 27 28 namespace es2 29 { 30 ResourceManager::ResourceManager() 31 { 32 mRefCount = 1; 33 } 34 35 ResourceManager::~ResourceManager() 36 { 37 while(!mBufferNameSpace.empty()) 38 { 39 deleteBuffer(mBufferNameSpace.firstName()); 40 } 41 42 while(!mProgramNameSpace.empty()) 43 { 44 deleteProgram(mProgramNameSpace.firstName()); 45 } 46 47 while(!mShaderNameSpace.empty()) 48 { 49 deleteShader(mShaderNameSpace.firstName()); 50 } 51 52 while(!mRenderbufferNameSpace.empty()) 53 { 54 deleteRenderbuffer(mRenderbufferNameSpace.firstName()); 55 } 56 57 while(!mTextureNameSpace.empty()) 58 { 59 deleteTexture(mTextureNameSpace.firstName()); 60 } 61 62 while(!mSamplerNameSpace.empty()) 63 { 64 deleteSampler(mSamplerNameSpace.firstName()); 65 } 66 67 while(!mFenceSyncNameSpace.empty()) 68 { 69 deleteFenceSync(mFenceSyncNameSpace.firstName()); 70 } 71 } 72 73 void ResourceManager::addRef() 74 { 75 mRefCount++; 76 } 77 78 void ResourceManager::release() 79 { 80 if(--mRefCount == 0) 81 { 82 delete this; 83 } 84 } 85 86 // Returns an unused buffer name 87 GLuint ResourceManager::createBuffer() 88 { 89 return mBufferNameSpace.allocate(); 90 } 91 92 // Returns an unused shader name 93 GLuint ResourceManager::createShader(GLenum type) 94 { 95 GLuint name = mProgramShaderNameSpace.allocate(); 96 97 if(type == GL_VERTEX_SHADER) 98 { 99 mShaderNameSpace.insert(name, new VertexShader(this, name)); 100 } 101 else if(type == GL_FRAGMENT_SHADER) 102 { 103 mShaderNameSpace.insert(name, new FragmentShader(this, name)); 104 } 105 else UNREACHABLE(type); 106 107 return name; 108 } 109 110 // Returns an unused program name 111 GLuint ResourceManager::createProgram() 112 { 113 GLuint name = mProgramShaderNameSpace.allocate(); 114 115 mProgramNameSpace.insert(name, new Program(this, name)); 116 117 return name; 118 } 119 120 // Returns an unused texture name 121 GLuint ResourceManager::createTexture() 122 { 123 return mTextureNameSpace.allocate(); 124 } 125 126 // Returns an unused renderbuffer name 127 GLuint ResourceManager::createRenderbuffer() 128 { 129 return mRenderbufferNameSpace.allocate(); 130 } 131 132 // Returns an unused sampler name 133 GLuint ResourceManager::createSampler() 134 { 135 return mSamplerNameSpace.allocate(); 136 } 137 138 // Returns the next unused fence name, and allocates the fence 139 GLuint ResourceManager::createFenceSync(GLenum condition, GLbitfield flags) 140 { 141 GLuint name = mFenceSyncNameSpace.allocate(); 142 143 FenceSync *fenceSync = new FenceSync(name, condition, flags); 144 fenceSync->addRef(); 145 146 mFenceSyncNameSpace.insert(name, fenceSync); 147 148 return name; 149 } 150 151 void ResourceManager::deleteBuffer(GLuint buffer) 152 { 153 Buffer *bufferObject = mBufferNameSpace.remove(buffer); 154 155 if(bufferObject) 156 { 157 bufferObject->release(); 158 } 159 } 160 161 void ResourceManager::deleteShader(GLuint shader) 162 { 163 Shader *shaderObject = mShaderNameSpace.find(shader); 164 165 if(shaderObject) 166 { 167 if(shaderObject->getRefCount() == 0) 168 { 169 delete shaderObject; 170 mShaderNameSpace.remove(shader); 171 mProgramShaderNameSpace.remove(shader); 172 } 173 else 174 { 175 shaderObject->flagForDeletion(); 176 } 177 } 178 } 179 180 void ResourceManager::deleteProgram(GLuint program) 181 { 182 Program *programObject = mProgramNameSpace.find(program); 183 184 if(programObject) 185 { 186 if(programObject->getRefCount() == 0) 187 { 188 delete programObject; 189 mProgramNameSpace.remove(program); 190 mProgramShaderNameSpace.remove(program); 191 } 192 else 193 { 194 programObject->flagForDeletion(); 195 } 196 } 197 } 198 199 void ResourceManager::deleteTexture(GLuint texture) 200 { 201 Texture *textureObject = mTextureNameSpace.remove(texture); 202 203 if(textureObject) 204 { 205 textureObject->release(); 206 } 207 } 208 209 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) 210 { 211 Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer); 212 213 if(renderbufferObject) 214 { 215 renderbufferObject->release(); 216 } 217 } 218 219 void ResourceManager::deleteSampler(GLuint sampler) 220 { 221 Sampler *samplerObject = mSamplerNameSpace.remove(sampler); 222 223 if(samplerObject) 224 { 225 samplerObject->release(); 226 } 227 } 228 229 void ResourceManager::deleteFenceSync(GLuint fenceSync) 230 { 231 FenceSync *fenceObject = mFenceSyncNameSpace.remove(fenceSync); 232 233 if(fenceObject) 234 { 235 fenceObject->release(); 236 } 237 } 238 239 Buffer *ResourceManager::getBuffer(unsigned int handle) 240 { 241 return mBufferNameSpace.find(handle); 242 } 243 244 Shader *ResourceManager::getShader(unsigned int handle) 245 { 246 return mShaderNameSpace.find(handle); 247 } 248 249 Texture *ResourceManager::getTexture(unsigned int handle) 250 { 251 return mTextureNameSpace.find(handle); 252 } 253 254 Program *ResourceManager::getProgram(unsigned int handle) 255 { 256 return mProgramNameSpace.find(handle); 257 } 258 259 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) 260 { 261 return mRenderbufferNameSpace.find(handle); 262 } 263 264 Sampler *ResourceManager::getSampler(unsigned int handle) 265 { 266 return mSamplerNameSpace.find(handle); 267 } 268 269 FenceSync *ResourceManager::getFenceSync(unsigned int handle) 270 { 271 return mFenceSyncNameSpace.find(handle); 272 } 273 274 void ResourceManager::checkBufferAllocation(unsigned int buffer) 275 { 276 if(buffer != 0 && !getBuffer(buffer)) 277 { 278 Buffer *bufferObject = new Buffer(buffer); 279 bufferObject->addRef(); 280 281 mBufferNameSpace.insert(buffer, bufferObject); 282 } 283 } 284 285 void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) 286 { 287 if(!getTexture(texture) && texture != 0) 288 { 289 Texture *textureObject; 290 291 if(type == TEXTURE_2D) 292 { 293 textureObject = new Texture2D(texture); 294 } 295 else if(type == TEXTURE_CUBE) 296 { 297 textureObject = new TextureCubeMap(texture); 298 } 299 else if(type == TEXTURE_EXTERNAL) 300 { 301 textureObject = new TextureExternal(texture); 302 } 303 else if(type == TEXTURE_3D) 304 { 305 textureObject = new Texture3D(texture); 306 } 307 else if(type == TEXTURE_2D_ARRAY) 308 { 309 textureObject = new Texture2DArray(texture); 310 } 311 else if(type == TEXTURE_2D_RECT) 312 { 313 textureObject = new Texture2DRect(texture); 314 } 315 else 316 { 317 UNREACHABLE(type); 318 return; 319 } 320 321 textureObject->addRef(); 322 323 mTextureNameSpace.insert(texture, textureObject); 324 } 325 } 326 327 void ResourceManager::checkRenderbufferAllocation(GLuint handle) 328 { 329 if(handle != 0 && !getRenderbuffer(handle)) 330 { 331 Renderbuffer *renderbufferObject = new Renderbuffer(handle, new Colorbuffer(0, 0, GL_NONE, 0)); 332 renderbufferObject->addRef(); 333 334 mRenderbufferNameSpace.insert(handle, renderbufferObject); 335 } 336 } 337 338 void ResourceManager::checkSamplerAllocation(GLuint sampler) 339 { 340 if(sampler != 0 && !getSampler(sampler)) 341 { 342 Sampler *samplerObject = new Sampler(sampler); 343 samplerObject->addRef(); 344 345 mSamplerNameSpace.insert(sampler, samplerObject); 346 } 347 } 348 349 bool ResourceManager::isSampler(GLuint sampler) 350 { 351 return mSamplerNameSpace.isReserved(sampler); 352 } 353 354 } 355