blob: 31d315a1bd9d8a15a1681df7c6105ed9750e2194 [file] [log] [blame]
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +00001//
Stuart Morgan9d737962019-08-14 12:25:12 -07002// Copyright 2002 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 Madill526392d2018-11-16 09:35:14 -050013#include "libANGLE/Context.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040014#include "libANGLE/Fence.h"
Michael Spangfb201c52019-04-03 14:57:35 -040015#include "libANGLE/MemoryObject.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030016#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/Program.h"
Yunchao Hea336b902017-08-02 16:05:21 +080018#include "libANGLE/ProgramPipeline.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050019#include "libANGLE/Renderbuffer.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040020#include "libANGLE/Sampler.h"
Michael Spang5093ba62019-05-14 17:36:36 -040021#include "libANGLE/Semaphore.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050022#include "libANGLE/Shader.h"
23#include "libANGLE/Texture.h"
Jamie Madill526392d2018-11-16 09:35:14 -050024#include "libANGLE/renderer/ContextImpl.h"
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000025
26namespace gl
27{
Geoff Lang4ddf5af2016-12-01 14:30:44 -050028
29namespace
30{
31
Jamie Madill7c7dec02019-08-06 17:44:11 -040032template <typename ResourceType, typename IDType>
33IDType AllocateEmptyObject(HandleAllocator *handleAllocator,
34 ResourceMap<ResourceType, IDType> *objectMap)
Geoff Lang4ddf5af2016-12-01 14:30:44 -050035{
Jamie Madill7c7dec02019-08-06 17:44:11 -040036 IDType handle = FromGL<IDType>(handleAllocator->allocate());
Jamie Madill96a483b2017-06-27 16:49:21 -040037 objectMap->assign(handle, nullptr);
Geoff Lang4ddf5af2016-12-01 14:30:44 -050038 return handle;
39}
40
Geoff Lang4ddf5af2016-12-01 14:30:44 -050041} // anonymous namespace
42
43template <typename HandleAllocatorType>
44ResourceManagerBase<HandleAllocatorType>::ResourceManagerBase() : mRefCount(1)
Jamie Madillb980c562018-11-27 11:34:27 -050045{}
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000046
Geoff Lang4ddf5af2016-12-01 14:30:44 -050047template <typename HandleAllocatorType>
48void ResourceManagerBase<HandleAllocatorType>::addRef()
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000049{
50 mRefCount++;
51}
52
Geoff Lang4ddf5af2016-12-01 14:30:44 -050053template <typename HandleAllocatorType>
Jamie Madill6c1f6712017-02-14 19:08:04 -050054void ResourceManagerBase<HandleAllocatorType>::release(const Context *context)
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000055{
56 if (--mRefCount == 0)
57 {
Jamie Madill6c1f6712017-02-14 19:08:04 -050058 reset(context);
daniel@transgaming.com0d25b002010-07-28 19:21:07 +000059 delete this;
60 }
61}
62
Jamie Madill7c7dec02019-08-06 17:44:11 -040063template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType>
64TypedResourceManager<ResourceType, HandleAllocatorType, ImplT, IDType>::~TypedResourceManager()
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000065{
Jamie Madill6c1f6712017-02-14 19:08:04 -050066 ASSERT(mObjectMap.empty());
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +000067}
68
Jamie Madill7c7dec02019-08-06 17:44:11 -040069template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType>
70void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT, IDType>::reset(
71 const Context *context)
Jamie Madill6c1f6712017-02-14 19:08:04 -050072{
Jamie Madill96a483b2017-06-27 16:49:21 -040073 this->mHandleAllocator.reset();
74 for (const auto &resource : mObjectMap)
Jamie Madill6c1f6712017-02-14 19:08:04 -050075 {
Jamie Madill96a483b2017-06-27 16:49:21 -040076 if (resource.second)
77 {
78 ImplT::DeleteObject(context, resource.second);
79 }
Jamie Madill6c1f6712017-02-14 19:08:04 -050080 }
81 mObjectMap.clear();
82}
83
Jamie Madill7c7dec02019-08-06 17:44:11 -040084template <typename ResourceType, typename HandleAllocatorType, typename ImplT, typename IDType>
85void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT, IDType>::deleteObject(
Jamie Madill6c1f6712017-02-14 19:08:04 -050086 const Context *context,
Jamie Madill7c7dec02019-08-06 17:44:11 -040087 IDType handle)
Geoff Lang4ddf5af2016-12-01 14:30:44 -050088{
Jamie Madill96a483b2017-06-27 16:49:21 -040089 ResourceType *resource = nullptr;
90 if (!mObjectMap.erase(handle, &resource))
Jamie Madill5f45e7c2017-02-10 15:23:28 -080091 {
92 return;
93 }
94
Jamie Madill5f45e7c2017-02-10 15:23:28 -080095 // Requires an explicit this-> because of C++ template rules.
Jamie Madill7c7dec02019-08-06 17:44:11 -040096 this->mHandleAllocator.release(GetIDValue(handle));
Geoff Lang4ddf5af2016-12-01 14:30:44 -050097
Jamie Madill96a483b2017-06-27 16:49:21 -040098 if (resource)
Jamie Madill5f45e7c2017-02-10 15:23:28 -080099 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400100 ImplT::DeleteObject(context, resource);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800101 }
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800102}
103
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500104template class ResourceManagerBase<HandleAllocator>;
105template class ResourceManagerBase<HandleRangeAllocator>;
Jamie Madill3b3fe832019-08-06 17:44:12 -0400106template class TypedResourceManager<Buffer, HandleAllocator, BufferManager, BufferID>;
Jamie Madill2ab08ed2019-08-12 16:20:21 -0400107template class TypedResourceManager<Texture, HandleAllocator, TextureManager, TextureID>;
Jamie Madill7c7dec02019-08-06 17:44:11 -0400108template class TypedResourceManager<Renderbuffer,
109 HandleAllocator,
110 RenderbufferManager,
111 RenderbufferID>;
Jiacheng Luee79e2f2019-08-20 11:28:36 -0600112template class TypedResourceManager<Sampler, HandleAllocator, SamplerManager, SamplerID>;
Jamie Madill7c7dec02019-08-06 17:44:11 -0400113template class TypedResourceManager<Sync, HandleAllocator, SyncManager, GLuint>;
114template class TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager, GLuint>;
115template class TypedResourceManager<ProgramPipeline,
116 HandleAllocator,
117 ProgramPipelineManager,
Jiacheng Lu378c1882019-08-22 16:55:39 -0600118 ProgramPipelineID>;
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800119
120// BufferManager Implementation.
121
122// static
Jamie Madill3b3fe832019-08-06 17:44:12 -0400123Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, BufferID handle)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800124{
125 Buffer *buffer = new Buffer(factory, handle);
126 buffer->addRef();
127 return buffer;
128}
129
130// static
Jamie Madill4928b7c2017-06-20 12:57:39 -0400131void BufferManager::DeleteObject(const Context *context, Buffer *buffer)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800132{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400133 buffer->release(context);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800134}
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500135
Jamie Madill3b3fe832019-08-06 17:44:12 -0400136BufferID BufferManager::createBuffer()
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500137{
138 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
139}
140
Jamie Madill3b3fe832019-08-06 17:44:12 -0400141Buffer *BufferManager::getBuffer(BufferID handle) const
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500142{
Jamie Madill96a483b2017-06-27 16:49:21 -0400143 return mObjectMap.query(handle);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500144}
145
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800146// ShaderProgramManager Implementation.
147
Jamie Madillb980c562018-11-27 11:34:27 -0500148ShaderProgramManager::ShaderProgramManager() {}
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500149
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500150ShaderProgramManager::~ShaderProgramManager()
151{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500152 ASSERT(mPrograms.empty());
153 ASSERT(mShaders.empty());
154}
155
156void ShaderProgramManager::reset(const Context *context)
157{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500158 while (!mPrograms.empty())
159 {
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600160 deleteProgram(context, {mPrograms.begin()->first});
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500161 }
Jamie Madill6c1f6712017-02-14 19:08:04 -0500162 mPrograms.clear();
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500163 while (!mShaders.empty())
164 {
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600165 deleteShader(context, {mShaders.begin()->first});
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500166 }
Jamie Madill6c1f6712017-02-14 19:08:04 -0500167 mShaders.clear();
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500168}
169
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600170ShaderProgramID ShaderProgramManager::createShader(rx::GLImplFactory *factory,
171 const gl::Limitations &rendererLimitations,
172 ShaderType type)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000173{
Jiawei Shao385b3e02018-03-21 09:43:28 +0800174 ASSERT(type != ShaderType::InvalidEnum);
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600175 ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()};
Jamie Madill96a483b2017-06-27 16:49:21 -0400176 mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle));
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000177 return handle;
178}
179
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600180void ShaderProgramManager::deleteShader(const Context *context, ShaderProgramID shader)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000181{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500182 deleteObject(context, &mShaders, shader);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000183}
184
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600185Shader *ShaderProgramManager::getShader(ShaderProgramID handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000186{
Jamie Madill96a483b2017-06-27 16:49:21 -0400187 return mShaders.query(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000188}
189
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600190ShaderProgramID ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000191{
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600192 ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()};
Jamie Madill96a483b2017-06-27 16:49:21 -0400193 mPrograms.assign(handle, new Program(factory, this, handle));
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000194 return handle;
195}
196
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600197void ShaderProgramManager::deleteProgram(const gl::Context *context, ShaderProgramID program)
Jamie Madilldc356042013-07-19 16:36:57 -0400198{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500199 deleteObject(context, &mPrograms, program);
Jamie Madilldc356042013-07-19 16:36:57 -0400200}
201
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600202template <typename ObjectType, typename IDType>
Jamie Madill6c1f6712017-02-14 19:08:04 -0500203void ShaderProgramManager::deleteObject(const Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600204 ResourceMap<ObjectType, IDType> *objectMap,
205 IDType id)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500206{
Jamie Madill96a483b2017-06-27 16:49:21 -0400207 ObjectType *object = objectMap->query(id);
208 if (!object)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500209 {
210 return;
211 }
212
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500213 if (object->getRefCount() == 0)
214 {
Jiacheng Lu120b61d2019-08-21 12:51:58 -0600215 mHandleAllocator.release(id.value);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400216 object->onDestroy(context);
Jamie Madill96a483b2017-06-27 16:49:21 -0400217 objectMap->erase(id, &object);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500218 }
219 else
220 {
221 object->flagForDeletion();
222 }
223}
224
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800225// TextureManager Implementation.
226
227// static
Corentin Wallez99d492c2018-02-27 15:17:10 -0500228Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory,
Jamie Madill2ab08ed2019-08-12 16:20:21 -0400229 TextureID handle,
Corentin Wallez99d492c2018-02-27 15:17:10 -0500230 TextureType type)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800231{
Corentin Wallez99d492c2018-02-27 15:17:10 -0500232 Texture *texture = new Texture(factory, handle, type);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800233 texture->addRef();
234 return texture;
235}
236
237// static
Jamie Madill4928b7c2017-06-20 12:57:39 -0400238void TextureManager::DeleteObject(const Context *context, Texture *texture)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800239{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400240 texture->release(context);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800241}
242
Jamie Madill2ab08ed2019-08-12 16:20:21 -0400243TextureID TextureManager::createTexture()
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500244{
245 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
246}
247
Jamie Madill124f78c2019-06-18 11:48:24 -0400248void TextureManager::signalAllTexturesDirty() const
Geoff Lang9aded172017-04-05 11:07:56 -0400249{
Jamie Madill96a483b2017-06-27 16:49:21 -0400250 for (const auto &texture : mObjectMap)
Geoff Lang9aded172017-04-05 11:07:56 -0400251 {
252 if (texture.second)
253 {
Jamie Madill05b35b22017-10-03 09:01:44 -0400254 // We don't know if the Texture needs init, but that's ok, since it will only force
255 // a re-check, and will not initialize the pixels if it's not needed.
Jamie Madill124f78c2019-06-18 11:48:24 -0400256 texture.second->signalDirtyStorage(InitState::MayNeedInit);
Geoff Lang9aded172017-04-05 11:07:56 -0400257 }
258 }
259}
260
Jamie Madillfc3463d2018-01-03 13:46:21 -0500261void TextureManager::enableHandleAllocatorLogging()
262{
263 mHandleAllocator.enableLogging(true);
264}
265
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800266// RenderbufferManager Implementation.
267
268// static
Jamie Madill7c7dec02019-08-06 17:44:11 -0400269Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory,
270 RenderbufferID handle)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800271{
Jamie Madille703c602018-02-20 10:21:48 -0500272 Renderbuffer *renderbuffer = new Renderbuffer(factory, handle);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800273 renderbuffer->addRef();
274 return renderbuffer;
275}
276
277// static
Jamie Madill4928b7c2017-06-20 12:57:39 -0400278void RenderbufferManager::DeleteObject(const Context *context, Renderbuffer *renderbuffer)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800279{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400280 renderbuffer->release(context);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800281}
282
Jamie Madill7c7dec02019-08-06 17:44:11 -0400283RenderbufferID RenderbufferManager::createRenderbuffer()
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500284{
Jamie Madill7c7dec02019-08-06 17:44:11 -0400285 return {AllocateEmptyObject(&mHandleAllocator, &mObjectMap)};
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500286}
287
Jamie Madill7c7dec02019-08-06 17:44:11 -0400288Renderbuffer *RenderbufferManager::getRenderbuffer(RenderbufferID handle) const
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500289{
Jamie Madill96a483b2017-06-27 16:49:21 -0400290 return mObjectMap.query(handle);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500291}
292
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800293// SamplerManager Implementation.
294
295// static
Jiacheng Luee79e2f2019-08-20 11:28:36 -0600296Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800297{
298 Sampler *sampler = new Sampler(factory, handle);
299 sampler->addRef();
300 return sampler;
301}
302
303// static
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304void SamplerManager::DeleteObject(const Context *context, Sampler *sampler)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800305{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400306 sampler->release(context);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800307}
308
Jiacheng Luee79e2f2019-08-20 11:28:36 -0600309SamplerID SamplerManager::createSampler()
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500310{
311 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
312}
313
Jiacheng Luee79e2f2019-08-20 11:28:36 -0600314Sampler *SamplerManager::getSampler(SamplerID handle) const
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500315{
Jamie Madill96a483b2017-06-27 16:49:21 -0400316 return mObjectMap.query(handle);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500317}
318
Jiacheng Luee79e2f2019-08-20 11:28:36 -0600319bool SamplerManager::isSampler(SamplerID sampler) const
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500320{
Jamie Madill96a483b2017-06-27 16:49:21 -0400321 return mObjectMap.contains(sampler);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500322}
323
Jamie Madill70b5bb02017-08-28 13:32:37 -0400324// SyncManager Implementation.
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800325
326// static
Jamie Madill70b5bb02017-08-28 13:32:37 -0400327void SyncManager::DeleteObject(const Context *context, Sync *sync)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500328{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400329 sync->release(context);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500330}
331
Jamie Madill70b5bb02017-08-28 13:32:37 -0400332GLuint SyncManager::createSync(rx::GLImplFactory *factory)
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500333{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400334 GLuint handle = mHandleAllocator.allocate();
335 Sync *sync = new Sync(factory->createSync(), handle);
336 sync->addRef();
337 mObjectMap.assign(handle, sync);
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800338 return handle;
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500339}
340
Jamie Madill70b5bb02017-08-28 13:32:37 -0400341Sync *SyncManager::getSync(GLuint handle) const
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500342{
Jamie Madill96a483b2017-06-27 16:49:21 -0400343 return mObjectMap.query(handle);
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500344}
345
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800346// PathManager Implementation.
347
Jamie Madill526392d2018-11-16 09:35:14 -0500348PathManager::PathManager() = default;
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500349
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600350angle::Result PathManager::createPaths(Context *context, GLsizei range, PathID *createdOut)
Sami Väisänene45e53b2016-05-25 10:36:04 +0300351{
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600352 *createdOut = {0};
Jamie Madill13951342018-09-30 15:24:28 -0400353
Sami Väisänene45e53b2016-05-25 10:36:04 +0300354 // Allocate client side handles.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500355 const GLuint client = mHandleAllocator.allocateRange(static_cast<GLuint>(range));
Sami Väisänene45e53b2016-05-25 10:36:04 +0300356 if (client == HandleRangeAllocator::kInvalidHandle)
Jamie Madill526392d2018-11-16 09:35:14 -0500357 {
358 context->handleError(GL_OUT_OF_MEMORY, "Failed to allocate path handle range.", __FILE__,
359 ANGLE_FUNCTION, __LINE__);
Jamie Madill7c985f52018-11-29 18:16:17 -0500360 return angle::Result::Stop;
Jamie Madill526392d2018-11-16 09:35:14 -0500361 }
Sami Väisänene45e53b2016-05-25 10:36:04 +0300362
Jamie Madill526392d2018-11-16 09:35:14 -0500363 const auto &paths = context->getImplementation()->createPaths(range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300364 if (paths.empty())
365 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500366 mHandleAllocator.releaseRange(client, range);
Jamie Madill526392d2018-11-16 09:35:14 -0500367 context->handleError(GL_OUT_OF_MEMORY, "Failed to allocate path objects.", __FILE__,
368 ANGLE_FUNCTION, __LINE__);
Jamie Madill7c985f52018-11-29 18:16:17 -0500369 return angle::Result::Stop;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300370 }
371
Sami Väisänene45e53b2016-05-25 10:36:04 +0300372 for (GLsizei i = 0; i < range; ++i)
373 {
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500374 rx::PathImpl *impl = paths[static_cast<unsigned>(i)];
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600375 PathID id = PathID{client + i};
Jamie Madill96a483b2017-06-27 16:49:21 -0400376 mPaths.assign(id, new Path(impl));
Sami Väisänene45e53b2016-05-25 10:36:04 +0300377 }
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600378 *createdOut = PathID{client};
Jamie Madill7c985f52018-11-29 18:16:17 -0500379 return angle::Result::Continue;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300380}
381
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600382void PathManager::deletePaths(PathID first, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +0300383{
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600384 GLuint firstHandle = first.value;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300385 for (GLsizei i = 0; i < range; ++i)
386 {
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600387 GLuint id = firstHandle + i;
388 Path *p = nullptr;
389 if (!mPaths.erase({id}, &p))
Sami Väisänene45e53b2016-05-25 10:36:04 +0300390 continue;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300391 delete p;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300392 }
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600393 mHandleAllocator.releaseRange(firstHandle, static_cast<GLuint>(range));
Sami Väisänene45e53b2016-05-25 10:36:04 +0300394}
395
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600396Path *PathManager::getPath(PathID handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000397{
Jamie Madill96a483b2017-06-27 16:49:21 -0400398 return mPaths.query(handle);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000399}
400
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600401bool PathManager::hasPath(PathID handle) const
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000402{
Jiacheng Lu7b5744f2019-08-22 16:26:35 -0600403 return mHandleAllocator.isUsed(GetIDValue(handle));
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000404}
405
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500406PathManager::~PathManager()
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000407{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500408 ASSERT(mPaths.empty());
409}
410
411void PathManager::reset(const Context *context)
412{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500413 for (auto path : mPaths)
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000414 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500415 SafeDelete(path.second);
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000416 }
Jamie Madill6c1f6712017-02-14 19:08:04 -0500417 mPaths.clear();
Geoff Langf41a7152016-09-19 15:11:17 -0400418}
419
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800420// FramebufferManager Implementation.
421
422// static
423Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
424 GLuint handle,
425 const Caps &caps)
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500426{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800427 return new Framebuffer(caps, factory, handle);
428}
429
430// static
Jamie Madill4928b7c2017-06-20 12:57:39 -0400431void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer)
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800432{
Geoff Langbf7b95d2018-05-01 16:48:21 -0400433 framebuffer->onDestroy(context);
434 delete framebuffer;
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500435}
436
437GLuint FramebufferManager::createFramebuffer()
438{
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800439 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500440}
441
442Framebuffer *FramebufferManager::getFramebuffer(GLuint handle) const
443{
Jamie Madill96a483b2017-06-27 16:49:21 -0400444 return mObjectMap.query(handle);
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500445}
446
447void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer)
448{
449 ASSERT(framebuffer == nullptr || framebuffer->id() == 0);
Jamie Madill96a483b2017-06-27 16:49:21 -0400450 mObjectMap.assign(0, framebuffer);
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500451}
452
Jamie Madill124f78c2019-06-18 11:48:24 -0400453void FramebufferManager::invalidateFramebufferComplenessCache() const
Geoff Lang9aded172017-04-05 11:07:56 -0400454{
Jamie Madill96a483b2017-06-27 16:49:21 -0400455 for (const auto &framebuffer : mObjectMap)
Geoff Lang9aded172017-04-05 11:07:56 -0400456 {
457 if (framebuffer.second)
458 {
Jamie Madill124f78c2019-06-18 11:48:24 -0400459 framebuffer.second->invalidateCompletenessCache();
Geoff Lang9aded172017-04-05 11:07:56 -0400460 }
461 }
462}
463
Yunchao Hea336b902017-08-02 16:05:21 +0800464// ProgramPipelineManager Implementation.
465
466// static
467ProgramPipeline *ProgramPipelineManager::AllocateNewObject(rx::GLImplFactory *factory,
Jiacheng Lu378c1882019-08-22 16:55:39 -0600468 ProgramPipelineID handle)
Yunchao Hea336b902017-08-02 16:05:21 +0800469{
470 ProgramPipeline *pipeline = new ProgramPipeline(factory, handle);
471 pipeline->addRef();
472 return pipeline;
473}
474
475// static
476void ProgramPipelineManager::DeleteObject(const Context *context, ProgramPipeline *pipeline)
477{
478 pipeline->release(context);
479}
480
Jiacheng Lu378c1882019-08-22 16:55:39 -0600481ProgramPipelineID ProgramPipelineManager::createProgramPipeline()
Yunchao Hea336b902017-08-02 16:05:21 +0800482{
483 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
484}
485
Jiacheng Lu378c1882019-08-22 16:55:39 -0600486ProgramPipeline *ProgramPipelineManager::getProgramPipeline(ProgramPipelineID handle) const
Yunchao Hea336b902017-08-02 16:05:21 +0800487{
488 return mObjectMap.query(handle);
489}
490
Michael Spangfb201c52019-04-03 14:57:35 -0400491// MemoryObjectManager Implementation.
492
493MemoryObjectManager::MemoryObjectManager() {}
494
495MemoryObjectManager::~MemoryObjectManager()
496{
497 ASSERT(mMemoryObjects.empty());
498}
499
500void MemoryObjectManager::reset(const Context *context)
501{
502 while (!mMemoryObjects.empty())
503 {
504 deleteMemoryObject(context, mMemoryObjects.begin()->first);
505 }
506 mMemoryObjects.clear();
507}
508
509GLuint MemoryObjectManager::createMemoryObject(rx::GLImplFactory *factory)
510{
Jamie Madill124f78c2019-06-18 11:48:24 -0400511 GLuint handle = mHandleAllocator.allocate();
Michael Spanga0b00e92019-04-09 18:45:22 -0400512 MemoryObject *memoryObject = new MemoryObject(factory, handle);
513 memoryObject->addRef();
514 mMemoryObjects.assign(handle, memoryObject);
Michael Spangfb201c52019-04-03 14:57:35 -0400515 return handle;
516}
517
518void MemoryObjectManager::deleteMemoryObject(const Context *context, GLuint handle)
519{
520 MemoryObject *memoryObject = nullptr;
521 if (!mMemoryObjects.erase(handle, &memoryObject))
522 {
523 return;
524 }
525
526 // Requires an explicit this-> because of C++ template rules.
527 this->mHandleAllocator.release(handle);
528
529 if (memoryObject)
530 {
531 memoryObject->release(context);
532 }
533}
534
535MemoryObject *MemoryObjectManager::getMemoryObject(GLuint handle) const
536{
537 return mMemoryObjects.query(handle);
538}
539
Michael Spang5093ba62019-05-14 17:36:36 -0400540// SemaphoreManager Implementation.
541
542SemaphoreManager::SemaphoreManager() {}
543
544SemaphoreManager::~SemaphoreManager()
545{
546 ASSERT(mSemaphores.empty());
547}
548
549void SemaphoreManager::reset(const Context *context)
550{
551 while (!mSemaphores.empty())
552 {
553 deleteSemaphore(context, mSemaphores.begin()->first);
554 }
555 mSemaphores.clear();
556}
557
558GLuint SemaphoreManager::createSemaphore(rx::GLImplFactory *factory)
559{
560 GLuint handle = mHandleAllocator.allocate();
561 Semaphore *semaphore = new Semaphore(factory, handle);
562 semaphore->addRef();
563 mSemaphores.assign(handle, semaphore);
564 return handle;
565}
566
567void SemaphoreManager::deleteSemaphore(const Context *context, GLuint handle)
568{
569 Semaphore *semaphore = nullptr;
570 if (!mSemaphores.erase(handle, &semaphore))
571 {
572 return;
573 }
574
575 // Requires an explicit this-> because of C++ template rules.
576 this->mHandleAllocator.release(handle);
577
578 if (semaphore)
579 {
580 semaphore->release(context);
581 }
582}
583
584Semaphore *SemaphoreManager::getSemaphore(GLuint handle) const
585{
586 return mSemaphores.query(handle);
587}
588
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500589} // namespace gl