blob: 701f7cb15a7d19411d13b1d5793229273f252542 [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
Brandon Jones71620962014-08-20 14:04:59 -070096 if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000097 {
Brandon Jones71620962014-08-20 14:04:59 -070098 mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000099 }
100 else UNREACHABLE();
101
102 return handle;
103}
104
105// Returns an unused program/shader name
106GLuint ResourceManager::createProgram()
107{
benvanik@google.com1a233342011-04-28 19:44:39 +0000108 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000109
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000110 mProgramMap[handle] = new Program(mRenderer, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000111
112 return handle;
113}
114
115// Returns an unused texture name
116GLuint ResourceManager::createTexture()
117{
benvanik@google.com1a233342011-04-28 19:44:39 +0000118 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000119
120 mTextureMap[handle] = NULL;
121
122 return handle;
123}
124
125// Returns an unused renderbuffer name
126GLuint ResourceManager::createRenderbuffer()
127{
benvanik@google.com1a233342011-04-28 19:44:39 +0000128 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000129
130 mRenderbufferMap[handle] = NULL;
131
132 return handle;
133}
134
Jamie Madilldc356042013-07-19 16:36:57 -0400135// Returns an unused sampler name
136GLuint ResourceManager::createSampler()
137{
138 GLuint handle = mSamplerHandleAllocator.allocate();
139
140 mSamplerMap[handle] = NULL;
141
142 return handle;
143}
144
Jamie Madillcd055f82013-07-26 11:55:15 -0400145// Returns the next unused fence name, and allocates the fence
146GLuint ResourceManager::createFenceSync()
147{
148 GLuint handle = mFenceSyncHandleAllocator.allocate();
149
Jamie Madillcfa33e62014-08-19 15:30:41 -0400150 FenceSync *fenceSync = new FenceSync(mRenderer, handle);
151 fenceSync->addRef();
152 mFenceSyncMap[handle] = fenceSync;
Jamie Madillcd055f82013-07-26 11:55:15 -0400153
154 return handle;
155}
156
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000157void ResourceManager::deleteBuffer(GLuint buffer)
158{
159 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
160
161 if (bufferObject != mBufferMap.end())
162 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000163 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000164 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000165 mBufferMap.erase(bufferObject);
166 }
167}
168
169void ResourceManager::deleteShader(GLuint shader)
170{
171 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
172
173 if (shaderObject != mShaderMap.end())
174 {
175 if (shaderObject->second->getRefCount() == 0)
176 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000177 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000178 delete shaderObject->second;
179 mShaderMap.erase(shaderObject);
180 }
181 else
182 {
183 shaderObject->second->flagForDeletion();
184 }
185 }
186}
187
188void ResourceManager::deleteProgram(GLuint program)
189{
190 ProgramMap::iterator programObject = mProgramMap.find(program);
191
192 if (programObject != mProgramMap.end())
193 {
194 if (programObject->second->getRefCount() == 0)
195 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000196 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000197 delete programObject->second;
198 mProgramMap.erase(programObject);
199 }
200 else
201 {
202 programObject->second->flagForDeletion();
203 }
204 }
205}
206
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000207void ResourceManager::deleteTexture(GLuint texture)
208{
209 TextureMap::iterator textureObject = mTextureMap.find(texture);
210
211 if (textureObject != mTextureMap.end())
212 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000213 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000214 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000215 mTextureMap.erase(textureObject);
216 }
217}
218
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000219void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
220{
221 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
222
223 if (renderbufferObject != mRenderbufferMap.end())
224 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000225 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000226 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000227 mRenderbufferMap.erase(renderbufferObject);
228 }
229}
230
Jamie Madilldc356042013-07-19 16:36:57 -0400231void ResourceManager::deleteSampler(GLuint sampler)
232{
233 auto samplerObject = mSamplerMap.find(sampler);
234
235 if (samplerObject != mSamplerMap.end())
236 {
Geoff Lang79931902014-02-03 14:29:42 -0500237 mSamplerHandleAllocator.release(samplerObject->first);
Jamie Madilldc356042013-07-19 16:36:57 -0400238 if (samplerObject->second) samplerObject->second->release();
239 mSamplerMap.erase(samplerObject);
240 }
241}
242
Jamie Madillcd055f82013-07-26 11:55:15 -0400243void ResourceManager::deleteFenceSync(GLuint fenceSync)
244{
245 auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
246
247 if (fenceObjectIt != mFenceSyncMap.end())
248 {
249 mFenceSyncHandleAllocator.release(fenceObjectIt->first);
250 if (fenceObjectIt->second) fenceObjectIt->second->release();
251 mFenceSyncMap.erase(fenceObjectIt);
252 }
253}
254
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000255Buffer *ResourceManager::getBuffer(unsigned int handle)
256{
257 BufferMap::iterator buffer = mBufferMap.find(handle);
258
259 if (buffer == mBufferMap.end())
260 {
261 return NULL;
262 }
263 else
264 {
265 return buffer->second;
266 }
267}
268
269Shader *ResourceManager::getShader(unsigned int handle)
270{
271 ShaderMap::iterator shader = mShaderMap.find(handle);
272
273 if (shader == mShaderMap.end())
274 {
275 return NULL;
276 }
277 else
278 {
279 return shader->second;
280 }
281}
282
283Texture *ResourceManager::getTexture(unsigned int handle)
284{
285 if (handle == 0) return NULL;
286
287 TextureMap::iterator texture = mTextureMap.find(handle);
288
289 if (texture == mTextureMap.end())
290 {
291 return NULL;
292 }
293 else
294 {
295 return texture->second;
296 }
297}
298
299Program *ResourceManager::getProgram(unsigned int handle)
300{
301 ProgramMap::iterator program = mProgramMap.find(handle);
302
303 if (program == mProgramMap.end())
304 {
305 return NULL;
306 }
307 else
308 {
309 return program->second;
310 }
311}
312
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400313Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000314{
315 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
316
317 if (renderbuffer == mRenderbufferMap.end())
318 {
319 return NULL;
320 }
321 else
322 {
323 return renderbuffer->second;
324 }
325}
326
Jamie Madilldc356042013-07-19 16:36:57 -0400327Sampler *ResourceManager::getSampler(unsigned int handle)
328{
329 auto sampler = mSamplerMap.find(handle);
330
331 if (sampler == mSamplerMap.end())
332 {
333 return NULL;
334 }
335 else
336 {
337 return sampler->second;
338 }
339}
340
Jamie Madillcd055f82013-07-26 11:55:15 -0400341FenceSync *ResourceManager::getFenceSync(unsigned int handle)
342{
343 auto fenceObjectIt = mFenceSyncMap.find(handle);
344
345 if (fenceObjectIt == mFenceSyncMap.end())
346 {
347 return NULL;
348 }
349 else
350 {
351 return fenceObjectIt->second;
352 }
353}
354
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400355void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000356{
357 mRenderbufferMap[handle] = buffer;
358}
359
360void ResourceManager::checkBufferAllocation(unsigned int buffer)
361{
362 if (buffer != 0 && !getBuffer(buffer))
363 {
Brandon Jonesd38f9262014-06-18 16:26:45 -0700364 Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000365 mBufferMap[buffer] = bufferObject;
366 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000367 }
368}
369
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000370void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000371{
372 if (!getTexture(texture) && texture != 0)
373 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000374 Texture *textureObject;
375
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000376 if (type == TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000377 {
Brandon Jones6053a522014-07-25 16:22:09 -0700378 textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000379 }
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000380 else if (type == TEXTURE_CUBE)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000381 {
Brandon Jones6053a522014-07-25 16:22:09 -0700382 textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000383 }
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000384 else if (type == TEXTURE_3D)
385 {
Brandon Jones6053a522014-07-25 16:22:09 -0700386 textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000387 }
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000388 else if (type == TEXTURE_2D_ARRAY)
389 {
Brandon Jones6053a522014-07-25 16:22:09 -0700390 textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000391 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000392 else
393 {
394 UNREACHABLE();
395 return;
396 }
397
398 mTextureMap[texture] = textureObject;
399 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000400 }
401}
402
403void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
404{
405 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
406 {
Geoff Lange4a492b2014-06-19 14:14:41 -0400407 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000408 mRenderbufferMap[renderbuffer] = renderbufferObject;
409 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000410 }
411}
412
Jamie Madilldc356042013-07-19 16:36:57 -0400413void ResourceManager::checkSamplerAllocation(GLuint sampler)
414{
415 if (sampler != 0 && !getSampler(sampler))
416 {
417 Sampler *samplerObject = new Sampler(sampler);
418 mSamplerMap[sampler] = samplerObject;
419 samplerObject->addRef();
420 }
421}
422
423bool ResourceManager::isSampler(GLuint sampler)
424{
425 return mSamplerMap.find(sampler) != mSamplerMap.end();
426}
427
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000428}