Commit 4ddf5afb by Geoff Lang Committed by Commit Bot

Refactor ResourceManager into separate managers per resource type.

BUG=angleproject:1639 Change-Id: I943f553cfb0e0feb57953770784b48e22fccc875 Reviewed-on: https://chromium-review.googlesource.com/423172 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent e794cd86
......@@ -49,7 +49,6 @@ class Renderbuffer;
class FenceNV;
class FenceSync;
class Query;
class ResourceManager;
class Buffer;
struct VertexAttribute;
class VertexArray;
......@@ -704,8 +703,6 @@ class Context final : public ValidationContext
bool mRobustAccess;
egl::Surface *mCurrentSurface;
ResourceManager *mResourceManager;
State::DirtyBits mTexImageDirtyBits;
State::DirtyObjects mTexImageDirtyObjects;
State::DirtyBits mReadPixelsDirtyBits;
......
......@@ -14,13 +14,37 @@
namespace gl
{
namespace
{
template <typename T>
using ContextStateMember = T *(ContextState::*);
template <typename T>
T *AllocateOrGetSharedResourceManager(const ContextState *shareContextState,
ContextStateMember<T> member)
{
if (shareContextState)
{
T *resourceManager = (*shareContextState).*member;
resourceManager->addRef();
return resourceManager;
}
else
{
return new T();
}
}
} // anonymous namespace
ContextState::ContextState(uintptr_t contextIn,
const ContextState *shareContextState,
const Version &clientVersion,
State *stateIn,
const Caps &capsIn,
const TextureCapsMap &textureCapsIn,
const Extensions &extensionsIn,
const ResourceManager *resourceManagerIn,
const Limitations &limitationsIn,
const ResourceMap<Framebuffer> &framebufferMap)
: mClientVersion(clientVersion),
......@@ -29,14 +53,30 @@ ContextState::ContextState(uintptr_t contextIn,
mCaps(capsIn),
mTextureCaps(textureCapsIn),
mExtensions(extensionsIn),
mResourceManager(resourceManagerIn),
mLimitations(limitationsIn),
mFramebufferMap(framebufferMap)
mFramebufferMap(framebufferMap),
mBuffers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mBuffers)),
mShaderPrograms(
AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mShaderPrograms)),
mTextures(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mTextures)),
mRenderbuffers(
AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mRenderbuffers)),
mSamplers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mSamplers)),
mFenceSyncs(
AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mFenceSyncs)),
mPaths(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mPaths))
{
}
ContextState::~ContextState()
{
mBuffers->release();
mShaderPrograms->release();
mTextures->release();
mRenderbuffers->release();
mSamplers->release();
mFenceSyncs->release();
mPaths->release();
}
const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
......@@ -44,22 +84,22 @@ const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
return mTextureCaps.get(internalFormat);
}
ValidationContext::ValidationContext(const Version &clientVersion,
ValidationContext::ValidationContext(const ValidationContext *shareContext,
const Version &clientVersion,
State *state,
const Caps &caps,
const TextureCapsMap &textureCaps,
const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap,
bool skipValidation)
: mState(reinterpret_cast<uintptr_t>(this),
shareContext ? &shareContext->mState : nullptr,
clientVersion,
state,
caps,
textureCaps,
extensions,
resourceManager,
limitations,
framebufferMap),
mSkipValidation(skipValidation)
......@@ -598,27 +638,27 @@ bool ValidationContext::getIndexedQueryParameterInfo(GLenum target,
Program *ValidationContext::getProgram(GLuint handle) const
{
return mState.mResourceManager->getProgram(handle);
return mState.mShaderPrograms->getProgram(handle);
}
Shader *ValidationContext::getShader(GLuint handle) const
{
return mState.mResourceManager->getShader(handle);
return mState.mShaderPrograms->getShader(handle);
}
bool ValidationContext::isTextureGenerated(GLuint texture) const
{
return mState.mResourceManager->isTextureGenerated(texture);
return mState.mTextures->isTextureGenerated(texture);
}
bool ValidationContext::isBufferGenerated(GLuint buffer) const
{
return mState.mResourceManager->isBufferGenerated(buffer);
return mState.mBuffers->isBufferGenerated(buffer);
}
bool ValidationContext::isRenderbufferGenerated(GLuint renderbuffer) const
{
return mState.mResourceManager->isRenderbufferGenerated(renderbuffer);
return mState.mRenderbuffers->isRenderbufferGenerated(renderbuffer);
}
bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const
......
......@@ -15,8 +15,15 @@
namespace gl
{
class ValidationContext;
class BufferManager;
class ContextState;
class FenceSyncManager;
class PathManager;
class RenderbufferManager;
class SamplerManager;
class ShaderProgramManager;
class TextureManager;
class ValidationContext;
static constexpr Version ES_2_0 = Version(2, 0);
static constexpr Version ES_3_0 = Version(3, 0);
......@@ -26,12 +33,12 @@ class ContextState final : public angle::NonCopyable
{
public:
ContextState(uintptr_t context,
const ContextState *shareContextState,
const Version &clientVersion,
State *state,
const Caps &caps,
const TextureCapsMap &textureCaps,
const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap);
~ContextState();
......@@ -44,7 +51,6 @@ class ContextState final : public angle::NonCopyable
const Caps &getCaps() const { return mCaps; }
const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
const Extensions &getExtensions() const { return mExtensions; }
const ResourceManager &getResourceManager() const { return *mResourceManager; }
const Limitations &getLimitations() const { return mLimitations; }
const TextureCaps &getTextureCap(GLenum internalFormat) const;
......@@ -59,20 +65,27 @@ class ContextState final : public angle::NonCopyable
const Caps &mCaps;
const TextureCapsMap &mTextureCaps;
const Extensions &mExtensions;
const ResourceManager *mResourceManager;
const Limitations &mLimitations;
const ResourceMap<Framebuffer> &mFramebufferMap;
BufferManager *mBuffers;
ShaderProgramManager *mShaderPrograms;
TextureManager *mTextures;
RenderbufferManager *mRenderbuffers;
SamplerManager *mSamplers;
FenceSyncManager *mFenceSyncs;
PathManager *mPaths;
};
class ValidationContext : angle::NonCopyable
{
public:
ValidationContext(const Version &clientVersion,
ValidationContext(const ValidationContext *shareContext,
const Version &clientVersion,
State *state,
const Caps &caps,
const TextureCapsMap &textureCaps,
const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap,
bool skipValidation);
......
......@@ -380,7 +380,7 @@ GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
return uniformIndex - mSamplerUniformRange.start;
}
Program::Program(rx::GLImplFactory *factory, ResourceManager *manager, GLuint handle)
Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle)
: mProgram(factory->createProgram(mState)),
mValidated(false),
mLinked(false),
......
......@@ -42,8 +42,8 @@ namespace gl
struct Caps;
class Context;
class ContextState;
class ResourceManager;
class Shader;
class ShaderProgramManager;
class InfoLog;
class Buffer;
class Framebuffer;
......@@ -261,7 +261,7 @@ class ProgramState final : angle::NonCopyable
class Program final : angle::NonCopyable, public LabeledObject
{
public:
Program(rx::GLImplFactory *factory, ResourceManager *manager, GLuint handle);
Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle);
~Program();
GLuint id() const { return mHandle; }
......@@ -543,7 +543,7 @@ class Program final : angle::NonCopyable, public LabeledObject
unsigned int mRefCount;
ResourceManager *mResourceManager;
ShaderProgramManager *mResourceManager;
const GLuint mHandle;
InfoLog mInfoLog;
......
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2016 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 class, which tracks objects
// shared by multiple GL contexts.
// ResourceManager.h : Defines the ResourceManager classes, which handle allocation and lifetime of
// GL objects.
#ifndef LIBANGLE_RESOURCEMANAGER_H_
#define LIBANGLE_RESOURCEMANAGER_H_
......@@ -34,89 +34,138 @@ class Sampler;
class Shader;
class Texture;
class ResourceManager : angle::NonCopyable
template <typename HandleAllocatorType>
class ResourceManagerBase : angle::NonCopyable
{
public:
ResourceManager();
~ResourceManager();
ResourceManagerBase();
void addRef();
void release();
protected:
virtual ~ResourceManagerBase() {}
HandleAllocatorType mHandleAllocator;
private:
size_t mRefCount;
};
template <typename ResourceType, typename HandleAllocatorType>
class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType>
{
public:
TypedResourceManager() {}
protected:
~TypedResourceManager() override;
void deleteObject(GLuint handle);
ResourceMap<ResourceType> mObjectMap;
};
class BufferManager : public TypedResourceManager<Buffer, HandleAllocator>
{
public:
GLuint createBuffer();
void deleteBuffer(GLuint buffer);
Buffer *getBuffer(GLuint handle) const;
Buffer *checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle);
bool isBufferGenerated(GLuint buffer) const;
protected:
~BufferManager() override {}
};
class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
{
public:
GLuint createShader(rx::GLImplFactory *factory,
const gl::Limitations &rendererLimitations,
GLenum type);
GLuint createProgram(rx::GLImplFactory *factory);
GLuint createTexture();
GLuint createRenderbuffer();
GLuint createSampler();
GLuint createFenceSync(rx::GLImplFactory *factory);
ErrorOrResult<GLuint> createPaths(rx::GLImplFactory *factory, GLsizei range);
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
void deleteSampler(GLuint sampler);
void deleteFenceSync(GLuint fenceSync);
void deletePaths(GLuint first, GLsizei range);
Buffer *getBuffer(GLuint handle);
Shader *getShader(GLuint handle) const;
Program *getProgram(GLuint handle) const;
Texture *getTexture(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle);
FenceSync *getFenceSync(GLuint handle);
// CHROMIUM_path_rendering
const Path *getPath(GLuint path) const;
Path *getPath(GLuint path);
bool hasPath(GLuint path) const;
GLuint createProgram(rx::GLImplFactory *factory);
void deleteProgram(GLuint program);
Program *getProgram(GLuint handle) const;
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
protected:
~ShaderProgramManager() override;
Buffer *checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle);
Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, GLenum type);
Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, GLuint handle);
Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, GLuint samplerHandle);
private:
template <typename ObjectType>
void deleteObject(ResourceMap<ObjectType> *objectMap, GLuint id);
bool isSampler(GLuint sampler);
ResourceMap<Shader> mShaders;
ResourceMap<Program> mPrograms;
};
// GL_CHROMIUM_bind_generates_resource
class TextureManager : public TypedResourceManager<Texture, HandleAllocator>
{
public:
GLuint createTexture();
void deleteTexture(GLuint texture);
Texture *getTexture(GLuint handle) const;
Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, GLenum type);
bool isTextureGenerated(GLuint texture) const;
bool isBufferGenerated(GLuint buffer) const;
bool isRenderbufferGenerated(GLuint renderbuffer) const;
private:
void createTextureInternal(GLuint handle);
protected:
~TextureManager() override {}
};
std::size_t mRefCount;
class RenderbufferManager : public TypedResourceManager<Renderbuffer, HandleAllocator>
{
public:
GLuint createRenderbuffer();
void deleteRenderbuffer(GLuint renderbuffer);
Renderbuffer *getRenderbuffer(GLuint handle);
Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, GLuint handle);
bool isRenderbufferGenerated(GLuint renderbuffer) const;
ResourceMap<Buffer> mBufferMap;
HandleAllocator mBufferHandleAllocator;
protected:
~RenderbufferManager() override {}
};
ResourceMap<Shader> mShaderMap;
class SamplerManager : public TypedResourceManager<Sampler, HandleAllocator>
{
public:
GLuint createSampler();
void deleteSampler(GLuint sampler);
Sampler *getSampler(GLuint handle);
Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, GLuint handle);
bool isSampler(GLuint sampler);
ResourceMap<Program> mProgramMap;
HandleAllocator mProgramShaderHandleAllocator;
protected:
~SamplerManager() override {}
};
ResourceMap<Texture> mTextureMap;
HandleAllocator mTextureHandleAllocator;
class FenceSyncManager : public TypedResourceManager<FenceSync, HandleAllocator>
{
public:
GLuint createFenceSync(rx::GLImplFactory *factory);
void deleteFenceSync(GLuint fenceSync);
FenceSync *getFenceSync(GLuint handle);
ResourceMap<Renderbuffer> mRenderbufferMap;
HandleAllocator mRenderbufferHandleAllocator;
protected:
~FenceSyncManager() override {}
};
ResourceMap<Sampler> mSamplerMap;
HandleAllocator mSamplerHandleAllocator;
class PathManager : public ResourceManagerBase<HandleRangeAllocator>
{
public:
ErrorOrResult<GLuint> createPaths(rx::GLImplFactory *factory, GLsizei range);
void deletePaths(GLuint first, GLsizei range);
Path *getPath(GLuint handle) const;
bool hasPath(GLuint handle) const;
ResourceMap<FenceSync> mFenceSyncMap;
HandleAllocator mFenceSyncHandleAllocator;
protected:
~PathManager() override;
ResourceMap<Path> mPathMap;
HandleRangeAllocator mPathHandleAllocator;
private:
ResourceMap<Path> mPaths;
};
} // namespace gl
......
......@@ -25,24 +25,30 @@ class ResourceManagerTest : public testing::Test
protected:
void SetUp() override
{
mResourceManager = new ResourceManager();
mTextureManager = new TextureManager();
mBufferManager = new BufferManager();
mRenderbuffermanager = new RenderbufferManager();
}
void TearDown() override
{
SafeDelete(mResourceManager);
mTextureManager->release();
mBufferManager->release();
mRenderbuffermanager->release();
}
MockGLFactory mMockFactory;
ResourceManager *mResourceManager;
TextureManager *mTextureManager;
BufferManager *mBufferManager;
RenderbufferManager *mRenderbuffermanager;
};
TEST_F(ResourceManagerTest, ReallocateBoundTexture)
{
EXPECT_CALL(mMockFactory, createTexture(_)).Times(1).RetiresOnSaturation();
mResourceManager->checkTextureAllocation(&mMockFactory, 1, GL_TEXTURE_2D);
GLuint newTexture = mResourceManager->createTexture();
mTextureManager->checkTextureAllocation(&mMockFactory, 1, GL_TEXTURE_2D);
GLuint newTexture = mTextureManager->createTexture();
EXPECT_NE(1u, newTexture);
}
......@@ -50,8 +56,8 @@ TEST_F(ResourceManagerTest, ReallocateBoundBuffer)
{
EXPECT_CALL(mMockFactory, createBuffer(_)).Times(1).RetiresOnSaturation();
mResourceManager->checkBufferAllocation(&mMockFactory, 1);
GLuint newBuffer = mResourceManager->createBuffer();
mBufferManager->checkBufferAllocation(&mMockFactory, 1);
GLuint newBuffer = mBufferManager->createBuffer();
EXPECT_NE(1u, newBuffer);
}
......@@ -59,8 +65,8 @@ TEST_F(ResourceManagerTest, ReallocateBoundRenderbuffer)
{
EXPECT_CALL(mMockFactory, createRenderbuffer()).Times(1).RetiresOnSaturation();
mResourceManager->checkRenderbufferAllocation(&mMockFactory, 1);
GLuint newRenderbuffer = mResourceManager->createRenderbuffer();
mRenderbuffermanager->checkRenderbufferAllocation(&mMockFactory, 1);
GLuint newRenderbuffer = mRenderbuffermanager->createRenderbuffer();
EXPECT_NE(1u, newRenderbuffer);
}
......
......@@ -83,7 +83,7 @@ ShaderState::~ShaderState()
{
}
Shader::Shader(ResourceManager *manager,
Shader::Shader(ShaderProgramManager *manager,
rx::GLImplFactory *implFactory,
const gl::Limitations &rendererLimitations,
GLenum type,
......
......@@ -35,7 +35,7 @@ namespace gl
class Compiler;
class ContextState;
struct Limitations;
class ResourceManager;
class ShaderProgramManager;
class Context;
class ShaderState final : angle::NonCopyable
......@@ -83,7 +83,7 @@ class ShaderState final : angle::NonCopyable
class Shader final : angle::NonCopyable, public LabeledObject
{
public:
Shader(ResourceManager *manager,
Shader(ShaderProgramManager *manager,
rx::GLImplFactory *implFactory,
const gl::Limitations &rendererLimitations,
GLenum type,
......@@ -145,7 +145,7 @@ class Shader final : angle::NonCopyable, public LabeledObject
bool mCompiled; // Indicates if this shader has been successfully compiled
std::string mInfoLog;
ResourceManager *mResourceManager;
ShaderProgramManager *mResourceManager;
};
bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y);
......
......@@ -30,40 +30,30 @@ namespace
class MockValidationContext : public ValidationContext
{
public:
MockValidationContext(const Version &version,
MockValidationContext(const ValidationContext *shareContext,
const Version &version,
State *state,
const Caps &caps,
const TextureCapsMap &textureCaps,
const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap,
bool skipValidation);
bool skipValidation)
: ValidationContext(shareContext,
version,
state,
caps,
textureCaps,
extensions,
limitations,
framebufferMap,
skipValidation)
{
}
MOCK_METHOD1(handleError, void(const Error &));
};
MockValidationContext::MockValidationContext(const Version &version,
State *state,
const Caps &caps,
const TextureCapsMap &textureCaps,
const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap,
bool skipValidation)
: ValidationContext(version,
state,
caps,
textureCaps,
extensions,
resourceManager,
limitations,
framebufferMap,
skipValidation)
{
}
// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
// but we want a test to ensure we maintain this behaviour.
......@@ -110,9 +100,8 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
state.setDrawFramebufferBinding(framebuffer);
state.setProgram(program);
NiceMock<MockValidationContext> testContext(Version(3, 0), &state, caps, textureCaps,
extensions, nullptr, limitations, framebufferMap,
false);
NiceMock<MockValidationContext> testContext(nullptr, Version(3, 0), &state, caps, textureCaps,
extensions, limitations, framebufferMap, false);
// Set the expectation for the validation error here.
Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment