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