blob: 12a86c1d91fb75d64a20d28dc5c0dc0eede808a2 [file] [log] [blame]
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// 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"
14#include "libGLESv2/RenderBuffer.h"
15#include "libGLESv2/Shader.h"
16#include "libGLESv2/Texture.h"
17
18namespace gl
19{
20ResourceManager::ResourceManager()
21{
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000022 mRefCount = 1;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000023}
24
25ResourceManager::~ResourceManager()
26{
27 while (!mBufferMap.empty())
28 {
29 deleteBuffer(mBufferMap.begin()->first);
30 }
31
32 while (!mProgramMap.empty())
33 {
34 deleteProgram(mProgramMap.begin()->first);
35 }
36
37 while (!mShaderMap.empty())
38 {
39 deleteShader(mShaderMap.begin()->first);
40 }
41
42 while (!mRenderbufferMap.empty())
43 {
44 deleteRenderbuffer(mRenderbufferMap.begin()->first);
45 }
46
47 while (!mTextureMap.empty())
48 {
49 deleteTexture(mTextureMap.begin()->first);
50 }
51}
52
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000053void ResourceManager::addRef()
54{
55 mRefCount++;
56}
57
58void ResourceManager::release()
59{
60 if (--mRefCount == 0)
61 {
62 delete this;
63 }
64}
65
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000066// Returns an unused buffer name
67GLuint ResourceManager::createBuffer()
68{
69 unsigned int handle = 1;
70
71 while (mBufferMap.find(handle) != mBufferMap.end())
72 {
73 handle++;
74 }
75
76 mBufferMap[handle] = NULL;
77
78 return handle;
79}
80
81// Returns an unused shader/program name
82GLuint ResourceManager::createShader(GLenum type)
83{
84 unsigned int handle = 1;
85
86 while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end()) // Shared name space
87 {
88 handle++;
89 }
90
91 if (type == GL_VERTEX_SHADER)
92 {
93 mShaderMap[handle] = new VertexShader(this, handle);
94 }
95 else if (type == GL_FRAGMENT_SHADER)
96 {
97 mShaderMap[handle] = new FragmentShader(this, handle);
98 }
99 else UNREACHABLE();
100
101 return handle;
102}
103
104// Returns an unused program/shader name
105GLuint ResourceManager::createProgram()
106{
107 unsigned int handle = 1;
108
109 while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end()) // Shared name space
110 {
111 handle++;
112 }
113
114 mProgramMap[handle] = new Program(this, handle);
115
116 return handle;
117}
118
119// Returns an unused texture name
120GLuint ResourceManager::createTexture()
121{
122 unsigned int handle = 1;
123
124 while (mTextureMap.find(handle) != mTextureMap.end())
125 {
126 handle++;
127 }
128
129 mTextureMap[handle] = NULL;
130
131 return handle;
132}
133
134// Returns an unused renderbuffer name
135GLuint ResourceManager::createRenderbuffer()
136{
137 unsigned int handle = 1;
138
139 while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
140 {
141 handle++;
142 }
143
144 mRenderbufferMap[handle] = NULL;
145
146 return handle;
147}
148
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000149void ResourceManager::deleteBuffer(GLuint buffer)
150{
151 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
152
153 if (bufferObject != mBufferMap.end())
154 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000155 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000156 mBufferMap.erase(bufferObject);
157 }
158}
159
160void ResourceManager::deleteShader(GLuint shader)
161{
162 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
163
164 if (shaderObject != mShaderMap.end())
165 {
166 if (shaderObject->second->getRefCount() == 0)
167 {
168 delete shaderObject->second;
169 mShaderMap.erase(shaderObject);
170 }
171 else
172 {
173 shaderObject->second->flagForDeletion();
174 }
175 }
176}
177
178void ResourceManager::deleteProgram(GLuint program)
179{
180 ProgramMap::iterator programObject = mProgramMap.find(program);
181
182 if (programObject != mProgramMap.end())
183 {
184 if (programObject->second->getRefCount() == 0)
185 {
186 delete programObject->second;
187 mProgramMap.erase(programObject);
188 }
189 else
190 {
191 programObject->second->flagForDeletion();
192 }
193 }
194}
195
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000196void ResourceManager::deleteTexture(GLuint texture)
197{
198 TextureMap::iterator textureObject = mTextureMap.find(texture);
199
200 if (textureObject != mTextureMap.end())
201 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000202 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000203 mTextureMap.erase(textureObject);
204 }
205}
206
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000207void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
208{
209 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
210
211 if (renderbufferObject != mRenderbufferMap.end())
212 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000213 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000214 mRenderbufferMap.erase(renderbufferObject);
215 }
216}
217
218Buffer *ResourceManager::getBuffer(unsigned int handle)
219{
220 BufferMap::iterator buffer = mBufferMap.find(handle);
221
222 if (buffer == mBufferMap.end())
223 {
224 return NULL;
225 }
226 else
227 {
228 return buffer->second;
229 }
230}
231
232Shader *ResourceManager::getShader(unsigned int handle)
233{
234 ShaderMap::iterator shader = mShaderMap.find(handle);
235
236 if (shader == mShaderMap.end())
237 {
238 return NULL;
239 }
240 else
241 {
242 return shader->second;
243 }
244}
245
246Texture *ResourceManager::getTexture(unsigned int handle)
247{
248 if (handle == 0) return NULL;
249
250 TextureMap::iterator texture = mTextureMap.find(handle);
251
252 if (texture == mTextureMap.end())
253 {
254 return NULL;
255 }
256 else
257 {
258 return texture->second;
259 }
260}
261
262Program *ResourceManager::getProgram(unsigned int handle)
263{
264 ProgramMap::iterator program = mProgramMap.find(handle);
265
266 if (program == mProgramMap.end())
267 {
268 return NULL;
269 }
270 else
271 {
272 return program->second;
273 }
274}
275
276Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
277{
278 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
279
280 if (renderbuffer == mRenderbufferMap.end())
281 {
282 return NULL;
283 }
284 else
285 {
286 return renderbuffer->second;
287 }
288}
289
290void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
291{
292 mRenderbufferMap[handle] = buffer;
293}
294
295void ResourceManager::checkBufferAllocation(unsigned int buffer)
296{
297 if (buffer != 0 && !getBuffer(buffer))
298 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000299 Buffer *bufferObject = new Buffer(buffer);
300 mBufferMap[buffer] = bufferObject;
301 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000302 }
303}
304
305void ResourceManager::checkTextureAllocation(GLuint texture, SamplerType type)
306{
307 if (!getTexture(texture) && texture != 0)
308 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000309 Texture *textureObject;
310
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000311 if (type == SAMPLER_2D)
312 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000313 textureObject = new Texture2D(texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000314 }
315 else if (type == SAMPLER_CUBE)
316 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000317 textureObject = new TextureCubeMap(texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000318 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000319 else
320 {
321 UNREACHABLE();
322 return;
323 }
324
325 mTextureMap[texture] = textureObject;
326 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000327 }
328}
329
330void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
331{
332 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
333 {
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000334 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000335 mRenderbufferMap[renderbuffer] = renderbufferObject;
336 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000337 }
338}
339
340}