blob: 7feab2a9314802f8cee6f43c3c36aaeb3e4cefb3 [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"
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000014#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000015#include "libGLESv2/Shader.h"
16#include "libGLESv2/Texture.h"
daniel@transgaming.com370482e2012-11-28 19:32:13 +000017#include "libGLESv2/renderer/Renderer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000018
19namespace gl
20{
daniel@transgaming.com370482e2012-11-28 19:32:13 +000021ResourceManager::ResourceManager(rx::Renderer *renderer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000022{
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000023 mRefCount = 1;
daniel@transgaming.com370482e2012-11-28 19:32:13 +000024 mRenderer = renderer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000025}
26
27ResourceManager::~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
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000055void ResourceManager::addRef()
56{
57 mRefCount++;
58}
59
60void ResourceManager::release()
61{
62 if (--mRefCount == 0)
63 {
64 delete this;
65 }
66}
67
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000068// Returns an unused buffer name
69GLuint ResourceManager::createBuffer()
70{
benvanik@google.com1a233342011-04-28 19:44:39 +000071 GLuint handle = mBufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000072
73 mBufferMap[handle] = NULL;
74
75 return handle;
76}
77
78// Returns an unused shader/program name
79GLuint ResourceManager::createShader(GLenum type)
80{
benvanik@google.com1a233342011-04-28 19:44:39 +000081 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000082
83 if (type == GL_VERTEX_SHADER)
84 {
85 mShaderMap[handle] = new VertexShader(this, handle);
86 }
87 else if (type == GL_FRAGMENT_SHADER)
88 {
89 mShaderMap[handle] = new FragmentShader(this, handle);
90 }
91 else UNREACHABLE();
92
93 return handle;
94}
95
96// Returns an unused program/shader name
97GLuint ResourceManager::createProgram()
98{
benvanik@google.com1a233342011-04-28 19:44:39 +000099 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000100
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000101 mProgramMap[handle] = new Program(mRenderer, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000102
103 return handle;
104}
105
106// Returns an unused texture name
107GLuint ResourceManager::createTexture()
108{
benvanik@google.com1a233342011-04-28 19:44:39 +0000109 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000110
111 mTextureMap[handle] = NULL;
112
113 return handle;
114}
115
116// Returns an unused renderbuffer name
117GLuint ResourceManager::createRenderbuffer()
118{
benvanik@google.com1a233342011-04-28 19:44:39 +0000119 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000120
121 mRenderbufferMap[handle] = NULL;
122
123 return handle;
124}
125
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000126void ResourceManager::deleteBuffer(GLuint buffer)
127{
128 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
129
130 if (bufferObject != mBufferMap.end())
131 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000132 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000133 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000134 mBufferMap.erase(bufferObject);
135 }
136}
137
138void 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 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000146 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000147 delete shaderObject->second;
148 mShaderMap.erase(shaderObject);
149 }
150 else
151 {
152 shaderObject->second->flagForDeletion();
153 }
154 }
155}
156
157void 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 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000165 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000166 delete programObject->second;
167 mProgramMap.erase(programObject);
168 }
169 else
170 {
171 programObject->second->flagForDeletion();
172 }
173 }
174}
175
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000176void ResourceManager::deleteTexture(GLuint texture)
177{
178 TextureMap::iterator textureObject = mTextureMap.find(texture);
179
180 if (textureObject != mTextureMap.end())
181 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000182 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000183 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000184 mTextureMap.erase(textureObject);
185 }
186}
187
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000188void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
189{
190 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
191
192 if (renderbufferObject != mRenderbufferMap.end())
193 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000194 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000195 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000196 mRenderbufferMap.erase(renderbufferObject);
197 }
198}
199
200Buffer *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
214Shader *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
228Texture *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
244Program *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
258Renderbuffer *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
272void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
273{
274 mRenderbufferMap[handle] = buffer;
275}
276
277void ResourceManager::checkBufferAllocation(unsigned int buffer)
278{
279 if (buffer != 0 && !getBuffer(buffer))
280 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000281 Buffer *bufferObject = new Buffer(mRenderer, buffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000282 mBufferMap[buffer] = bufferObject;
283 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000284 }
285}
286
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000287void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000288{
289 if (!getTexture(texture) && texture != 0)
290 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000291 Texture *textureObject;
292
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000293 if (type == TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000294 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000295 textureObject = new Texture2D(mRenderer, texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000296 }
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000297 else if (type == TEXTURE_CUBE)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000298 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000299 textureObject = new TextureCubeMap(mRenderer, texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000300 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000301 else
302 {
303 UNREACHABLE();
304 return;
305 }
306
307 mTextureMap[texture] = textureObject;
308 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000309 }
310}
311
312void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
313{
314 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
315 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000316 Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000317 mRenderbufferMap[renderbuffer] = renderbufferObject;
318 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000319 }
320}
321
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000322}