blob: 55c743ca6721e81011ce5399c0bc753d0884d524 [file] [log] [blame]
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00001//
Jamie Madilldc356042013-07-19 16:36:57 -04002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00003// 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
Jamie Madillea247592014-08-28 10:37:08 -040010#include "libGLESv2/common_includes.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000011#include "libGLESv2/ResourceManager.h"
12
13#include "libGLESv2/Buffer.h"
14#include "libGLESv2/Program.h"
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000015#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000016#include "libGLESv2/Shader.h"
17#include "libGLESv2/Texture.h"
Jamie Madilldc356042013-07-19 16:36:57 -040018#include "libGLESv2/Sampler.h"
Jamie Madillcd055f82013-07-26 11:55:15 -040019#include "libGLESv2/Fence.h"
Brandon Jonesd38f9262014-06-18 16:26:45 -070020#include "libGLESv2/renderer/Renderer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000021
22namespace gl
23{
daniel@transgaming.com370482e2012-11-28 19:32:13 +000024ResourceManager::ResourceManager(rx::Renderer *renderer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000025{
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000026 mRefCount = 1;
daniel@transgaming.com370482e2012-11-28 19:32:13 +000027 mRenderer = renderer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000028}
29
30ResourceManager::~ResourceManager()
31{
32 while (!mBufferMap.empty())
33 {
34 deleteBuffer(mBufferMap.begin()->first);
35 }
36
37 while (!mProgramMap.empty())
38 {
39 deleteProgram(mProgramMap.begin()->first);
40 }
41
42 while (!mShaderMap.empty())
43 {
44 deleteShader(mShaderMap.begin()->first);
45 }
46
47 while (!mRenderbufferMap.empty())
48 {
49 deleteRenderbuffer(mRenderbufferMap.begin()->first);
50 }
51
52 while (!mTextureMap.empty())
53 {
54 deleteTexture(mTextureMap.begin()->first);
55 }
Jamie Madilldc356042013-07-19 16:36:57 -040056
57 while (!mSamplerMap.empty())
58 {
59 deleteSampler(mSamplerMap.begin()->first);
60 }
Jamie Madillcd055f82013-07-26 11:55:15 -040061
62 while (!mFenceSyncMap.empty())
63 {
64 deleteFenceSync(mFenceSyncMap.begin()->first);
65 }
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000066}
67
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000068void ResourceManager::addRef()
69{
70 mRefCount++;
71}
72
73void ResourceManager::release()
74{
75 if (--mRefCount == 0)
76 {
77 delete this;
78 }
79}
80
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000081// Returns an unused buffer name
82GLuint ResourceManager::createBuffer()
83{
benvanik@google.com1a233342011-04-28 19:44:39 +000084 GLuint handle = mBufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000085
86 mBufferMap[handle] = NULL;
87
88 return handle;
89}
90
91// Returns an unused shader/program name
92GLuint ResourceManager::createShader(GLenum type)
93{
benvanik@google.com1a233342011-04-28 19:44:39 +000094 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000095
96 if (type == GL_VERTEX_SHADER)
97 {
Brandon Jonesf05cdee2014-08-27 15:24:07 -070098 mShaderMap[handle] = new VertexShader(this, mRenderer->createShader(type), handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000099 }
100 else if (type == GL_FRAGMENT_SHADER)
101 {
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700102 mShaderMap[handle] = new FragmentShader(this, mRenderer->createShader(type), handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000103 }
104 else UNREACHABLE();
105
106 return handle;
107}
108
109// Returns an unused program/shader name
110GLuint ResourceManager::createProgram()
111{
benvanik@google.com1a233342011-04-28 19:44:39 +0000112 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000113
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000114 mProgramMap[handle] = new Program(mRenderer, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000115
116 return handle;
117}
118
119// Returns an unused texture name
120GLuint ResourceManager::createTexture()
121{
benvanik@google.com1a233342011-04-28 19:44:39 +0000122 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000123
124 mTextureMap[handle] = NULL;
125
126 return handle;
127}
128
129// Returns an unused renderbuffer name
130GLuint ResourceManager::createRenderbuffer()
131{
benvanik@google.com1a233342011-04-28 19:44:39 +0000132 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000133
134 mRenderbufferMap[handle] = NULL;
135
136 return handle;
137}
138
Jamie Madilldc356042013-07-19 16:36:57 -0400139// Returns an unused sampler name
140GLuint ResourceManager::createSampler()
141{
142 GLuint handle = mSamplerHandleAllocator.allocate();
143
144 mSamplerMap[handle] = NULL;
145
146 return handle;
147}
148
Jamie Madillcd055f82013-07-26 11:55:15 -0400149// Returns the next unused fence name, and allocates the fence
150GLuint ResourceManager::createFenceSync()
151{
152 GLuint handle = mFenceSyncHandleAllocator.allocate();
153
Jamie Madillcfa33e62014-08-19 15:30:41 -0400154 FenceSync *fenceSync = new FenceSync(mRenderer, handle);
155 fenceSync->addRef();
156 mFenceSyncMap[handle] = fenceSync;
Jamie Madillcd055f82013-07-26 11:55:15 -0400157
158 return handle;
159}
160
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000161void ResourceManager::deleteBuffer(GLuint buffer)
162{
163 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
164
165 if (bufferObject != mBufferMap.end())
166 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000167 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000168 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000169 mBufferMap.erase(bufferObject);
170 }
171}
172
173void ResourceManager::deleteShader(GLuint shader)
174{
175 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
176
177 if (shaderObject != mShaderMap.end())
178 {
179 if (shaderObject->second->getRefCount() == 0)
180 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000181 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000182 delete shaderObject->second;
183 mShaderMap.erase(shaderObject);
184 }
185 else
186 {
187 shaderObject->second->flagForDeletion();
188 }
189 }
190}
191
192void ResourceManager::deleteProgram(GLuint program)
193{
194 ProgramMap::iterator programObject = mProgramMap.find(program);
195
196 if (programObject != mProgramMap.end())
197 {
198 if (programObject->second->getRefCount() == 0)
199 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000200 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000201 delete programObject->second;
202 mProgramMap.erase(programObject);
203 }
204 else
205 {
206 programObject->second->flagForDeletion();
207 }
208 }
209}
210
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000211void ResourceManager::deleteTexture(GLuint texture)
212{
213 TextureMap::iterator textureObject = mTextureMap.find(texture);
214
215 if (textureObject != mTextureMap.end())
216 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000217 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000218 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000219 mTextureMap.erase(textureObject);
220 }
221}
222
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000223void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
224{
225 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
226
227 if (renderbufferObject != mRenderbufferMap.end())
228 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000229 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000230 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000231 mRenderbufferMap.erase(renderbufferObject);
232 }
233}
234
Jamie Madilldc356042013-07-19 16:36:57 -0400235void ResourceManager::deleteSampler(GLuint sampler)
236{
237 auto samplerObject = mSamplerMap.find(sampler);
238
239 if (samplerObject != mSamplerMap.end())
240 {
Geoff Lang79931902014-02-03 14:29:42 -0500241 mSamplerHandleAllocator.release(samplerObject->first);
Jamie Madilldc356042013-07-19 16:36:57 -0400242 if (samplerObject->second) samplerObject->second->release();
243 mSamplerMap.erase(samplerObject);
244 }
245}
246
Jamie Madillcd055f82013-07-26 11:55:15 -0400247void ResourceManager::deleteFenceSync(GLuint fenceSync)
248{
249 auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
250
251 if (fenceObjectIt != mFenceSyncMap.end())
252 {
253 mFenceSyncHandleAllocator.release(fenceObjectIt->first);
254 if (fenceObjectIt->second) fenceObjectIt->second->release();
255 mFenceSyncMap.erase(fenceObjectIt);
256 }
257}
258
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000259Buffer *ResourceManager::getBuffer(unsigned int handle)
260{
261 BufferMap::iterator buffer = mBufferMap.find(handle);
262
263 if (buffer == mBufferMap.end())
264 {
265 return NULL;
266 }
267 else
268 {
269 return buffer->second;
270 }
271}
272
273Shader *ResourceManager::getShader(unsigned int handle)
274{
275 ShaderMap::iterator shader = mShaderMap.find(handle);
276
277 if (shader == mShaderMap.end())
278 {
279 return NULL;
280 }
281 else
282 {
283 return shader->second;
284 }
285}
286
287Texture *ResourceManager::getTexture(unsigned int handle)
288{
289 if (handle == 0) return NULL;
290
291 TextureMap::iterator texture = mTextureMap.find(handle);
292
293 if (texture == mTextureMap.end())
294 {
295 return NULL;
296 }
297 else
298 {
299 return texture->second;
300 }
301}
302
303Program *ResourceManager::getProgram(unsigned int handle)
304{
305 ProgramMap::iterator program = mProgramMap.find(handle);
306
307 if (program == mProgramMap.end())
308 {
309 return NULL;
310 }
311 else
312 {
313 return program->second;
314 }
315}
316
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400317Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000318{
319 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
320
321 if (renderbuffer == mRenderbufferMap.end())
322 {
323 return NULL;
324 }
325 else
326 {
327 return renderbuffer->second;
328 }
329}
330
Jamie Madilldc356042013-07-19 16:36:57 -0400331Sampler *ResourceManager::getSampler(unsigned int handle)
332{
333 auto sampler = mSamplerMap.find(handle);
334
335 if (sampler == mSamplerMap.end())
336 {
337 return NULL;
338 }
339 else
340 {
341 return sampler->second;
342 }
343}
344
Jamie Madillcd055f82013-07-26 11:55:15 -0400345FenceSync *ResourceManager::getFenceSync(unsigned int handle)
346{
347 auto fenceObjectIt = mFenceSyncMap.find(handle);
348
349 if (fenceObjectIt == mFenceSyncMap.end())
350 {
351 return NULL;
352 }
353 else
354 {
355 return fenceObjectIt->second;
356 }
357}
358
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400359void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000360{
361 mRenderbufferMap[handle] = buffer;
362}
363
364void ResourceManager::checkBufferAllocation(unsigned int buffer)
365{
366 if (buffer != 0 && !getBuffer(buffer))
367 {
Brandon Jonesd38f9262014-06-18 16:26:45 -0700368 Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000369 mBufferMap[buffer] = bufferObject;
370 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000371 }
372}
373
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000374void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000375{
376 if (!getTexture(texture) && texture != 0)
377 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000378 Texture *textureObject;
379
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000380 if (type == TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000381 {
Brandon Jones6053a522014-07-25 16:22:09 -0700382 textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000383 }
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000384 else if (type == TEXTURE_CUBE)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000385 {
Brandon Jones6053a522014-07-25 16:22:09 -0700386 textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000387 }
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000388 else if (type == TEXTURE_3D)
389 {
Brandon Jones6053a522014-07-25 16:22:09 -0700390 textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000391 }
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000392 else if (type == TEXTURE_2D_ARRAY)
393 {
Brandon Jones6053a522014-07-25 16:22:09 -0700394 textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000395 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000396 else
397 {
398 UNREACHABLE();
399 return;
400 }
401
402 mTextureMap[texture] = textureObject;
403 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000404 }
405}
406
407void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
408{
409 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
410 {
Geoff Lange4a492b2014-06-19 14:14:41 -0400411 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000412 mRenderbufferMap[renderbuffer] = renderbufferObject;
413 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000414 }
415}
416
Jamie Madilldc356042013-07-19 16:36:57 -0400417void ResourceManager::checkSamplerAllocation(GLuint sampler)
418{
419 if (sampler != 0 && !getSampler(sampler))
420 {
421 Sampler *samplerObject = new Sampler(sampler);
422 mSamplerMap[sampler] = samplerObject;
423 samplerObject->addRef();
424 }
425}
426
427bool ResourceManager::isSampler(GLuint sampler)
428{
429 return mSamplerMap.find(sampler) != mSamplerMap.end();
430}
431
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000432}