blob: 9121de1750f43741d23b1773f62f63a41f1a4a1e [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
10#include "libGLESv2/ResourceManager.h"
11
12#include "libGLESv2/Buffer.h"
13#include "libGLESv2/Program.h"
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000014#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000015#include "libGLESv2/Shader.h"
16#include "libGLESv2/Texture.h"
Jamie Madilldc356042013-07-19 16:36:57 -040017#include "libGLESv2/Sampler.h"
Jamie Madillcd055f82013-07-26 11:55:15 -040018#include "libGLESv2/Fence.h"
Brandon Jonesd38f9262014-06-18 16:26:45 -070019#include "libGLESv2/renderer/Renderer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000020
21namespace gl
22{
daniel@transgaming.com370482e2012-11-28 19:32:13 +000023ResourceManager::ResourceManager(rx::Renderer *renderer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000024{
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000025 mRefCount = 1;
daniel@transgaming.com370482e2012-11-28 19:32:13 +000026 mRenderer = renderer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000027}
28
29ResourceManager::~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 }
Jamie Madilldc356042013-07-19 16:36:57 -040055
56 while (!mSamplerMap.empty())
57 {
58 deleteSampler(mSamplerMap.begin()->first);
59 }
Jamie Madillcd055f82013-07-26 11:55:15 -040060
61 while (!mFenceSyncMap.empty())
62 {
63 deleteFenceSync(mFenceSyncMap.begin()->first);
64 }
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000065}
66
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000067void ResourceManager::addRef()
68{
69 mRefCount++;
70}
71
72void ResourceManager::release()
73{
74 if (--mRefCount == 0)
75 {
76 delete this;
77 }
78}
79
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000080// Returns an unused buffer name
81GLuint ResourceManager::createBuffer()
82{
benvanik@google.com1a233342011-04-28 19:44:39 +000083 GLuint handle = mBufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000084
85 mBufferMap[handle] = NULL;
86
87 return handle;
88}
89
90// Returns an unused shader/program name
91GLuint ResourceManager::createShader(GLenum type)
92{
benvanik@google.com1a233342011-04-28 19:44:39 +000093 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000094
Brandon Jones71620962014-08-20 14:04:59 -070095 if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000096 {
Brandon Jones71620962014-08-20 14:04:59 -070097 mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000098 }
99 else UNREACHABLE();
100
101 return handle;
102}
103
104// Returns an unused program/shader name
105GLuint ResourceManager::createProgram()
106{
benvanik@google.com1a233342011-04-28 19:44:39 +0000107 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000108
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000109 mProgramMap[handle] = new Program(mRenderer, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000110
111 return handle;
112}
113
114// Returns an unused texture name
115GLuint ResourceManager::createTexture()
116{
benvanik@google.com1a233342011-04-28 19:44:39 +0000117 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000118
119 mTextureMap[handle] = NULL;
120
121 return handle;
122}
123
124// Returns an unused renderbuffer name
125GLuint ResourceManager::createRenderbuffer()
126{
benvanik@google.com1a233342011-04-28 19:44:39 +0000127 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000128
129 mRenderbufferMap[handle] = NULL;
130
131 return handle;
132}
133
Jamie Madilldc356042013-07-19 16:36:57 -0400134// Returns an unused sampler name
135GLuint ResourceManager::createSampler()
136{
137 GLuint handle = mSamplerHandleAllocator.allocate();
138
139 mSamplerMap[handle] = NULL;
140
141 return handle;
142}
143
Jamie Madillcd055f82013-07-26 11:55:15 -0400144// Returns the next unused fence name, and allocates the fence
145GLuint ResourceManager::createFenceSync()
146{
147 GLuint handle = mFenceSyncHandleAllocator.allocate();
148
Jamie Madillcfa33e62014-08-19 15:30:41 -0400149 FenceSync *fenceSync = new FenceSync(mRenderer, handle);
150 fenceSync->addRef();
151 mFenceSyncMap[handle] = fenceSync;
Jamie Madillcd055f82013-07-26 11:55:15 -0400152
153 return handle;
154}
155
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000156void ResourceManager::deleteBuffer(GLuint buffer)
157{
158 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
159
160 if (bufferObject != mBufferMap.end())
161 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000162 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000163 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000164 mBufferMap.erase(bufferObject);
165 }
166}
167
168void 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 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000176 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000177 delete shaderObject->second;
178 mShaderMap.erase(shaderObject);
179 }
180 else
181 {
182 shaderObject->second->flagForDeletion();
183 }
184 }
185}
186
187void 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 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000195 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000196 delete programObject->second;
197 mProgramMap.erase(programObject);
198 }
199 else
200 {
201 programObject->second->flagForDeletion();
202 }
203 }
204}
205
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000206void ResourceManager::deleteTexture(GLuint texture)
207{
208 TextureMap::iterator textureObject = mTextureMap.find(texture);
209
210 if (textureObject != mTextureMap.end())
211 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000212 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000213 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000214 mTextureMap.erase(textureObject);
215 }
216}
217
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000218void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
219{
220 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
221
222 if (renderbufferObject != mRenderbufferMap.end())
223 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000224 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000225 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000226 mRenderbufferMap.erase(renderbufferObject);
227 }
228}
229
Jamie Madilldc356042013-07-19 16:36:57 -0400230void ResourceManager::deleteSampler(GLuint sampler)
231{
232 auto samplerObject = mSamplerMap.find(sampler);
233
234 if (samplerObject != mSamplerMap.end())
235 {
Geoff Lang79931902014-02-03 14:29:42 -0500236 mSamplerHandleAllocator.release(samplerObject->first);
Jamie Madilldc356042013-07-19 16:36:57 -0400237 if (samplerObject->second) samplerObject->second->release();
238 mSamplerMap.erase(samplerObject);
239 }
240}
241
Jamie Madillcd055f82013-07-26 11:55:15 -0400242void 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
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000254Buffer *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
268Shader *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
282Texture *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
298Program *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
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400312Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000313{
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
Jamie Madilldc356042013-07-19 16:36:57 -0400326Sampler *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
Jamie Madillcd055f82013-07-26 11:55:15 -0400340FenceSync *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
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400354void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000355{
356 mRenderbufferMap[handle] = buffer;
357}
358
359void ResourceManager::checkBufferAllocation(unsigned int buffer)
360{
361 if (buffer != 0 && !getBuffer(buffer))
362 {
Brandon Jonesd38f9262014-06-18 16:26:45 -0700363 Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000364 mBufferMap[buffer] = bufferObject;
365 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000366 }
367}
368
Geoff Lang76b10c92014-09-05 16:28:14 -0400369void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000370{
371 if (!getTexture(texture) && texture != 0)
372 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000373 Texture *textureObject;
374
Geoff Lang76b10c92014-09-05 16:28:14 -0400375 if (type == GL_TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000376 {
Brandon Jones6053a522014-07-25 16:22:09 -0700377 textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000378 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400379 else if (type == GL_TEXTURE_CUBE_MAP)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000380 {
Brandon Jones6053a522014-07-25 16:22:09 -0700381 textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000382 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400383 else if (type == GL_TEXTURE_3D)
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000384 {
Brandon Jones6053a522014-07-25 16:22:09 -0700385 textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000386 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400387 else if (type == GL_TEXTURE_2D_ARRAY)
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000388 {
Brandon Jones6053a522014-07-25 16:22:09 -0700389 textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000390 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000391 else
392 {
393 UNREACHABLE();
394 return;
395 }
396
397 mTextureMap[texture] = textureObject;
398 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000399 }
400}
401
402void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
403{
404 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
405 {
Geoff Lange4a492b2014-06-19 14:14:41 -0400406 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000407 mRenderbufferMap[renderbuffer] = renderbufferObject;
408 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000409 }
410}
411
Jamie Madilldc356042013-07-19 16:36:57 -0400412void 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
422bool ResourceManager::isSampler(GLuint sampler)
423{
424 return mSamplerMap.find(sampler) != mSamplerMap.end();
425}
426
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000427}