blob: f51bed218c36206d903676b9e2a90afce96bd117 [file] [log] [blame]
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00001//
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002// Copyright (c) 2002-2016 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
Geoff Lang4ddf5af2016-12-01 14:30:44 -05007// ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and
8// lifetime of GL objects.
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00009
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"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040013#include "libANGLE/Fence.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050015#include "libANGLE/Program.h"
16#include "libANGLE/Renderbuffer.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040017#include "libANGLE/Sampler.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050018#include "libANGLE/Shader.h"
19#include "libANGLE/Texture.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040020#include "libANGLE/renderer/GLImplFactory.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000021
22namespace gl
23{
Geoff Lang4ddf5af2016-12-01 14:30:44 -050024
25namespace
26{
27
28template <typename ResourceType>
29GLuint AllocateEmptyObject(HandleAllocator *handleAllocator, ResourceMap<ResourceType> *objectMap)
30{
31 GLuint handle = handleAllocator->allocate();
32 (*objectMap)[handle] = nullptr;
33 return handle;
34}
35
Geoff Lang4ddf5af2016-12-01 14:30:44 -050036template <typename ResourceType>
37ResourceType *GetObject(const ResourceMap<ResourceType> &objectMap, GLuint handle)
38{
39 auto iter = objectMap.find(handle);
40 return iter != objectMap.end() ? iter->second : nullptr;
41}
42
43} // anonymous namespace
44
45template <typename HandleAllocatorType>
46ResourceManagerBase<HandleAllocatorType>::ResourceManagerBase() : mRefCount(1)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000047{
48}
49
Geoff Lang4ddf5af2016-12-01 14:30:44 -050050template <typename HandleAllocatorType>
51void ResourceManagerBase<HandleAllocatorType>::addRef()
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000052{
53 mRefCount++;
54}
55
Geoff Lang4ddf5af2016-12-01 14:30:44 -050056template <typename HandleAllocatorType>
Jamie Madill6c1f6712017-02-14 19:08:04 -050057void ResourceManagerBase<HandleAllocatorType>::release(const Context *context)
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000058{
59 if (--mRefCount == 0)
60 {
Jamie Madill6c1f6712017-02-14 19:08:04 -050061 reset(context);
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000062 delete this;
63 }
64}
65
Jamie Madill5f45e7c2017-02-10 15:23:28 -080066template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
67TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::~TypedResourceManager()
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000068{
Jamie Madill6c1f6712017-02-14 19:08:04 -050069 ASSERT(mObjectMap.empty());
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000070}
71
Jamie Madill5f45e7c2017-02-10 15:23:28 -080072template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
Jamie Madill6c1f6712017-02-14 19:08:04 -050073void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::reset(const Context *context)
74{
75 while (!mObjectMap.empty())
76 {
77 deleteObject(context, mObjectMap.begin()->first);
78 }
79 mObjectMap.clear();
80}
81
82template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
83void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObject(
84 const Context *context,
85 GLuint handle)
Geoff Lang4ddf5af2016-12-01 14:30:44 -050086{
Jamie Madill5f45e7c2017-02-10 15:23:28 -080087 auto objectIter = mObjectMap.find(handle);
88 if (objectIter == mObjectMap.end())
89 {
90 return;
91 }
92
93 if (objectIter->second != nullptr)
94 {
Jamie Madill6c1f6712017-02-14 19:08:04 -050095 objectIter->second->destroy(context);
Jamie Madill5f45e7c2017-02-10 15:23:28 -080096 ImplT::DeleteObject(objectIter->second);
97 }
98
99 // Requires an explicit this-> because of C++ template rules.
100 this->mHandleAllocator.release(objectIter->first);
101 mObjectMap.erase(objectIter);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500102}
103
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800104template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
105template <typename... ArgTypes>
106ResourceType *TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::allocateObject(
107 typename ResourceMap<ResourceType>::iterator &objectMapIter,
108 rx::GLImplFactory *factory,
109 GLuint handle,
110 ArgTypes... args)
111{
112 ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...);
113
114 if (objectMapIter != mObjectMap.end())
115 {
116 objectMapIter->second = object;
117 }
118 else
119 {
120 this->mHandleAllocator.reserve(handle);
121 mObjectMap[handle] = object;
122 }
123
124 return object;
125}
126
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500127template class ResourceManagerBase<HandleAllocator>;
128template class ResourceManagerBase<HandleRangeAllocator>;
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800129template class TypedResourceManager<Buffer, HandleAllocator, BufferManager>;
130template Buffer *TypedResourceManager<Buffer, HandleAllocator, BufferManager>::allocateObject(
131 ResourceMap<Buffer>::iterator &,
132 rx::GLImplFactory *,
133 GLuint);
134template class TypedResourceManager<Texture, HandleAllocator, TextureManager>;
135template Texture *TypedResourceManager<Texture, HandleAllocator, TextureManager>::allocateObject(
136 ResourceMap<Texture>::iterator &,
137 rx::GLImplFactory *,
138 GLuint,
139 GLenum);
140template class TypedResourceManager<Renderbuffer, HandleAllocator, RenderbufferManager>;
141template Renderbuffer *
142TypedResourceManager<Renderbuffer, HandleAllocator, RenderbufferManager>::allocateObject(
143 ResourceMap<Renderbuffer>::iterator &,
144 rx::GLImplFactory *,
145 GLuint);
146template class TypedResourceManager<Sampler, HandleAllocator, SamplerManager>;
147template Sampler *TypedResourceManager<Sampler, HandleAllocator, SamplerManager>::allocateObject(
148 ResourceMap<Sampler>::iterator &,
149 rx::GLImplFactory *,
150 GLuint);
151template class TypedResourceManager<FenceSync, HandleAllocator, FenceSyncManager>;
152template class TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager>;
153template Framebuffer *
154TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager>::allocateObject(
155 ResourceMap<Framebuffer>::iterator &,
156 rx::GLImplFactory *,
157 GLuint,
158 const Caps &);
159
160// BufferManager Implementation.
161
162// static
163Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle)
164{
165 Buffer *buffer = new Buffer(factory, handle);
166 buffer->addRef();
167 return buffer;
168}
169
170// static
171void BufferManager::DeleteObject(Buffer *buffer)
172{
173 buffer->release();
174}
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500175
176GLuint BufferManager::createBuffer()
177{
178 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
179}
180
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500181Buffer *BufferManager::getBuffer(GLuint handle) const
182{
183 return GetObject(mObjectMap, handle);
184}
185
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500186bool BufferManager::isBufferGenerated(GLuint buffer) const
187{
188 return buffer == 0 || mObjectMap.find(buffer) != mObjectMap.end();
189}
190
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800191// ShaderProgramManager Implementation.
192
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500193ShaderProgramManager::~ShaderProgramManager()
194{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500195 ASSERT(mPrograms.empty());
196 ASSERT(mShaders.empty());
197}
198
199void ShaderProgramManager::reset(const Context *context)
200{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500201 while (!mPrograms.empty())
202 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500203 deleteProgram(context, mPrograms.begin()->first);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500204 }
Jamie Madill6c1f6712017-02-14 19:08:04 -0500205 mPrograms.clear();
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500206 while (!mShaders.empty())
207 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500208 deleteShader(context, mShaders.begin()->first);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500209 }
Jamie Madill6c1f6712017-02-14 19:08:04 -0500210 mShaders.clear();
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500211}
212
213GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
214 const gl::Limitations &rendererLimitations,
215 GLenum type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000216{
Martin Radev4c4c8e72016-08-04 12:25:34 +0300217 ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500218 GLuint handle = mHandleAllocator.allocate();
219 mShaders[handle] = new Shader(this, factory, rendererLimitations, type, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000220 return handle;
221}
222
Jamie Madill6c1f6712017-02-14 19:08:04 -0500223void ShaderProgramManager::deleteShader(const Context *context, GLuint shader)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000224{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500225 deleteObject(context, &mShaders, shader);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000226}
227
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500228Shader *ShaderProgramManager::getShader(GLuint handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000229{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500230 return GetObject(mShaders, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000231}
232
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500233GLuint ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000234{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500235 GLuint handle = mHandleAllocator.allocate();
236 mPrograms[handle] = new Program(factory, this, handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000237 return handle;
238}
239
Jamie Madill6c1f6712017-02-14 19:08:04 -0500240void ShaderProgramManager::deleteProgram(const gl::Context *context, GLuint program)
Jamie Madilldc356042013-07-19 16:36:57 -0400241{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500242 deleteObject(context, &mPrograms, program);
Jamie Madilldc356042013-07-19 16:36:57 -0400243}
244
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500245Program *ShaderProgramManager::getProgram(GLuint handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400246{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500247 return GetObject(mPrograms, handle);
Jamie Madillcd055f82013-07-26 11:55:15 -0400248}
249
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500250template <typename ObjectType>
Jamie Madill6c1f6712017-02-14 19:08:04 -0500251void ShaderProgramManager::deleteObject(const Context *context,
252 ResourceMap<ObjectType> *objectMap,
253 GLuint id)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500254{
255 auto iter = objectMap->find(id);
256 if (iter == objectMap->end())
257 {
258 return;
259 }
260
261 auto object = iter->second;
262 if (object->getRefCount() == 0)
263 {
264 mHandleAllocator.release(id);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500265 object->destroy(context);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500266 SafeDelete(object);
267 objectMap->erase(iter);
268 }
269 else
270 {
271 object->flagForDeletion();
272 }
273}
274
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800275// TextureManager Implementation.
276
277// static
278Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target)
279{
280 Texture *texture = new Texture(factory, handle, target);
281 texture->addRef();
282 return texture;
283}
284
285// static
286void TextureManager::DeleteObject(Texture *texture)
287{
288 texture->release();
289}
290
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500291GLuint TextureManager::createTexture()
292{
293 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
294}
295
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500296Texture *TextureManager::getTexture(GLuint handle) const
297{
298 ASSERT(GetObject(mObjectMap, 0) == nullptr);
299 return GetObject(mObjectMap, handle);
300}
301
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500302bool TextureManager::isTextureGenerated(GLuint texture) const
303{
304 return texture == 0 || mObjectMap.find(texture) != mObjectMap.end();
305}
306
Geoff Lang9aded172017-04-05 11:07:56 -0400307void TextureManager::invalidateTextureComplenessCache()
308{
309 for (auto &texture : mObjectMap)
310 {
311 if (texture.second)
312 {
313 texture.second->invalidateCompletenessCache();
314 }
315 }
316}
317
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800318// RenderbufferManager Implementation.
319
320// static
321Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle)
322{
323 Renderbuffer *renderbuffer = new Renderbuffer(factory->createRenderbuffer(), handle);
324 renderbuffer->addRef();
325 return renderbuffer;
326}
327
328// static
329void RenderbufferManager::DeleteObject(Renderbuffer *renderbuffer)
330{
331 renderbuffer->release();
332}
333
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500334GLuint RenderbufferManager::createRenderbuffer()
335{
336 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
337}
338
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500339Renderbuffer *RenderbufferManager::getRenderbuffer(GLuint handle)
340{
341 return GetObject(mObjectMap, handle);
342}
343
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500344bool RenderbufferManager::isRenderbufferGenerated(GLuint renderbuffer) const
345{
346 return renderbuffer == 0 || mObjectMap.find(renderbuffer) != mObjectMap.end();
347}
348
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800349// SamplerManager Implementation.
350
351// static
352Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle)
353{
354 Sampler *sampler = new Sampler(factory, handle);
355 sampler->addRef();
356 return sampler;
357}
358
359// static
360void SamplerManager::DeleteObject(Sampler *sampler)
361{
362 sampler->release();
363}
364
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500365GLuint SamplerManager::createSampler()
366{
367 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
368}
369
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500370Sampler *SamplerManager::getSampler(GLuint handle)
371{
372 return GetObject(mObjectMap, handle);
373}
374
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500375bool SamplerManager::isSampler(GLuint sampler)
376{
377 return mObjectMap.find(sampler) != mObjectMap.end();
378}
379
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800380// FenceSyncManager Implementation.
381
382// static
383void FenceSyncManager::DeleteObject(FenceSync *fenceSync)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500384{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800385 fenceSync->release();
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500386}
387
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800388GLuint FenceSyncManager::createFenceSync(rx::GLImplFactory *factory)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500389{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800390 GLuint handle = mHandleAllocator.allocate();
391 FenceSync *fenceSync = new FenceSync(factory->createFenceSync(), handle);
392 fenceSync->addRef();
393 mObjectMap[handle] = fenceSync;
394 return handle;
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500395}
396
397FenceSync *FenceSyncManager::getFenceSync(GLuint handle)
398{
399 return GetObject(mObjectMap, handle);
400}
401
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800402// PathManager Implementation.
403
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500404ErrorOrResult<GLuint> PathManager::createPaths(rx::GLImplFactory *factory, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +0300405{
406 // Allocate client side handles.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500407 const GLuint client = mHandleAllocator.allocateRange(static_cast<GLuint>(range));
Sami Väisänene45e53b2016-05-25 10:36:04 +0300408 if (client == HandleRangeAllocator::kInvalidHandle)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500409 return Error(GL_OUT_OF_MEMORY, "Failed to allocate path handle range.");
Sami Väisänene45e53b2016-05-25 10:36:04 +0300410
411 const auto &paths = factory->createPaths(range);
412 if (paths.empty())
413 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500414 mHandleAllocator.releaseRange(client, range);
415 return Error(GL_OUT_OF_MEMORY, "Failed to allocate path objects.");
Sami Väisänene45e53b2016-05-25 10:36:04 +0300416 }
417
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500418 auto hint = mPaths.begin();
Sami Väisänene45e53b2016-05-25 10:36:04 +0300419
420 for (GLsizei i = 0; i < range; ++i)
421 {
422 const auto impl = paths[static_cast<unsigned>(i)];
423 const auto id = client + i;
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500424 hint = mPaths.insert(hint, std::make_pair(id, new Path(impl)));
Sami Väisänene45e53b2016-05-25 10:36:04 +0300425 }
426 return client;
427}
428
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500429void PathManager::deletePaths(GLuint first, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +0300430{
431 for (GLsizei i = 0; i < range; ++i)
432 {
433 const auto id = first + i;
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500434 const auto it = mPaths.find(id);
435 if (it == mPaths.end())
Sami Väisänene45e53b2016-05-25 10:36:04 +0300436 continue;
437 Path *p = it->second;
438 delete p;
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500439 mPaths.erase(it);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300440 }
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500441 mHandleAllocator.releaseRange(first, static_cast<GLuint>(range));
Sami Väisänene45e53b2016-05-25 10:36:04 +0300442}
443
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500444Path *PathManager::getPath(GLuint handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000445{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500446 auto iter = mPaths.find(handle);
447 return iter != mPaths.end() ? iter->second : nullptr;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000448}
449
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500450bool PathManager::hasPath(GLuint handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000451{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500452 return mHandleAllocator.isUsed(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000453}
454
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500455PathManager::~PathManager()
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000456{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500457 ASSERT(mPaths.empty());
458}
459
460void PathManager::reset(const Context *context)
461{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500462 for (auto path : mPaths)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000463 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500464 SafeDelete(path.second);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000465 }
Jamie Madill6c1f6712017-02-14 19:08:04 -0500466 mPaths.clear();
Geoff Langf41a7152016-09-19 15:11:17 -0400467}
468
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800469// FramebufferManager Implementation.
470
471// static
472Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
473 GLuint handle,
474 const Caps &caps)
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500475{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800476 return new Framebuffer(caps, factory, handle);
477}
478
479// static
480void FramebufferManager::DeleteObject(Framebuffer *framebuffer)
481{
482 // Default framebuffer are owned by their respective Surface
483 if (framebuffer->id() != 0)
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500484 {
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800485 delete framebuffer;
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500486 }
487}
488
489GLuint FramebufferManager::createFramebuffer()
490{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800491 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500492}
493
494Framebuffer *FramebufferManager::getFramebuffer(GLuint handle) const
495{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800496 return GetObject(mObjectMap, handle);
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500497}
498
499void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer)
500{
501 ASSERT(framebuffer == nullptr || framebuffer->id() == 0);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800502 mObjectMap[0] = framebuffer;
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500503}
504
505bool FramebufferManager::isFramebufferGenerated(GLuint framebuffer)
506{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800507 ASSERT(mObjectMap.find(0) != mObjectMap.end());
508 return mObjectMap.find(framebuffer) != mObjectMap.end();
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500509}
510
Geoff Lang9aded172017-04-05 11:07:56 -0400511void FramebufferManager::invalidateFramebufferComplenessCache()
512{
513 for (auto &framebuffer : mObjectMap)
514 {
515 if (framebuffer.second)
516 {
517 framebuffer.second->invalidateCompletenessCache();
518 }
519 }
520}
521
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500522} // namespace gl