blob: 59b71a11b2c27ea00875ee6b733d562ca4f73b4d [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00002//
Jamie Madilldc356042013-07-19 16:36:57 -04003// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and
9// retrieves objects which may be shared by multiple Contexts.
10
11#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 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +000098 mShaderMap[handle] = new VertexShader(this, mRenderer, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000099 }
100 else if (type == GL_FRAGMENT_SHADER)
101 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000102 mShaderMap[handle] = new FragmentShader(this, mRenderer, 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
154 mFenceSyncMap[handle] = new FenceSync(mRenderer, handle);
155
156 return handle;
157}
158
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000159void ResourceManager::deleteBuffer(GLuint buffer)
160{
161 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
162
163 if (bufferObject != mBufferMap.end())
164 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000165 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000166 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000167 mBufferMap.erase(bufferObject);
168 }
169}
170
171void ResourceManager::deleteShader(GLuint shader)
172{
173 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
174
175 if (shaderObject != mShaderMap.end())
176 {
177 if (shaderObject->second->getRefCount() == 0)
178 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000179 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000180 delete shaderObject->second;
181 mShaderMap.erase(shaderObject);
182 }
183 else
184 {
185 shaderObject->second->flagForDeletion();
186 }
187 }
188}
189
190void ResourceManager::deleteProgram(GLuint program)
191{
192 ProgramMap::iterator programObject = mProgramMap.find(program);
193
194 if (programObject != mProgramMap.end())
195 {
196 if (programObject->second->getRefCount() == 0)
197 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000198 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000199 delete programObject->second;
200 mProgramMap.erase(programObject);
201 }
202 else
203 {
204 programObject->second->flagForDeletion();
205 }
206 }
207}
208
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000209void ResourceManager::deleteTexture(GLuint texture)
210{
211 TextureMap::iterator textureObject = mTextureMap.find(texture);
212
213 if (textureObject != mTextureMap.end())
214 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000215 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000216 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000217 mTextureMap.erase(textureObject);
218 }
219}
220
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000221void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
222{
223 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
224
225 if (renderbufferObject != mRenderbufferMap.end())
226 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000227 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000228 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000229 mRenderbufferMap.erase(renderbufferObject);
230 }
231}
232
Jamie Madilldc356042013-07-19 16:36:57 -0400233void ResourceManager::deleteSampler(GLuint sampler)
234{
235 auto samplerObject = mSamplerMap.find(sampler);
236
237 if (samplerObject != mSamplerMap.end())
238 {
Geoff Lang79931902014-02-03 14:29:42 -0500239 mSamplerHandleAllocator.release(samplerObject->first);
Jamie Madilldc356042013-07-19 16:36:57 -0400240 if (samplerObject->second) samplerObject->second->release();
241 mSamplerMap.erase(samplerObject);
242 }
243}
244
Jamie Madillcd055f82013-07-26 11:55:15 -0400245void ResourceManager::deleteFenceSync(GLuint fenceSync)
246{
247 auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
248
249 if (fenceObjectIt != mFenceSyncMap.end())
250 {
251 mFenceSyncHandleAllocator.release(fenceObjectIt->first);
252 if (fenceObjectIt->second) fenceObjectIt->second->release();
253 mFenceSyncMap.erase(fenceObjectIt);
254 }
255}
256
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000257Buffer *ResourceManager::getBuffer(unsigned int handle)
258{
259 BufferMap::iterator buffer = mBufferMap.find(handle);
260
261 if (buffer == mBufferMap.end())
262 {
263 return NULL;
264 }
265 else
266 {
267 return buffer->second;
268 }
269}
270
271Shader *ResourceManager::getShader(unsigned int handle)
272{
273 ShaderMap::iterator shader = mShaderMap.find(handle);
274
275 if (shader == mShaderMap.end())
276 {
277 return NULL;
278 }
279 else
280 {
281 return shader->second;
282 }
283}
284
285Texture *ResourceManager::getTexture(unsigned int handle)
286{
287 if (handle == 0) return NULL;
288
289 TextureMap::iterator texture = mTextureMap.find(handle);
290
291 if (texture == mTextureMap.end())
292 {
293 return NULL;
294 }
295 else
296 {
297 return texture->second;
298 }
299}
300
301Program *ResourceManager::getProgram(unsigned int handle)
302{
303 ProgramMap::iterator program = mProgramMap.find(handle);
304
305 if (program == mProgramMap.end())
306 {
307 return NULL;
308 }
309 else
310 {
311 return program->second;
312 }
313}
314
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400315Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000316{
317 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
318
319 if (renderbuffer == mRenderbufferMap.end())
320 {
321 return NULL;
322 }
323 else
324 {
325 return renderbuffer->second;
326 }
327}
328
Jamie Madilldc356042013-07-19 16:36:57 -0400329Sampler *ResourceManager::getSampler(unsigned int handle)
330{
331 auto sampler = mSamplerMap.find(handle);
332
333 if (sampler == mSamplerMap.end())
334 {
335 return NULL;
336 }
337 else
338 {
339 return sampler->second;
340 }
341}
342
Jamie Madillcd055f82013-07-26 11:55:15 -0400343FenceSync *ResourceManager::getFenceSync(unsigned int handle)
344{
345 auto fenceObjectIt = mFenceSyncMap.find(handle);
346
347 if (fenceObjectIt == mFenceSyncMap.end())
348 {
349 return NULL;
350 }
351 else
352 {
353 return fenceObjectIt->second;
354 }
355}
356
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400357void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000358{
359 mRenderbufferMap[handle] = buffer;
360}
361
362void ResourceManager::checkBufferAllocation(unsigned int buffer)
363{
364 if (buffer != 0 && !getBuffer(buffer))
365 {
Brandon Jonesd38f9262014-06-18 16:26:45 -0700366 Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000367 mBufferMap[buffer] = bufferObject;
368 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000369 }
370}
371
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000372void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000373{
374 if (!getTexture(texture) && texture != 0)
375 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000376 Texture *textureObject;
377
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000378 if (type == TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000379 {
Brandon Jonesf47bebc2014-07-09 14:28:42 -0700380 textureObject = new Texture2D(mRenderer->createTexture2D(), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000381 }
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000382 else if (type == TEXTURE_CUBE)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000383 {
Brandon Jones0511e802014-07-14 16:27:26 -0700384 textureObject = new TextureCubeMap(mRenderer->createTextureCube(), texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000385 }
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000386 else if (type == TEXTURE_3D)
387 {
388 textureObject = new Texture3D(mRenderer, texture);
389 }
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000390 else if (type == TEXTURE_2D_ARRAY)
391 {
392 textureObject = new Texture2DArray(mRenderer, texture);
393 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000394 else
395 {
396 UNREACHABLE();
397 return;
398 }
399
400 mTextureMap[texture] = textureObject;
401 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000402 }
403}
404
405void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
406{
407 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
408 {
Geoff Lange4a492b2014-06-19 14:14:41 -0400409 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000410 mRenderbufferMap[renderbuffer] = renderbufferObject;
411 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000412 }
413}
414
Jamie Madilldc356042013-07-19 16:36:57 -0400415void ResourceManager::checkSamplerAllocation(GLuint sampler)
416{
417 if (sampler != 0 && !getSampler(sampler))
418 {
419 Sampler *samplerObject = new Sampler(sampler);
420 mSamplerMap[sampler] = samplerObject;
421 samplerObject->addRef();
422 }
423}
424
425bool ResourceManager::isSampler(GLuint sampler)
426{
427 return mSamplerMap.find(sampler) != mSamplerMap.end();
428}
429
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000430}