356 lines
10 KiB
C++
356 lines
10 KiB
C++
//
|
|
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
|
|
// ResourceManager.h : Defines the ResourceManager classes, which handle allocation and lifetime of
|
|
// GL objects.
|
|
|
|
#ifndef LIBANGLE_RESOURCEMANAGER_H_
|
|
#define LIBANGLE_RESOURCEMANAGER_H_
|
|
|
|
#include "angle_gl.h"
|
|
#include "common/angleutils.h"
|
|
#include "libANGLE/Error.h"
|
|
#include "libANGLE/HandleAllocator.h"
|
|
#include "libANGLE/ResourceMap.h"
|
|
|
|
namespace rx
|
|
{
|
|
class GLImplFactory;
|
|
} // namespace rx
|
|
|
|
namespace egl
|
|
{
|
|
class ShareGroup;
|
|
} // namespace egl
|
|
|
|
namespace gl
|
|
{
|
|
class Buffer;
|
|
struct Caps;
|
|
class Context;
|
|
class Framebuffer;
|
|
struct Limitations;
|
|
class MemoryObject;
|
|
class Path;
|
|
class Program;
|
|
class ProgramPipeline;
|
|
class Renderbuffer;
|
|
class Sampler;
|
|
class Semaphore;
|
|
class Shader;
|
|
class Sync;
|
|
class Texture;
|
|
|
|
class ResourceManagerBase : angle::NonCopyable
|
|
{
|
|
public:
|
|
ResourceManagerBase();
|
|
|
|
void addRef();
|
|
void release(const Context *context);
|
|
|
|
protected:
|
|
virtual void reset(const Context *context) = 0;
|
|
virtual ~ResourceManagerBase();
|
|
|
|
HandleAllocator mHandleAllocator;
|
|
|
|
private:
|
|
size_t mRefCount;
|
|
};
|
|
|
|
template <typename ResourceType, typename ImplT, typename IDType>
|
|
class TypedResourceManager : public ResourceManagerBase
|
|
{
|
|
public:
|
|
TypedResourceManager() {}
|
|
|
|
void deleteObject(const Context *context, IDType handle);
|
|
ANGLE_INLINE bool isHandleGenerated(IDType handle) const
|
|
{
|
|
// Zero is always assumed to have been generated implicitly.
|
|
return GetIDValue(handle) == 0 || mObjectMap.contains(handle);
|
|
}
|
|
|
|
typename ResourceMap<ResourceType, IDType>::Iterator begin() const
|
|
{
|
|
return mObjectMap.begin();
|
|
}
|
|
typename ResourceMap<ResourceType, IDType>::Iterator end() const { return mObjectMap.end(); }
|
|
|
|
protected:
|
|
~TypedResourceManager() override;
|
|
|
|
// Inlined in the header for performance.
|
|
template <typename... ArgTypes>
|
|
ANGLE_INLINE ResourceType *checkObjectAllocation(rx::GLImplFactory *factory,
|
|
IDType handle,
|
|
ArgTypes... args)
|
|
{
|
|
ResourceType *value = mObjectMap.query(handle);
|
|
if (value)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
if (GetIDValue(handle) == 0)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return checkObjectAllocationImpl(factory, handle, args...);
|
|
}
|
|
|
|
void reset(const Context *context) override;
|
|
|
|
ResourceMap<ResourceType, IDType> mObjectMap;
|
|
|
|
private:
|
|
template <typename... ArgTypes>
|
|
ResourceType *checkObjectAllocationImpl(rx::GLImplFactory *factory,
|
|
IDType handle,
|
|
ArgTypes... args)
|
|
{
|
|
ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...);
|
|
|
|
if (!mObjectMap.contains(handle))
|
|
{
|
|
this->mHandleAllocator.reserve(GetIDValue(handle));
|
|
}
|
|
mObjectMap.assign(handle, object);
|
|
|
|
return object;
|
|
}
|
|
};
|
|
|
|
class BufferManager : public TypedResourceManager<Buffer, BufferManager, BufferID>
|
|
{
|
|
public:
|
|
BufferID createBuffer();
|
|
Buffer *getBuffer(BufferID handle) const;
|
|
|
|
ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle)
|
|
{
|
|
return checkObjectAllocation(factory, handle);
|
|
}
|
|
|
|
// TODO(jmadill): Investigate design which doesn't expose these methods publicly.
|
|
static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle);
|
|
static void DeleteObject(const Context *context, Buffer *buffer);
|
|
|
|
protected:
|
|
~BufferManager() override;
|
|
};
|
|
|
|
class ShaderProgramManager : public ResourceManagerBase
|
|
{
|
|
public:
|
|
ShaderProgramManager();
|
|
|
|
ShaderProgramID createShader(rx::GLImplFactory *factory,
|
|
const Limitations &rendererLimitations,
|
|
ShaderType type);
|
|
void deleteShader(const Context *context, ShaderProgramID shader);
|
|
Shader *getShader(ShaderProgramID handle) const;
|
|
|
|
ShaderProgramID createProgram(rx::GLImplFactory *factory);
|
|
void deleteProgram(const Context *context, ShaderProgramID program);
|
|
|
|
ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const
|
|
{
|
|
return mPrograms.query(handle);
|
|
}
|
|
|
|
// For capture and performance counters only.
|
|
const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; }
|
|
const ResourceMap<Program, ShaderProgramID> &getProgramsForCaptureAndPerf() const
|
|
{
|
|
return mPrograms;
|
|
}
|
|
|
|
protected:
|
|
~ShaderProgramManager() override;
|
|
|
|
private:
|
|
template <typename ObjectType, typename IDType>
|
|
void deleteObject(const Context *context,
|
|
ResourceMap<ObjectType, IDType> *objectMap,
|
|
IDType id);
|
|
|
|
void reset(const Context *context) override;
|
|
|
|
ResourceMap<Shader, ShaderProgramID> mShaders;
|
|
ResourceMap<Program, ShaderProgramID> mPrograms;
|
|
};
|
|
|
|
class TextureManager : public TypedResourceManager<Texture, TextureManager, TextureID>
|
|
{
|
|
public:
|
|
TextureID createTexture();
|
|
ANGLE_INLINE Texture *getTexture(TextureID handle) const
|
|
{
|
|
ASSERT(mObjectMap.query({0}) == nullptr);
|
|
return mObjectMap.query(handle);
|
|
}
|
|
|
|
void signalAllTexturesDirty() const;
|
|
|
|
ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory,
|
|
TextureID handle,
|
|
TextureType type)
|
|
{
|
|
return checkObjectAllocation(factory, handle, type);
|
|
}
|
|
|
|
static Texture *AllocateNewObject(rx::GLImplFactory *factory,
|
|
TextureID handle,
|
|
TextureType type);
|
|
static void DeleteObject(const Context *context, Texture *texture);
|
|
|
|
void enableHandleAllocatorLogging();
|
|
|
|
protected:
|
|
~TextureManager() override;
|
|
};
|
|
|
|
class RenderbufferManager
|
|
: public TypedResourceManager<Renderbuffer, RenderbufferManager, RenderbufferID>
|
|
{
|
|
public:
|
|
RenderbufferID createRenderbuffer();
|
|
Renderbuffer *getRenderbuffer(RenderbufferID handle) const;
|
|
|
|
Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle)
|
|
{
|
|
return checkObjectAllocation(factory, handle);
|
|
}
|
|
|
|
static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle);
|
|
static void DeleteObject(const Context *context, Renderbuffer *renderbuffer);
|
|
|
|
protected:
|
|
~RenderbufferManager() override;
|
|
};
|
|
|
|
class SamplerManager : public TypedResourceManager<Sampler, SamplerManager, SamplerID>
|
|
{
|
|
public:
|
|
SamplerID createSampler();
|
|
Sampler *getSampler(SamplerID handle) const;
|
|
bool isSampler(SamplerID sampler) const;
|
|
|
|
Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle)
|
|
{
|
|
return checkObjectAllocation(factory, handle);
|
|
}
|
|
|
|
static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle);
|
|
static void DeleteObject(const Context *context, Sampler *sampler);
|
|
|
|
protected:
|
|
~SamplerManager() override;
|
|
};
|
|
|
|
class SyncManager : public TypedResourceManager<Sync, SyncManager, GLuint>
|
|
{
|
|
public:
|
|
GLuint createSync(rx::GLImplFactory *factory);
|
|
Sync *getSync(GLuint handle) const;
|
|
|
|
static void DeleteObject(const Context *context, Sync *sync);
|
|
|
|
protected:
|
|
~SyncManager() override;
|
|
};
|
|
|
|
class FramebufferManager
|
|
: public TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID>
|
|
{
|
|
public:
|
|
FramebufferID createFramebuffer();
|
|
Framebuffer *getFramebuffer(FramebufferID handle) const;
|
|
void setDefaultFramebuffer(Framebuffer *framebuffer);
|
|
Framebuffer *getDefaultFramebuffer() const;
|
|
|
|
void invalidateFramebufferCompletenessCache() const;
|
|
|
|
Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
|
|
const Caps &caps,
|
|
FramebufferID handle,
|
|
egl::ShareGroup *shareGroup)
|
|
{
|
|
return checkObjectAllocation<const Caps &>(factory, handle, caps, shareGroup);
|
|
}
|
|
|
|
static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
|
|
FramebufferID handle,
|
|
const Caps &caps,
|
|
egl::ShareGroup *shareGroup);
|
|
static void DeleteObject(const Context *context, Framebuffer *framebuffer);
|
|
|
|
protected:
|
|
~FramebufferManager() override;
|
|
};
|
|
|
|
class ProgramPipelineManager
|
|
: public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID>
|
|
{
|
|
public:
|
|
ProgramPipelineID createProgramPipeline();
|
|
ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const;
|
|
|
|
ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory,
|
|
ProgramPipelineID handle)
|
|
{
|
|
return checkObjectAllocation(factory, handle);
|
|
}
|
|
|
|
static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle);
|
|
static void DeleteObject(const Context *context, ProgramPipeline *pipeline);
|
|
|
|
protected:
|
|
~ProgramPipelineManager() override;
|
|
};
|
|
|
|
class MemoryObjectManager : public ResourceManagerBase
|
|
{
|
|
public:
|
|
MemoryObjectManager();
|
|
|
|
MemoryObjectID createMemoryObject(rx::GLImplFactory *factory);
|
|
void deleteMemoryObject(const Context *context, MemoryObjectID handle);
|
|
MemoryObject *getMemoryObject(MemoryObjectID handle) const;
|
|
|
|
protected:
|
|
~MemoryObjectManager() override;
|
|
|
|
private:
|
|
void reset(const Context *context) override;
|
|
|
|
ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects;
|
|
};
|
|
|
|
class SemaphoreManager : public ResourceManagerBase
|
|
{
|
|
public:
|
|
SemaphoreManager();
|
|
|
|
SemaphoreID createSemaphore(rx::GLImplFactory *factory);
|
|
void deleteSemaphore(const Context *context, SemaphoreID handle);
|
|
Semaphore *getSemaphore(SemaphoreID handle) const;
|
|
|
|
protected:
|
|
~SemaphoreManager() override;
|
|
|
|
private:
|
|
void reset(const Context *context) override;
|
|
|
|
ResourceMap<Semaphore, SemaphoreID> mSemaphores;
|
|
};
|
|
} // namespace gl
|
|
|
|
#endif // LIBANGLE_RESOURCEMANAGER_H_
|