blob: 58c204acc4404ad3fd21cf91044230fdc44ca718 [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 Madill7aea7e02016-05-10 10:39:45 -040023ResourceManager::ResourceManager(rx::GLImplFactory *factory) : mFactory(factory), mRefCount(1)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000024{
25}
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 }
Jamie Madilldc356042013-07-19 16:36:57 -040053
54 while (!mSamplerMap.empty())
55 {
56 deleteSampler(mSamplerMap.begin()->first);
57 }
Jamie Madillcd055f82013-07-26 11:55:15 -040058
59 while (!mFenceSyncMap.empty())
60 {
61 deleteFenceSync(mFenceSyncMap.begin()->first);
62 }
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000063}
64
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000065void ResourceManager::addRef()
66{
67 mRefCount++;
68}
69
70void ResourceManager::release()
71{
72 if (--mRefCount == 0)
73 {
74 delete this;
75 }
76}
77
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000078// Returns an unused buffer name
79GLuint ResourceManager::createBuffer()
80{
benvanik@google.com1a233342011-04-28 19:44:39 +000081 GLuint handle = mBufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000082
Jamie Madill4e25a0d2016-03-08 13:53:03 -050083 mBufferMap[handle] = nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000084
85 return handle;
86}
87
88// Returns an unused shader/program name
Jamie Madill006cbc52015-09-23 16:47:54 -040089GLuint ResourceManager::createShader(const gl::Limitations &rendererLimitations, GLenum type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000090{
benvanik@google.com1a233342011-04-28 19:44:39 +000091 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000092
Brandon Jones71620962014-08-20 14:04:59 -070093 if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000094 {
Jamie Madill006cbc52015-09-23 16:47:54 -040095 mShaderMap[handle] = new Shader(this, mFactory, rendererLimitations, type, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000096 }
97 else UNREACHABLE();
98
99 return handle;
100}
101
102// Returns an unused program/shader name
103GLuint ResourceManager::createProgram()
104{
benvanik@google.com1a233342011-04-28 19:44:39 +0000105 GLuint handle = mProgramShaderHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000106
Jamie Madill5c6b7bf2015-08-17 12:53:35 -0400107 mProgramMap[handle] = new Program(mFactory, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000108
109 return handle;
110}
111
112// Returns an unused texture name
113GLuint ResourceManager::createTexture()
114{
benvanik@google.com1a233342011-04-28 19:44:39 +0000115 GLuint handle = mTextureHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000116
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500117 mTextureMap[handle] = nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000118
119 return handle;
120}
121
122// Returns an unused renderbuffer name
123GLuint ResourceManager::createRenderbuffer()
124{
benvanik@google.com1a233342011-04-28 19:44:39 +0000125 GLuint handle = mRenderbufferHandleAllocator.allocate();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000126
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500127 mRenderbufferMap[handle] = nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000128
129 return handle;
130}
131
Jamie Madilldc356042013-07-19 16:36:57 -0400132// Returns an unused sampler name
133GLuint ResourceManager::createSampler()
134{
135 GLuint handle = mSamplerHandleAllocator.allocate();
136
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500137 mSamplerMap[handle] = nullptr;
Jamie Madilldc356042013-07-19 16:36:57 -0400138
139 return handle;
140}
141
Jamie Madillcd055f82013-07-26 11:55:15 -0400142// Returns the next unused fence name, and allocates the fence
143GLuint ResourceManager::createFenceSync()
144{
145 GLuint handle = mFenceSyncHandleAllocator.allocate();
146
Jamie Madillae6495e2015-03-16 10:46:56 -0400147 FenceSync *fenceSync = new FenceSync(mFactory->createFenceSync(), handle);
Jamie Madillcfa33e62014-08-19 15:30:41 -0400148 fenceSync->addRef();
149 mFenceSyncMap[handle] = fenceSync;
Jamie Madillcd055f82013-07-26 11:55:15 -0400150
151 return handle;
152}
153
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000154void ResourceManager::deleteBuffer(GLuint buffer)
155{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500156 auto bufferObject = mBufferMap.find(buffer);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000157
158 if (bufferObject != mBufferMap.end())
159 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000160 mBufferHandleAllocator.release(bufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000161 if (bufferObject->second) bufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000162 mBufferMap.erase(bufferObject);
163 }
164}
165
166void ResourceManager::deleteShader(GLuint shader)
167{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500168 auto shaderObject = mShaderMap.find(shader);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000169
170 if (shaderObject != mShaderMap.end())
171 {
172 if (shaderObject->second->getRefCount() == 0)
173 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000174 mProgramShaderHandleAllocator.release(shaderObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000175 delete shaderObject->second;
176 mShaderMap.erase(shaderObject);
177 }
178 else
179 {
180 shaderObject->second->flagForDeletion();
181 }
182 }
183}
184
185void ResourceManager::deleteProgram(GLuint program)
186{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500187 auto programObject = mProgramMap.find(program);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000188
189 if (programObject != mProgramMap.end())
190 {
191 if (programObject->second->getRefCount() == 0)
192 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000193 mProgramShaderHandleAllocator.release(programObject->first);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000194 delete programObject->second;
195 mProgramMap.erase(programObject);
196 }
197 else
198 {
199 programObject->second->flagForDeletion();
200 }
201 }
202}
203
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000204void ResourceManager::deleteTexture(GLuint texture)
205{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500206 auto textureObject = mTextureMap.find(texture);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000207
208 if (textureObject != mTextureMap.end())
209 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000210 mTextureHandleAllocator.release(textureObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000211 if (textureObject->second) textureObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000212 mTextureMap.erase(textureObject);
213 }
214}
215
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000216void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
217{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500218 auto renderbufferObject = mRenderbufferMap.find(renderbuffer);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000219
220 if (renderbufferObject != mRenderbufferMap.end())
221 {
benvanik@google.com1a233342011-04-28 19:44:39 +0000222 mRenderbufferHandleAllocator.release(renderbufferObject->first);
apatrick@chromium.orgff8bdfb2010-09-15 17:27:49 +0000223 if (renderbufferObject->second) renderbufferObject->second->release();
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000224 mRenderbufferMap.erase(renderbufferObject);
225 }
226}
227
Jamie Madilldc356042013-07-19 16:36:57 -0400228void ResourceManager::deleteSampler(GLuint sampler)
229{
230 auto samplerObject = mSamplerMap.find(sampler);
231
232 if (samplerObject != mSamplerMap.end())
233 {
Geoff Lang79931902014-02-03 14:29:42 -0500234 mSamplerHandleAllocator.release(samplerObject->first);
Jamie Madilldc356042013-07-19 16:36:57 -0400235 if (samplerObject->second) samplerObject->second->release();
236 mSamplerMap.erase(samplerObject);
237 }
238}
239
Jamie Madillcd055f82013-07-26 11:55:15 -0400240void ResourceManager::deleteFenceSync(GLuint fenceSync)
241{
242 auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
243
244 if (fenceObjectIt != mFenceSyncMap.end())
245 {
246 mFenceSyncHandleAllocator.release(fenceObjectIt->first);
247 if (fenceObjectIt->second) fenceObjectIt->second->release();
248 mFenceSyncMap.erase(fenceObjectIt);
249 }
250}
251
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000252Buffer *ResourceManager::getBuffer(unsigned int handle)
253{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500254 auto buffer = mBufferMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000255
256 if (buffer == mBufferMap.end())
257 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500258 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000259 }
260 else
261 {
262 return buffer->second;
263 }
264}
265
266Shader *ResourceManager::getShader(unsigned int handle)
267{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500268 auto shader = mShaderMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000269
270 if (shader == mShaderMap.end())
271 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500272 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000273 }
274 else
275 {
276 return shader->second;
277 }
278}
279
280Texture *ResourceManager::getTexture(unsigned int handle)
281{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500282 if (handle == 0)
283 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000284
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500285 auto texture = mTextureMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000286
287 if (texture == mTextureMap.end())
288 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500289 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000290 }
291 else
292 {
293 return texture->second;
294 }
295}
296
Jamie Madilld9e58302014-11-06 15:27:26 -0500297Program *ResourceManager::getProgram(unsigned int handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000298{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500299 auto program = mProgramMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000300
301 if (program == mProgramMap.end())
302 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500303 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000304 }
305 else
306 {
307 return program->second;
308 }
309}
310
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400311Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000312{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500313 auto renderbuffer = mRenderbufferMap.find(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000314
315 if (renderbuffer == mRenderbufferMap.end())
316 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500317 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000318 }
319 else
320 {
321 return renderbuffer->second;
322 }
323}
324
Jamie Madilldc356042013-07-19 16:36:57 -0400325Sampler *ResourceManager::getSampler(unsigned int handle)
326{
327 auto sampler = mSamplerMap.find(handle);
328
329 if (sampler == mSamplerMap.end())
330 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500331 return nullptr;
Jamie Madilldc356042013-07-19 16:36:57 -0400332 }
333 else
334 {
335 return sampler->second;
336 }
337}
338
Jamie Madillcd055f82013-07-26 11:55:15 -0400339FenceSync *ResourceManager::getFenceSync(unsigned int handle)
340{
341 auto fenceObjectIt = mFenceSyncMap.find(handle);
342
343 if (fenceObjectIt == mFenceSyncMap.end())
344 {
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500345 return nullptr;
Jamie Madillcd055f82013-07-26 11:55:15 -0400346 }
347 else
348 {
349 return fenceObjectIt->second;
350 }
351}
352
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400353void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000354{
355 mRenderbufferMap[handle] = buffer;
356}
357
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500358Buffer *ResourceManager::checkBufferAllocation(GLuint handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000359{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500360 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000361 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500362 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000363 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500364
365 auto bufferMapIt = mBufferMap.find(handle);
366 bool handleAllocated = (bufferMapIt != mBufferMap.end());
367
368 if (handleAllocated && bufferMapIt->second != nullptr)
369 {
370 return bufferMapIt->second;
371 }
372
373 Buffer *buffer = new Buffer(mFactory->createBuffer(), handle);
374 buffer->addRef();
375
376 if (handleAllocated)
377 {
378 bufferMapIt->second = buffer;
379 }
380 else
381 {
382 mBufferHandleAllocator.reserve(handle);
383 mBufferMap[handle] = buffer;
384 }
385
386 return buffer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000387}
388
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500389Texture *ResourceManager::checkTextureAllocation(GLuint handle, GLenum type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000390{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500391 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000392 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500393 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000394 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500395
396 auto textureMapIt = mTextureMap.find(handle);
397 bool handleAllocated = (textureMapIt != mTextureMap.end());
398
399 if (handleAllocated && textureMapIt->second != nullptr)
400 {
401 return textureMapIt->second;
402 }
403
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300404 Texture *texture = new Texture(mFactory, handle, type);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500405 texture->addRef();
406
407 if (handleAllocated)
408 {
409 textureMapIt->second = texture;
410 }
411 else
412 {
413 mTextureHandleAllocator.reserve(handle);
414 mTextureMap[handle] = texture;
415 }
416
417 return texture;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000418}
419
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500420Renderbuffer *ResourceManager::checkRenderbufferAllocation(GLuint handle)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000421{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500422 if (handle == 0)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000423 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500424 return nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000425 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500426
427 auto renderbufferMapIt = mRenderbufferMap.find(handle);
428 bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
429
430 if (handleAllocated && renderbufferMapIt->second != nullptr)
431 {
432 return renderbufferMapIt->second;
433 }
434
435 Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle);
436 renderbuffer->addRef();
437
438 if (handleAllocated)
439 {
440 renderbufferMapIt->second = renderbuffer;
441 }
442 else
443 {
444 mRenderbufferHandleAllocator.reserve(handle);
445 mRenderbufferMap[handle] = renderbuffer;
446 }
447
448 return renderbuffer;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000449}
450
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500451Sampler *ResourceManager::checkSamplerAllocation(GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400452{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500453 // Samplers cannot be created via Bind
454 if (samplerHandle == 0)
Jamie Madilldc356042013-07-19 16:36:57 -0400455 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500456 return nullptr;
Jamie Madilldc356042013-07-19 16:36:57 -0400457 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500458
459 Sampler *sampler = getSampler(samplerHandle);
460
461 if (!sampler)
462 {
463 sampler = new Sampler(mFactory, samplerHandle);
464 mSamplerMap[samplerHandle] = sampler;
465 sampler->addRef();
466 }
467
468 return sampler;
Jamie Madilldc356042013-07-19 16:36:57 -0400469}
470
471bool ResourceManager::isSampler(GLuint sampler)
472{
473 return mSamplerMap.find(sampler) != mSamplerMap.end();
474}
475
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500476} // namespace gl