blob: ae26352e058e6c7130f9eb6565f34fce8beba695 [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{
benvanik@google.com1a233342011-04-28 19:44:39 +000069 GLuint handle = mBufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000070
71 mBufferMap[handle] = NULL;
72
73 return handle;
74}
75
76// Returns an unused shader/program name
77GLuint ResourceManager::createShader(GLenum type)
78{
benvanik@google.com1a233342011-04-28 19:44:39 +000079 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000080
81 if (type == GL_VERTEX_SHADER)
82 {
83 mShaderMap[handle] = new VertexShader(this, handle);
84 }
85 else if (type == GL_FRAGMENT_SHADER)
86 {
87 mShaderMap[handle] = new FragmentShader(this, handle);
88 }
89 else UNREACHABLE();
90
91 return handle;
92}
93
94// Returns an unused program/shader name
95GLuint ResourceManager::createProgram()
96{
benvanik@google.com1a233342011-04-28 19:44:39 +000097 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000098
99 mProgramMap[handle] = new Program(this, handle);
100
101 return handle;
102}
103
104// Returns an unused texture name
105GLuint ResourceManager::createTexture()
106{
benvanik@google.com1a233342011-04-28 19:44:39 +0000107 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000108
109 mTextureMap[handle] = NULL;
110
111 return handle;
112}
113
114// Returns an unused renderbuffer name
115GLuint ResourceManager::createRenderbuffer()
116{
benvanik@google.com1a233342011-04-28 19:44:39 +0000117 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000118
119 mRenderbufferMap[handle] = NULL;
120
121 return handle;
122}
123
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000124void ResourceManager::deleteBuffer(GLuint buffer)
125{
126 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
127
128 if (bufferObject != mBufferMap.end())
129 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000130 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000131 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000132 mBufferMap.erase(bufferObject);
133 }
134}
135
136void ResourceManager::deleteShader(GLuint shader)
137{
138 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
139
140 if (shaderObject != mShaderMap.end())
141 {
142 if (shaderObject->second->getRefCount() == 0)
143 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000144 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000145 delete shaderObject->second;
146 mShaderMap.erase(shaderObject);
147 }
148 else
149 {
150 shaderObject->second->flagForDeletion();
151 }
152 }
153}
154
155void ResourceManager::deleteProgram(GLuint program)
156{
157 ProgramMap::iterator programObject = mProgramMap.find(program);
158
159 if (programObject != mProgramMap.end())
160 {
161 if (programObject->second->getRefCount() == 0)
162 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000163 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000164 delete programObject->second;
165 mProgramMap.erase(programObject);
166 }
167 else
168 {
169 programObject->second->flagForDeletion();
170 }
171 }
172}
173
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000174void ResourceManager::deleteTexture(GLuint texture)
175{
176 TextureMap::iterator textureObject = mTextureMap.find(texture);
177
178 if (textureObject != mTextureMap.end())
179 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000180 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000181 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000182 mTextureMap.erase(textureObject);
183 }
184}
185
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000186void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
187{
188 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
189
190 if (renderbufferObject != mRenderbufferMap.end())
191 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000192 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000193 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000194 mRenderbufferMap.erase(renderbufferObject);
195 }
196}
197
198Buffer *ResourceManager::getBuffer(unsigned int handle)
199{
200 BufferMap::iterator buffer = mBufferMap.find(handle);
201
202 if (buffer == mBufferMap.end())
203 {
204 return NULL;
205 }
206 else
207 {
208 return buffer->second;
209 }
210}
211
212Shader *ResourceManager::getShader(unsigned int handle)
213{
214 ShaderMap::iterator shader = mShaderMap.find(handle);
215
216 if (shader == mShaderMap.end())
217 {
218 return NULL;
219 }
220 else
221 {
222 return shader->second;
223 }
224}
225
226Texture *ResourceManager::getTexture(unsigned int handle)
227{
228 if (handle == 0) return NULL;
229
230 TextureMap::iterator texture = mTextureMap.find(handle);
231
232 if (texture == mTextureMap.end())
233 {
234 return NULL;
235 }
236 else
237 {
238 return texture->second;
239 }
240}
241
242Program *ResourceManager::getProgram(unsigned int handle)
243{
244 ProgramMap::iterator program = mProgramMap.find(handle);
245
246 if (program == mProgramMap.end())
247 {
248 return NULL;
249 }
250 else
251 {
252 return program->second;
253 }
254}
255
256Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
257{
258 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
259
260 if (renderbuffer == mRenderbufferMap.end())
261 {
262 return NULL;
263 }
264 else
265 {
266 return renderbuffer->second;
267 }
268}
269
270void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
271{
272 mRenderbufferMap[handle] = buffer;
273}
274
275void ResourceManager::checkBufferAllocation(unsigned int buffer)
276{
277 if (buffer != 0 && !getBuffer(buffer))
278 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000279 Buffer *bufferObject = new Buffer(buffer);
280 mBufferMap[buffer] = bufferObject;
281 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000282 }
283}
284
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000285void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000286{
287 if (!getTexture(texture) && texture != 0)
288 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000289 Texture *textureObject;
290
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000291 if (type == TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000292 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000293 textureObject = new Texture2D(texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000294 }
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000295 else if (type == TEXTURE_CUBE)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000296 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000297 textureObject = new TextureCubeMap(texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000298 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000299 else
300 {
301 UNREACHABLE();
302 return;
303 }
304
305 mTextureMap[texture] = textureObject;
306 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000307 }
308}
309
310void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
311{
312 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
313 {
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000314 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000315 mRenderbufferMap[renderbuffer] = renderbufferObject;
316 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000317 }
318}
319
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000320}