blob: db2c55f304fe27fe3d1a12e6691c056b0feaa78b [file] [log] [blame]
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00001//
Jamie Madilldc356042013-07-19 16:36:57 -04002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00003// 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
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/ResourceManager.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000011
Geoff Lang2b5420c2014-11-19 14:20:15 -050012#include "libANGLE/Buffer.h"
13#include "libANGLE/Program.h"
14#include "libANGLE/Renderbuffer.h"
15#include "libANGLE/Shader.h"
16#include "libANGLE/Texture.h"
17#include "libANGLE/Sampler.h"
18#include "libANGLE/Fence.h"
19#include "libANGLE/renderer/Renderer.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000020
21namespace gl
22{
Jamie Madillae6495e2015-03-16 10:46:56 -040023ResourceManager::ResourceManager(rx::ImplFactory *factory)
24 : mFactory(factory),
Jamie Madill93e13fb2014-11-06 15:27:25 -050025 mRefCount(1)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000026{
27}
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
Jamie Madill006cbc52015-09-23 16:47:54 -040091GLuint ResourceManager::createShader(const gl::Limitations &rendererLimitations, GLenum type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000092{
benvanik@google.com1a233342011-04-28 19:44:39 +000093 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000094
Brandon Jones71620962014-08-20 14:04:59 -070095 if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000096 {
Jamie Madill006cbc52015-09-23 16:47:54 -040097 mShaderMap[handle] = new Shader(this, mFactory, rendererLimitations, type, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000098 }
99 else UNREACHABLE();
100
101 return handle;
102}
103
104// Returns an unused program/shader name
105GLuint ResourceManager::createProgram()
106{
benvanik@google.com1a233342011-04-28 19:44:39 +0000107 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000108
Jamie Madill5c6b7bf2015-08-17 12:53:35 -0400109 mProgramMap[handle] = new Program(mFactory, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000110
111 return handle;
112}
113
114// Returns an unused texture name
115GLuint ResourceManager::createTexture()
116{
benvanik@google.com1a233342011-04-28 19:44:39 +0000117 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000118
119 mTextureMap[handle] = NULL;
120
121 return handle;
122}
123
124// Returns an unused renderbuffer name
125GLuint ResourceManager::createRenderbuffer()
126{
benvanik@google.com1a233342011-04-28 19:44:39 +0000127 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000128
129 mRenderbufferMap[handle] = NULL;
130
131 return handle;
132}
133
Jamie Madilldc356042013-07-19 16:36:57 -0400134// Returns an unused sampler name
135GLuint ResourceManager::createSampler()
136{
137 GLuint handle = mSamplerHandleAllocator.allocate();
138
139 mSamplerMap[handle] = NULL;
140
141 return handle;
142}
143
Jamie Madillcd055f82013-07-26 11:55:15 -0400144// Returns the next unused fence name, and allocates the fence
145GLuint ResourceManager::createFenceSync()
146{
147 GLuint handle = mFenceSyncHandleAllocator.allocate();
148
Jamie Madillae6495e2015-03-16 10:46:56 -0400149 FenceSync *fenceSync = new FenceSync(mFactory->createFenceSync(), handle);
Jamie Madillcfa33e62014-08-19 15:30:41 -0400150 fenceSync->addRef();
151 mFenceSyncMap[handle] = fenceSync;
Jamie Madillcd055f82013-07-26 11:55:15 -0400152
153 return handle;
154}
155
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000156void ResourceManager::deleteBuffer(GLuint buffer)
157{
158 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
159
160 if (bufferObject != mBufferMap.end())
161 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000162 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000163 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000164 mBufferMap.erase(bufferObject);
165 }
166}
167
168void ResourceManager::deleteShader(GLuint shader)
169{
170 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
171
172 if (shaderObject != mShaderMap.end())
173 {
174 if (shaderObject->second->getRefCount() == 0)
175 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000176 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000177 delete shaderObject->second;
178 mShaderMap.erase(shaderObject);
179 }
180 else
181 {
182 shaderObject->second->flagForDeletion();
183 }
184 }
185}
186
187void ResourceManager::deleteProgram(GLuint program)
188{
189 ProgramMap::iterator programObject = mProgramMap.find(program);
190
191 if (programObject != mProgramMap.end())
192 {
193 if (programObject->second->getRefCount() == 0)
194 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000195 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000196 delete programObject->second;
197 mProgramMap.erase(programObject);
198 }
199 else
200 {
201 programObject->second->flagForDeletion();
202 }
203 }
204}
205
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000206void ResourceManager::deleteTexture(GLuint texture)
207{
208 TextureMap::iterator textureObject = mTextureMap.find(texture);
209
210 if (textureObject != mTextureMap.end())
211 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000212 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000213 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000214 mTextureMap.erase(textureObject);
215 }
216}
217
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000218void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
219{
220 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
221
222 if (renderbufferObject != mRenderbufferMap.end())
223 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000224 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000225 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000226 mRenderbufferMap.erase(renderbufferObject);
227 }
228}
229
Jamie Madilldc356042013-07-19 16:36:57 -0400230void ResourceManager::deleteSampler(GLuint sampler)
231{
232 auto samplerObject = mSamplerMap.find(sampler);
233
234 if (samplerObject != mSamplerMap.end())
235 {
Geoff Lang79931902014-02-03 14:29:42 -0500236 mSamplerHandleAllocator.release(samplerObject->first);
Jamie Madilldc356042013-07-19 16:36:57 -0400237 if (samplerObject->second) samplerObject->second->release();
238 mSamplerMap.erase(samplerObject);
239 }
240}
241
Jamie Madillcd055f82013-07-26 11:55:15 -0400242void ResourceManager::deleteFenceSync(GLuint fenceSync)
243{
244 auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
245
246 if (fenceObjectIt != mFenceSyncMap.end())
247 {
248 mFenceSyncHandleAllocator.release(fenceObjectIt->first);
249 if (fenceObjectIt->second) fenceObjectIt->second->release();
250 mFenceSyncMap.erase(fenceObjectIt);
251 }
252}
253
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000254Buffer *ResourceManager::getBuffer(unsigned int handle)
255{
256 BufferMap::iterator buffer = mBufferMap.find(handle);
257
258 if (buffer == mBufferMap.end())
259 {
260 return NULL;
261 }
262 else
263 {
264 return buffer->second;
265 }
266}
267
268Shader *ResourceManager::getShader(unsigned int handle)
269{
270 ShaderMap::iterator shader = mShaderMap.find(handle);
271
272 if (shader == mShaderMap.end())
273 {
274 return NULL;
275 }
276 else
277 {
278 return shader->second;
279 }
280}
281
282Texture *ResourceManager::getTexture(unsigned int handle)
283{
284 if (handle == 0) return NULL;
285
286 TextureMap::iterator texture = mTextureMap.find(handle);
287
288 if (texture == mTextureMap.end())
289 {
290 return NULL;
291 }
292 else
293 {
294 return texture->second;
295 }
296}
297
Jamie Madilld9e58302014-11-06 15:27:26 -0500298Program *ResourceManager::getProgram(unsigned int handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000299{
Jamie Madilld9e58302014-11-06 15:27:26 -0500300 ProgramMap::const_iterator program = mProgramMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000301
302 if (program == mProgramMap.end())
303 {
304 return NULL;
305 }
306 else
307 {
308 return program->second;
309 }
310}
311
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400312Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000313{
314 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
315
316 if (renderbuffer == mRenderbufferMap.end())
317 {
318 return NULL;
319 }
320 else
321 {
322 return renderbuffer->second;
323 }
324}
325
Jamie Madilldc356042013-07-19 16:36:57 -0400326Sampler *ResourceManager::getSampler(unsigned int handle)
327{
328 auto sampler = mSamplerMap.find(handle);
329
330 if (sampler == mSamplerMap.end())
331 {
332 return NULL;
333 }
334 else
335 {
336 return sampler->second;
337 }
338}
339
Jamie Madillcd055f82013-07-26 11:55:15 -0400340FenceSync *ResourceManager::getFenceSync(unsigned int handle)
341{
342 auto fenceObjectIt = mFenceSyncMap.find(handle);
343
344 if (fenceObjectIt == mFenceSyncMap.end())
345 {
346 return NULL;
347 }
348 else
349 {
350 return fenceObjectIt->second;
351 }
352}
353
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400354void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000355{
356 mRenderbufferMap[handle] = buffer;
357}
358
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500359Buffer *ResourceManager::checkBufferAllocation(GLuint handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000360{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500361 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000362 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500363 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000364 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500365
366 auto bufferMapIt = mBufferMap.find(handle);
367 bool handleAllocated = (bufferMapIt != mBufferMap.end());
368
369 if (handleAllocated && bufferMapIt->second != nullptr)
370 {
371 return bufferMapIt->second;
372 }
373
374 Buffer *buffer = new Buffer(mFactory->createBuffer(), handle);
375 buffer->addRef();
376
377 if (handleAllocated)
378 {
379 bufferMapIt->second = buffer;
380 }
381 else
382 {
383 mBufferHandleAllocator.reserve(handle);
384 mBufferMap[handle] = buffer;
385 }
386
387 return buffer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000388}
389
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500390Texture *ResourceManager::checkTextureAllocation(GLuint handle, GLenum type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000391{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500392 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000393 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500394 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000395 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500396
397 auto textureMapIt = mTextureMap.find(handle);
398 bool handleAllocated = (textureMapIt != mTextureMap.end());
399
400 if (handleAllocated && textureMapIt->second != nullptr)
401 {
402 return textureMapIt->second;
403 }
404
405 Texture *texture = new Texture(mFactory->createTexture(type), handle, type);
406 texture->addRef();
407
408 if (handleAllocated)
409 {
410 textureMapIt->second = texture;
411 }
412 else
413 {
414 mTextureHandleAllocator.reserve(handle);
415 mTextureMap[handle] = texture;
416 }
417
418 return texture;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000419}
420
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500421Renderbuffer *ResourceManager::checkRenderbufferAllocation(GLuint handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000422{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500423 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000424 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500425 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000426 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500427
428 auto renderbufferMapIt = mRenderbufferMap.find(handle);
429 bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
430
431 if (handleAllocated && renderbufferMapIt->second != nullptr)
432 {
433 return renderbufferMapIt->second;
434 }
435
436 Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle);
437 renderbuffer->addRef();
438
439 if (handleAllocated)
440 {
441 renderbufferMapIt->second = renderbuffer;
442 }
443 else
444 {
445 mRenderbufferHandleAllocator.reserve(handle);
446 mRenderbufferMap[handle] = renderbuffer;
447 }
448
449 return renderbuffer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000450}
451
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500452Sampler *ResourceManager::checkSamplerAllocation(GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400453{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500454 // Samplers cannot be created via Bind
455 if (samplerHandle == 0)
Jamie Madilldc356042013-07-19 16:36:57 -0400456 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500457 return nullptr;
Jamie Madilldc356042013-07-19 16:36:57 -0400458 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500459
460 Sampler *sampler = getSampler(samplerHandle);
461
462 if (!sampler)
463 {
464 sampler = new Sampler(mFactory, samplerHandle);
465 mSamplerMap[samplerHandle] = sampler;
466 sampler->addRef();
467 }
468
469 return sampler;
Jamie Madilldc356042013-07-19 16:36:57 -0400470}
471
472bool ResourceManager::isSampler(GLuint sampler)
473{
474 return mSamplerMap.find(sampler) != mSamplerMap.end();
475}
476
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500477} // namespace gl