1 //
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
18 namespace gl
19 {
ResourceManager()20 ResourceManager::ResourceManager()
21 {
22 mRefCount = 1;
23 }
24
~ResourceManager()25 ResourceManager::~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
addRef()53 void ResourceManager::addRef()
54 {
55 mRefCount++;
56 }
57
release()58 void ResourceManager::release()
59 {
60 if (--mRefCount == 0)
61 {
62 delete this;
63 }
64 }
65
66 // Returns an unused buffer name
createBuffer()67 GLuint 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
createShader(GLenum type)82 GLuint 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
createProgram()105 GLuint 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
createTexture()120 GLuint 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
createRenderbuffer()135 GLuint 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
deleteBuffer(GLuint buffer)149 void ResourceManager::deleteBuffer(GLuint buffer)
150 {
151 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
152
153 if (bufferObject != mBufferMap.end())
154 {
155 if (bufferObject->second) bufferObject->second->release();
156 mBufferMap.erase(bufferObject);
157 }
158 }
159
deleteShader(GLuint shader)160 void 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
deleteProgram(GLuint program)178 void 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
deleteTexture(GLuint texture)196 void ResourceManager::deleteTexture(GLuint texture)
197 {
198 TextureMap::iterator textureObject = mTextureMap.find(texture);
199
200 if (textureObject != mTextureMap.end())
201 {
202 if (textureObject->second) textureObject->second->release();
203 mTextureMap.erase(textureObject);
204 }
205 }
206
deleteRenderbuffer(GLuint renderbuffer)207 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
208 {
209 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
210
211 if (renderbufferObject != mRenderbufferMap.end())
212 {
213 if (renderbufferObject->second) renderbufferObject->second->release();
214 mRenderbufferMap.erase(renderbufferObject);
215 }
216 }
217
getBuffer(unsigned int handle)218 Buffer *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
getShader(unsigned int handle)232 Shader *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
getTexture(unsigned int handle)246 Texture *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
getProgram(unsigned int handle)262 Program *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
getRenderbuffer(unsigned int handle)276 Renderbuffer *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
setRenderbuffer(GLuint handle,Renderbuffer * buffer)290 void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
291 {
292 mRenderbufferMap[handle] = buffer;
293 }
294
checkBufferAllocation(unsigned int buffer)295 void ResourceManager::checkBufferAllocation(unsigned int buffer)
296 {
297 if (buffer != 0 && !getBuffer(buffer))
298 {
299 Buffer *bufferObject = new Buffer(buffer);
300 mBufferMap[buffer] = bufferObject;
301 bufferObject->addRef();
302 }
303 }
304
checkTextureAllocation(GLuint texture,SamplerType type)305 void ResourceManager::checkTextureAllocation(GLuint texture, SamplerType type)
306 {
307 if (!getTexture(texture) && texture != 0)
308 {
309 Texture *textureObject;
310
311 if (type == SAMPLER_2D)
312 {
313 textureObject = new Texture2D(texture);
314 }
315 else if (type == SAMPLER_CUBE)
316 {
317 textureObject = new TextureCubeMap(texture);
318 }
319 else
320 {
321 UNREACHABLE();
322 return;
323 }
324
325 mTextureMap[texture] = textureObject;
326 textureObject->addRef();
327 }
328 }
329
checkRenderbufferAllocation(GLuint renderbuffer)330 void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
331 {
332 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
333 {
334 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
335 mRenderbufferMap[renderbuffer] = renderbufferObject;
336 renderbufferObject->addRef();
337 }
338 }
339
340 }
341