blob: 97c28cb9913424c6f80830c6c22aa393511f62e5 [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00002//
Jamie Madilldc356042013-07-19 16:36:57 -04003// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00004// 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"
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000015#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000016#include "libGLESv2/Shader.h"
17#include "libGLESv2/Texture.h"
Jamie Madilldc356042013-07-19 16:36:57 -040018#include "libGLESv2/Sampler.h"
Jamie Madillcd055f82013-07-26 11:55:15 -040019#include "libGLESv2/Fence.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000020
21namespace gl
22{
daniel@transgaming.com370482e2012-11-28 19:32:13 +000023ResourceManager::ResourceManager(rx::Renderer *renderer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000024{
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000025 mRefCount = 1;
daniel@transgaming.com370482e2012-11-28 19:32:13 +000026 mRenderer = renderer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000027}
28
29ResourceManager::~ResourceManager()
30{
31 while (!mBufferMap.empty())
32 {
33 deleteBuffer(mBufferMap.begin()->first);
34 }
35
36 while (!mProgramMap.empty())
37 {
38 deleteProgram(mProgramMap.begin()->first);
39 }
40
41 while (!mShaderMap.empty())
42 {
43 deleteShader(mShaderMap.begin()->first);
44 }
45
46 while (!mRenderbufferMap.empty())
47 {
48 deleteRenderbuffer(mRenderbufferMap.begin()->first);
49 }
50
51 while (!mTextureMap.empty())
52 {
53 deleteTexture(mTextureMap.begin()->first);
54 }
Jamie Madilldc356042013-07-19 16:36:57 -040055
56 while (!mSamplerMap.empty())
57 {
58 deleteSampler(mSamplerMap.begin()->first);
59 }
Jamie Madillcd055f82013-07-26 11:55:15 -040060
61 while (!mFenceSyncMap.empty())
62 {
63 deleteFenceSync(mFenceSyncMap.begin()->first);
64 }
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000065}
66
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000067void ResourceManager::addRef()
68{
69 mRefCount++;
70}
71
72void ResourceManager::release()
73{
74 if (--mRefCount == 0)
75 {
76 delete this;
77 }
78}
79
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000080// Returns an unused buffer name
81GLuint ResourceManager::createBuffer()
82{
benvanik@google.com1a233342011-04-28 19:44:39 +000083 GLuint handle = mBufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000084
85 mBufferMap[handle] = NULL;
86
87 return handle;
88}
89
90// Returns an unused shader/program name
91GLuint ResourceManager::createShader(GLenum type)
92{
benvanik@google.com1a233342011-04-28 19:44:39 +000093 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000094
95 if (type == GL_VERTEX_SHADER)
96 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +000097 mShaderMap[handle] = new VertexShader(this, mRenderer, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000098 }
99 else if (type == GL_FRAGMENT_SHADER)
100 {
shannon.woods@transgaming.comb73964e2013-01-25 21:49:14 +0000101 mShaderMap[handle] = new FragmentShader(this, mRenderer, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000102 }
103 else UNREACHABLE();
104
105 return handle;
106}
107
108// Returns an unused program/shader name
109GLuint ResourceManager::createProgram()
110{
benvanik@google.com1a233342011-04-28 19:44:39 +0000111 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000112
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000113 mProgramMap[handle] = new Program(mRenderer, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000114
115 return handle;
116}
117
118// Returns an unused texture name
119GLuint ResourceManager::createTexture()
120{
benvanik@google.com1a233342011-04-28 19:44:39 +0000121 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000122
123 mTextureMap[handle] = NULL;
124
125 return handle;
126}
127
128// Returns an unused renderbuffer name
129GLuint ResourceManager::createRenderbuffer()
130{
benvanik@google.com1a233342011-04-28 19:44:39 +0000131 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000132
133 mRenderbufferMap[handle] = NULL;
134
135 return handle;
136}
137
Jamie Madilldc356042013-07-19 16:36:57 -0400138// Returns an unused sampler name
139GLuint ResourceManager::createSampler()
140{
141 GLuint handle = mSamplerHandleAllocator.allocate();
142
143 mSamplerMap[handle] = NULL;
144
145 return handle;
146}
147
Jamie Madillcd055f82013-07-26 11:55:15 -0400148// Returns the next unused fence name, and allocates the fence
149GLuint ResourceManager::createFenceSync()
150{
151 GLuint handle = mFenceSyncHandleAllocator.allocate();
152
153 mFenceSyncMap[handle] = new FenceSync(mRenderer, handle);
154
155 return handle;
156}
157
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000158void ResourceManager::deleteBuffer(GLuint buffer)
159{
160 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
161
162 if (bufferObject != mBufferMap.end())
163 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000164 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000165 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000166 mBufferMap.erase(bufferObject);
167 }
168}
169
170void ResourceManager::deleteShader(GLuint shader)
171{
172 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
173
174 if (shaderObject != mShaderMap.end())
175 {
176 if (shaderObject->second->getRefCount() == 0)
177 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000178 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000179 delete shaderObject->second;
180 mShaderMap.erase(shaderObject);
181 }
182 else
183 {
184 shaderObject->second->flagForDeletion();
185 }
186 }
187}
188
189void ResourceManager::deleteProgram(GLuint program)
190{
191 ProgramMap::iterator programObject = mProgramMap.find(program);
192
193 if (programObject != mProgramMap.end())
194 {
195 if (programObject->second->getRefCount() == 0)
196 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000197 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000198 delete programObject->second;
199 mProgramMap.erase(programObject);
200 }
201 else
202 {
203 programObject->second->flagForDeletion();
204 }
205 }
206}
207
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000208void ResourceManager::deleteTexture(GLuint texture)
209{
210 TextureMap::iterator textureObject = mTextureMap.find(texture);
211
212 if (textureObject != mTextureMap.end())
213 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000214 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000215 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000216 mTextureMap.erase(textureObject);
217 }
218}
219
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000220void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
221{
222 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
223
224 if (renderbufferObject != mRenderbufferMap.end())
225 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000226 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000227 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000228 mRenderbufferMap.erase(renderbufferObject);
229 }
230}
231
Jamie Madilldc356042013-07-19 16:36:57 -0400232void ResourceManager::deleteSampler(GLuint sampler)
233{
234 auto samplerObject = mSamplerMap.find(sampler);
235
236 if (samplerObject != mSamplerMap.end())
237 {
Geoff Lang79931902014-02-03 14:29:42 -0500238 mSamplerHandleAllocator.release(samplerObject->first);
Jamie Madilldc356042013-07-19 16:36:57 -0400239 if (samplerObject->second) samplerObject->second->release();
240 mSamplerMap.erase(samplerObject);
241 }
242}
243
Jamie Madillcd055f82013-07-26 11:55:15 -0400244void ResourceManager::deleteFenceSync(GLuint fenceSync)
245{
246 auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
247
248 if (fenceObjectIt != mFenceSyncMap.end())
249 {
250 mFenceSyncHandleAllocator.release(fenceObjectIt->first);
251 if (fenceObjectIt->second) fenceObjectIt->second->release();
252 mFenceSyncMap.erase(fenceObjectIt);
253 }
254}
255
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000256Buffer *ResourceManager::getBuffer(unsigned int handle)
257{
258 BufferMap::iterator buffer = mBufferMap.find(handle);
259
260 if (buffer == mBufferMap.end())
261 {
262 return NULL;
263 }
264 else
265 {
266 return buffer->second;
267 }
268}
269
270Shader *ResourceManager::getShader(unsigned int handle)
271{
272 ShaderMap::iterator shader = mShaderMap.find(handle);
273
274 if (shader == mShaderMap.end())
275 {
276 return NULL;
277 }
278 else
279 {
280 return shader->second;
281 }
282}
283
284Texture *ResourceManager::getTexture(unsigned int handle)
285{
286 if (handle == 0) return NULL;
287
288 TextureMap::iterator texture = mTextureMap.find(handle);
289
290 if (texture == mTextureMap.end())
291 {
292 return NULL;
293 }
294 else
295 {
296 return texture->second;
297 }
298}
299
300Program *ResourceManager::getProgram(unsigned int handle)
301{
302 ProgramMap::iterator program = mProgramMap.find(handle);
303
304 if (program == mProgramMap.end())
305 {
306 return NULL;
307 }
308 else
309 {
310 return program->second;
311 }
312}
313
314Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
315{
316 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
317
318 if (renderbuffer == mRenderbufferMap.end())
319 {
320 return NULL;
321 }
322 else
323 {
324 return renderbuffer->second;
325 }
326}
327
Jamie Madilldc356042013-07-19 16:36:57 -0400328Sampler *ResourceManager::getSampler(unsigned int handle)
329{
330 auto sampler = mSamplerMap.find(handle);
331
332 if (sampler == mSamplerMap.end())
333 {
334 return NULL;
335 }
336 else
337 {
338 return sampler->second;
339 }
340}
341
Jamie Madillcd055f82013-07-26 11:55:15 -0400342FenceSync *ResourceManager::getFenceSync(unsigned int handle)
343{
344 auto fenceObjectIt = mFenceSyncMap.find(handle);
345
346 if (fenceObjectIt == mFenceSyncMap.end())
347 {
348 return NULL;
349 }
350 else
351 {
352 return fenceObjectIt->second;
353 }
354}
355
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000356void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
357{
358 mRenderbufferMap[handle] = buffer;
359}
360
361void ResourceManager::checkBufferAllocation(unsigned int buffer)
362{
363 if (buffer != 0 && !getBuffer(buffer))
364 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000365 Buffer *bufferObject = new Buffer(mRenderer, buffer);
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000366 mBufferMap[buffer] = bufferObject;
367 bufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000368 }
369}
370
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000371void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000372{
373 if (!getTexture(texture) && texture != 0)
374 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000375 Texture *textureObject;
376
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000377 if (type == TEXTURE_2D)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000378 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000379 textureObject = new Texture2D(mRenderer, texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000380 }
daniel@transgaming.com0e64dd62011-05-11 15:36:37 +0000381 else if (type == TEXTURE_CUBE)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000382 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000383 textureObject = new TextureCubeMap(mRenderer, texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000384 }
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000385 else if (type == TEXTURE_3D)
386 {
387 textureObject = new Texture3D(mRenderer, texture);
388 }
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000389 else if (type == TEXTURE_2D_ARRAY)
390 {
391 textureObject = new Texture2DArray(mRenderer, texture);
392 }
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000393 else
394 {
395 UNREACHABLE();
396 return;
397 }
398
399 mTextureMap[texture] = textureObject;
400 textureObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000401 }
402}
403
404void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
405{
406 if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
407 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000408 Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000409 mRenderbufferMap[renderbuffer] = renderbufferObject;
410 renderbufferObject->addRef();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000411 }
412}
413
Jamie Madilldc356042013-07-19 16:36:57 -0400414void ResourceManager::checkSamplerAllocation(GLuint sampler)
415{
416 if (sampler != 0 && !getSampler(sampler))
417 {
418 Sampler *samplerObject = new Sampler(sampler);
419 mSamplerMap[sampler] = samplerObject;
420 samplerObject->addRef();
421 }
422}
423
424bool ResourceManager::isSampler(GLuint sampler)
425{
426 return mSamplerMap.find(sampler) != mSamplerMap.end();
427}
428
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000429}