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 {
ResourceManager(rx::Renderer * renderer)23 ResourceManager::ResourceManager(rx::Renderer *renderer)
24 {
25 mRefCount = 1;
26 mRenderer = renderer;
27 }
28
~ResourceManager()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
addRef()67 void ResourceManager::addRef()
68 {
69 mRefCount++;
70 }
71
release()72 void ResourceManager::release()
73 {
74 if (--mRefCount == 0)
75 {
76 delete this;
77 }
78 }
79
80 // Returns an unused buffer name
createBuffer()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
createShader(GLenum type)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
createProgram()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
createTexture()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
createRenderbuffer()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
createSampler()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
createFenceSync()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
deleteBuffer(GLuint buffer)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
deleteShader(GLuint shader)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
deleteProgram(GLuint program)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
deleteTexture(GLuint texture)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
deleteRenderbuffer(GLuint renderbuffer)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
deleteSampler(GLuint sampler)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
deleteFenceSync(GLuint fenceSync)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
getBuffer(unsigned int handle)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
getShader(unsigned int handle)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
getTexture(unsigned int handle)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
getProgram(unsigned int handle)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
getRenderbuffer(unsigned int handle)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
getSampler(unsigned int handle)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
getFenceSync(unsigned int handle)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
setRenderbuffer(GLuint handle,Renderbuffer * buffer)354 void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
355 {
356 mRenderbufferMap[handle] = buffer;
357 }
358
checkBufferAllocation(unsigned int buffer)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
checkTextureAllocation(GLuint texture,GLenum type)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
checkRenderbufferAllocation(GLuint renderbuffer)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
checkSamplerAllocation(GLuint sampler)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
isSampler(GLuint sampler)422 bool ResourceManager::isSampler(GLuint sampler)
423 {
424 return mSamplerMap.find(sampler) != mSamplerMap.end();
425 }
426
427 }
428