blob: a0af9c64455c4218384069bb8bb69d22081d2fe9 [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
Jamie Madill4e25a0d2016-03-08 13:53:03 -050085 mBufferMap[handle] = nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000086
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
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500119 mTextureMap[handle] = nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000120
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
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500129 mRenderbufferMap[handle] = nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000130
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
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500139 mSamplerMap[handle] = nullptr;
Jamie Madilldc356042013-07-19 16:36:57 -0400140
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{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500158 auto bufferObject = mBufferMap.find(buffer);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000159
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{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500170 auto shaderObject = mShaderMap.find(shader);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000171
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{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500189 auto programObject = mProgramMap.find(program);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000190
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{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500208 auto textureObject = mTextureMap.find(texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000209
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{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500220 auto renderbufferObject = mRenderbufferMap.find(renderbuffer);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000221
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{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500256 auto buffer = mBufferMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000257
258 if (buffer == mBufferMap.end())
259 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500260 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000261 }
262 else
263 {
264 return buffer->second;
265 }
266}
267
268Shader *ResourceManager::getShader(unsigned int handle)
269{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500270 auto shader = mShaderMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000271
272 if (shader == mShaderMap.end())
273 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500274 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000275 }
276 else
277 {
278 return shader->second;
279 }
280}
281
282Texture *ResourceManager::getTexture(unsigned int handle)
283{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500284 if (handle == 0)
285 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000286
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500287 auto texture = mTextureMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000288
289 if (texture == mTextureMap.end())
290 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500291 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000292 }
293 else
294 {
295 return texture->second;
296 }
297}
298
Jamie Madilld9e58302014-11-06 15:27:26 -0500299Program *ResourceManager::getProgram(unsigned int handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000300{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500301 auto program = mProgramMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000302
303 if (program == mProgramMap.end())
304 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500305 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000306 }
307 else
308 {
309 return program->second;
310 }
311}
312
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400313Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000314{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500315 auto renderbuffer = mRenderbufferMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000316
317 if (renderbuffer == mRenderbufferMap.end())
318 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500319 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000320 }
321 else
322 {
323 return renderbuffer->second;
324 }
325}
326
Jamie Madilldc356042013-07-19 16:36:57 -0400327Sampler *ResourceManager::getSampler(unsigned int handle)
328{
329 auto sampler = mSamplerMap.find(handle);
330
331 if (sampler == mSamplerMap.end())
332 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500333 return nullptr;
Jamie Madilldc356042013-07-19 16:36:57 -0400334 }
335 else
336 {
337 return sampler->second;
338 }
339}
340
Jamie Madillcd055f82013-07-26 11:55:15 -0400341FenceSync *ResourceManager::getFenceSync(unsigned int handle)
342{
343 auto fenceObjectIt = mFenceSyncMap.find(handle);
344
345 if (fenceObjectIt == mFenceSyncMap.end())
346 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500347 return nullptr;
Jamie Madillcd055f82013-07-26 11:55:15 -0400348 }
349 else
350 {
351 return fenceObjectIt->second;
352 }
353}
354
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400355void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000356{
357 mRenderbufferMap[handle] = buffer;
358}
359
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500360Buffer *ResourceManager::checkBufferAllocation(GLuint handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000361{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500362 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000363 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500364 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000365 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500366
367 auto bufferMapIt = mBufferMap.find(handle);
368 bool handleAllocated = (bufferMapIt != mBufferMap.end());
369
370 if (handleAllocated && bufferMapIt->second != nullptr)
371 {
372 return bufferMapIt->second;
373 }
374
375 Buffer *buffer = new Buffer(mFactory->createBuffer(), handle);
376 buffer->addRef();
377
378 if (handleAllocated)
379 {
380 bufferMapIt->second = buffer;
381 }
382 else
383 {
384 mBufferHandleAllocator.reserve(handle);
385 mBufferMap[handle] = buffer;
386 }
387
388 return buffer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000389}
390
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500391Texture *ResourceManager::checkTextureAllocation(GLuint handle, GLenum type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000392{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500393 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000394 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500395 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000396 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500397
398 auto textureMapIt = mTextureMap.find(handle);
399 bool handleAllocated = (textureMapIt != mTextureMap.end());
400
401 if (handleAllocated && textureMapIt->second != nullptr)
402 {
403 return textureMapIt->second;
404 }
405
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300406 Texture *texture = new Texture(mFactory, handle, type);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500407 texture->addRef();
408
409 if (handleAllocated)
410 {
411 textureMapIt->second = texture;
412 }
413 else
414 {
415 mTextureHandleAllocator.reserve(handle);
416 mTextureMap[handle] = texture;
417 }
418
419 return texture;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000420}
421
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500422Renderbuffer *ResourceManager::checkRenderbufferAllocation(GLuint handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000423{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500424 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000425 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500426 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000427 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500428
429 auto renderbufferMapIt = mRenderbufferMap.find(handle);
430 bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
431
432 if (handleAllocated && renderbufferMapIt->second != nullptr)
433 {
434 return renderbufferMapIt->second;
435 }
436
437 Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle);
438 renderbuffer->addRef();
439
440 if (handleAllocated)
441 {
442 renderbufferMapIt->second = renderbuffer;
443 }
444 else
445 {
446 mRenderbufferHandleAllocator.reserve(handle);
447 mRenderbufferMap[handle] = renderbuffer;
448 }
449
450 return renderbuffer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000451}
452
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500453Sampler *ResourceManager::checkSamplerAllocation(GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400454{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500455 // Samplers cannot be created via Bind
456 if (samplerHandle == 0)
Jamie Madilldc356042013-07-19 16:36:57 -0400457 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500458 return nullptr;
Jamie Madilldc356042013-07-19 16:36:57 -0400459 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500460
461 Sampler *sampler = getSampler(samplerHandle);
462
463 if (!sampler)
464 {
465 sampler = new Sampler(mFactory, samplerHandle);
466 mSamplerMap[samplerHandle] = sampler;
467 sampler->addRef();
468 }
469
470 return sampler;
Jamie Madilldc356042013-07-19 16:36:57 -0400471}
472
473bool ResourceManager::isSampler(GLuint sampler)
474{
475 return mSamplerMap.find(sampler) != mSamplerMap.end();
476}
477
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500478} // namespace gl