blob: 890bd8398006519dd1a1fbdfb2a90d2a15553f64 [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"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000019
20namespace gl
21{
daniel@transgaming.com370482e2012-11-28 19:32:13 +000022ResourceManager::ResourceManager(rx::Renderer *renderer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000023{
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000024 mRefCount = 1;
daniel@transgaming.com370482e2012-11-28 19:32:13 +000025 mRenderer = renderer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000026}
27
28ResourceManager::~ResourceManager()
29{
30 while (!mBufferMap.empty())
31 {
32 deleteBuffer(mBufferMap.begin()->first);
33 }
34
35 while (!mProgramMap.empty())
36 {
37 deleteProgram(mProgramMap.begin()->first);
38 }
39
40 while (!mShaderMap.empty())
41 {
42 deleteShader(mShaderMap.begin()->first);
43 }
44
45 while (!mRenderbufferMap.empty())
46 {
47 deleteRenderbuffer(mRenderbufferMap.begin()->first);
48 }
49
50 while (!mTextureMap.empty())
51 {
52 deleteTexture(mTextureMap.begin()->first);
53 }
Jamie Madilldc356042013-07-19 16:36:57 -040054
55 while (!mSamplerMap.empty())
56 {
57 deleteSampler(mSamplerMap.begin()->first);
58 }
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000059}
60
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000061void ResourceManager::addRef()
62{
63 mRefCount++;
64}
65
66void ResourceManager::release()
67{
68 if (--mRefCount == 0)
69 {
70 delete this;
71 }
72}
73
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000074// Returns an unused buffer name
75GLuint ResourceManager::createBuffer()
76{
benvanik@google.com1a233342011-04-28 19:44:39 +000077 GLuint handle = mBufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000078
79 mBufferMap[handle] = NULL;
80
81 return handle;
82}
83
84// Returns an unused shader/program name
85GLuint ResourceManager::createShader(GLenum type)
86{
benvanik@google.com1a233342011-04-28 19:44:39 +000087 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000088
89 if (type == GL_VERTEX_SHADER)
90 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +000091 mShaderMap[handle] = new VertexShader(this, mRenderer, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000092 }
93 else if (type == GL_FRAGMENT_SHADER)
94 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +000095 mShaderMap[handle] = new FragmentShader(this, mRenderer, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000096 }
97 else UNREACHABLE();
98
99 return handle;
100}
101
102// Returns an unused program/shader name
103GLuint ResourceManager::createProgram()
104{
benvanik@google.com1a233342011-04-28 19:44:39 +0000105 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000106
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000107 mProgramMap[handle] = new Program(mRenderer, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000108
109 return handle;
110}
111
112// Returns an unused texture name
113GLuint ResourceManager::createTexture()
114{
benvanik@google.com1a233342011-04-28 19:44:39 +0000115 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000116
117 mTextureMap[handle] = NULL;
118
119 return handle;
120}
121
122// Returns an unused renderbuffer name
123GLuint ResourceManager::createRenderbuffer()
124{
benvanik@google.com1a233342011-04-28 19:44:39 +0000125 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000126
127 mRenderbufferMap[handle] = NULL;
128
129 return handle;
130}
131
Jamie Madilldc356042013-07-19 16:36:57 -0400132// Returns an unused sampler name
133GLuint ResourceManager::createSampler()
134{
135 GLuint handle = mSamplerHandleAllocator.allocate();
136
137 mSamplerMap[handle] = NULL;
138
139 return handle;
140}
141
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000142void ResourceManager::deleteBuffer(GLuint buffer)
143{
144 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
145
146 if (bufferObject != mBufferMap.end())
147 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000148 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000149 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000150 mBufferMap.erase(bufferObject);
151 }
152}
153
154void ResourceManager::deleteShader(GLuint shader)
155{
156 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
157
158 if (shaderObject != mShaderMap.end())
159 {
160 if (shaderObject->second->getRefCount() == 0)
161 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000162 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000163 delete shaderObject->second;
164 mShaderMap.erase(shaderObject);
165 }
166 else
167 {
168 shaderObject->second->flagForDeletion();
169 }
170 }
171}
172
173void ResourceManager::deleteProgram(GLuint program)
174{
175 ProgramMap::iterator programObject = mProgramMap.find(program);
176
177 if (programObject != mProgramMap.end())
178 {
179 if (programObject->second->getRefCount() == 0)
180 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000181 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000182 delete programObject->second;
183 mProgramMap.erase(programObject);
184 }
185 else
186 {
187 programObject->second->flagForDeletion();
188 }
189 }
190}
191
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000192void ResourceManager::deleteTexture(GLuint texture)
193{
194 TextureMap::iterator textureObject = mTextureMap.find(texture);
195
196 if (textureObject != mTextureMap.end())
197 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000198 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000199 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000200 mTextureMap.erase(textureObject);
201 }
202}
203
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000204void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
205{
206 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
207
208 if (renderbufferObject != mRenderbufferMap.end())
209 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000210 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000211 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000212 mRenderbufferMap.erase(renderbufferObject);
213 }
214}
215
Jamie Madilldc356042013-07-19 16:36:57 -0400216void ResourceManager::deleteSampler(GLuint sampler)
217{
218 auto samplerObject = mSamplerMap.find(sampler);
219
220 if (samplerObject != mSamplerMap.end())
221 {
222 mRenderbufferHandleAllocator.release(samplerObject->first);
223 if (samplerObject->second) samplerObject->second->release();
224 mSamplerMap.erase(samplerObject);
225 }
226}
227
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000228Buffer *ResourceManager::getBuffer(unsigned int handle)
229{
230 BufferMap::iterator buffer = mBufferMap.find(handle);
231
232 if (buffer == mBufferMap.end())
233 {
234 return NULL;
235 }
236 else
237 {
238 return buffer->second;
239 }
240}
241
242Shader *ResourceManager::getShader(unsigned int handle)
243{
244 ShaderMap::iterator shader = mShaderMap.find(handle);
245
246 if (shader == mShaderMap.end())
247 {
248 return NULL;
249 }
250 else
251 {
252 return shader->second;
253 }
254}
255
256Texture *ResourceManager::getTexture(unsigned int handle)
257{
258 if (handle == 0) return NULL;
259
260 TextureMap::iterator texture = mTextureMap.find(handle);
261
262 if (texture == mTextureMap.end())
263 {
264 return NULL;
265 }
266 else
267 {
268 return texture->second;
269 }
270}
271
272Program *ResourceManager::getProgram(unsigned int handle)
273{
274 ProgramMap::iterator program = mProgramMap.find(handle);
275
276 if (program == mProgramMap.end())
277 {
278 return NULL;
279 }
280 else
281 {
282 return program->second;
283 }
284}
285
286Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
287{
288 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
289
290 if (renderbuffer == mRenderbufferMap.end())
291 {
292 return NULL;
293 }
294 else
295 {
296 return renderbuffer->second;
297 }
298}
299
Jamie Madilldc356042013-07-19 16:36:57 -0400300Sampler *ResourceManager::getSampler(unsigned int handle)
301{
302 auto sampler = mSamplerMap.find(handle);
303
304 if (sampler == mSamplerMap.end())
305 {
306 return NULL;
307 }
308 else
309 {
310 return sampler->second;
311 }
312}
313
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000314void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
315{
316 mRenderbufferMap[handle] = buffer;
317}
318
319void ResourceManager::checkBufferAllocation(unsigned int buffer)
320{
321 if (buffer != 0 && !getBuffer(buffer))
322 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000323 Buffer *bufferObject = new Buffer(mRenderer, buffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000324 mBufferMap[buffer] = bufferObject;
325 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000326 }
327}
328
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000329void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000330{
331 if (!getTexture(texture) && texture != 0)
332 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000333 Texture *textureObject;
334
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000335 if (type == TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000336 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000337 textureObject = new Texture2D(mRenderer, texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000338 }
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000339 else if (type == TEXTURE_CUBE)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000340 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000341 textureObject = new TextureCubeMap(mRenderer, texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000342 }
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000343 else if (type == TEXTURE_3D)
344 {
345 textureObject = new Texture3D(mRenderer, texture);
346 }
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000347 else if (type == TEXTURE_2D_ARRAY)
348 {
349 textureObject = new Texture2DArray(mRenderer, texture);
350 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000351 else
352 {
353 UNREACHABLE();
354 return;
355 }
356
357 mTextureMap[texture] = textureObject;
358 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000359 }
360}
361
362void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
363{
364 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
365 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000366 Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000367 mRenderbufferMap[renderbuffer] = renderbufferObject;
368 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000369 }
370}
371
Jamie Madilldc356042013-07-19 16:36:57 -0400372void ResourceManager::checkSamplerAllocation(GLuint sampler)
373{
374 if (sampler != 0 && !getSampler(sampler))
375 {
376 Sampler *samplerObject = new Sampler(sampler);
377 mSamplerMap[sampler] = samplerObject;
378 samplerObject->addRef();
379 }
380}
381
382bool ResourceManager::isSampler(GLuint sampler)
383{
384 return mSamplerMap.find(sampler) != mSamplerMap.end();
385}
386
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000387}