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
......@@ -46,7 +46,7 @@ namespace
{
template <typename T>
std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
GLsizei numPaths,
const void *paths,
GLuint pathBase)
......@@ -66,7 +66,7 @@ std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
return ret;
}
std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
GLsizei numPaths,
GLenum pathNameType,
const void *paths,
......@@ -239,12 +239,12 @@ Context::Context(rx::EGLImplFactory *implFactory,
const Context *shareContext,
const egl::AttributeMap &attribs)
: ValidationContext(GetClientVersion(attribs),
: ValidationContext(shareContext,
GetClientVersion(attribs),
&mGLState,
mCaps,
mTextureCaps,
mExtensions,
nullptr,
mLimitations,
mFramebufferMap,
GetNoError(attribs)),
......@@ -258,8 +258,7 @@ Context::Context(rx::EGLImplFactory *implFactory,
mContextLostForced(false),
mResetStrategy(GetResetStrategy(attribs)),
mRobustAccess(GetRobustAccess(attribs)),
mCurrentSurface(nullptr),
mResourceManager(nullptr)
mCurrentSurface(nullptr)
{
if (mRobustAccess)
{
......@@ -274,18 +273,6 @@ Context::Context(rx::EGLImplFactory *implFactory,
mFenceNVHandleAllocator.setBaseHandle(0);
if (shareContext != nullptr)
{
mResourceManager = shareContext->mResourceManager;
mResourceManager->addRef();
}
else
{
mResourceManager = new ResourceManager();
}
mState.mResourceManager = mResourceManager;
// [OpenGL ES 2.0.24] section 3.7 page 83:
// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
// and cube map texture state vectors respectively associated with them.
......@@ -444,11 +431,6 @@ Context::~Context()
releaseSurface();
}
if (mResourceManager)
{
mResourceManager->release();
}
SafeDelete(mCompiler);
}
......@@ -521,39 +503,39 @@ void Context::releaseSurface()
GLuint Context::createBuffer()
{
return mResourceManager->createBuffer();
return mState.mBuffers->createBuffer();
}
GLuint Context::createProgram()
{
return mResourceManager->createProgram(mImplementation.get());
return mState.mShaderPrograms->createProgram(mImplementation.get());
}
GLuint Context::createShader(GLenum type)
{
return mResourceManager->createShader(mImplementation.get(), mLimitations, type);
return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
}
GLuint Context::createTexture()
{
return mResourceManager->createTexture();
return mState.mTextures->createTexture();
}
GLuint Context::createRenderbuffer()
{
return mResourceManager->createRenderbuffer();
return mState.mRenderbuffers->createRenderbuffer();
}
GLsync Context::createFenceSync()
{
GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
}
GLuint Context::createPaths(GLsizei range)
{
auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
if (resultOrError.isError())
{
handleError(resultOrError.getError());
......@@ -571,7 +553,7 @@ GLuint Context::createVertexArray()
GLuint Context::createSampler()
{
return mResourceManager->createSampler();
return mState.mSamplers->createSampler();
}
GLuint Context::createTransformFeedback()
......@@ -612,42 +594,42 @@ GLuint Context::createQuery()
void Context::deleteBuffer(GLuint buffer)
{
if (mResourceManager->getBuffer(buffer))
if (mState.mBuffers->getBuffer(buffer))
{
detachBuffer(buffer);
}
mResourceManager->deleteBuffer(buffer);
mState.mBuffers->deleteBuffer(buffer);
}
void Context::deleteShader(GLuint shader)
{
mResourceManager->deleteShader(shader);
mState.mShaderPrograms->deleteShader(shader);
}
void Context::deleteProgram(GLuint program)
{
mResourceManager->deleteProgram(program);
mState.mShaderPrograms->deleteProgram(program);
}
void Context::deleteTexture(GLuint texture)
{
if (mResourceManager->getTexture(texture))
if (mState.mTextures->getTexture(texture))
{
detachTexture(texture);
}
mResourceManager->deleteTexture(texture);
mState.mTextures->deleteTexture(texture);
}
void Context::deleteRenderbuffer(GLuint renderbuffer)
{
if (mResourceManager->getRenderbuffer(renderbuffer))
if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
{
detachRenderbuffer(renderbuffer);
}
mResourceManager->deleteRenderbuffer(renderbuffer);
mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
}
void Context::deleteFenceSync(GLsync fenceSync)
......@@ -656,17 +638,18 @@ void Context::deleteFenceSync(GLsync fenceSync)
// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
// and since our API is currently designed for being called from a single thread, we can delete
// the fence immediately.
mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
mState.mFenceSyncs->deleteFenceSync(
static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
}
void Context::deletePaths(GLuint first, GLsizei range)
{
mResourceManager->deletePaths(first, range);
mState.mPaths->deletePaths(first, range);
}
bool Context::hasPathData(GLuint path) const
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
if (pathObj == nullptr)
return false;
......@@ -675,7 +658,7 @@ bool Context::hasPathData(GLuint path) const
bool Context::hasPath(GLuint path) const
{
return mResourceManager->hasPath(path);
return mState.mPaths->hasPath(path);
}
void Context::setPathCommands(GLuint path,
......@@ -685,14 +668,14 @@ void Context::setPathCommands(GLuint path,
GLenum coordType,
const void *coords)
{
auto *pathObject = mResourceManager->getPath(path);
auto *pathObject = mState.mPaths->getPath(path);
handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
}
void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
{
auto *pathObj = mResourceManager->getPath(path);
auto *pathObj = mState.mPaths->getPath(path);
switch (pname)
{
......@@ -719,7 +702,7 @@ void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
switch (pname)
{
......@@ -768,12 +751,12 @@ void Context::deleteVertexArray(GLuint vertexArray)
void Context::deleteSampler(GLuint sampler)
{
if (mResourceManager->getSampler(sampler))
if (mState.mSamplers->getSampler(sampler))
{
detachSampler(sampler);
}
mResourceManager->deleteSampler(sampler);
mState.mSamplers->deleteSampler(sampler);
}
void Context::deleteTransformFeedback(GLuint transformFeedback)
......@@ -835,22 +818,23 @@ void Context::deleteQuery(GLuint query)
Buffer *Context::getBuffer(GLuint handle) const
{
return mResourceManager->getBuffer(handle);
return mState.mBuffers->getBuffer(handle);
}
Texture *Context::getTexture(GLuint handle) const
{
return mResourceManager->getTexture(handle);
return mState.mTextures->getTexture(handle);
}
Renderbuffer *Context::getRenderbuffer(GLuint handle) const
{
return mResourceManager->getRenderbuffer(handle);
return mState.mRenderbuffers->getRenderbuffer(handle);
}
FenceSync *Context::getFenceSync(GLsync handle) const
{
return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
return mState.mFenceSyncs->getFenceSync(
static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
}
VertexArray *Context::getVertexArray(GLuint handle) const
......@@ -861,7 +845,7 @@ VertexArray *Context::getVertexArray(GLuint handle) const
Sampler *Context::getSampler(GLuint handle) const
{
return mResourceManager->getSampler(handle);
return mState.mSamplers->getSampler(handle);
}
TransformFeedback *Context::getTransformFeedback(GLuint handle) const
......@@ -950,24 +934,24 @@ void Context::getObjectPtrLabel(const void *ptr,
bool Context::isSampler(GLuint samplerName) const
{
return mResourceManager->isSampler(samplerName);
return mState.mSamplers->isSampler(samplerName);
}
void Context::bindArrayBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setArrayBufferBinding(buffer);
}
void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setDrawIndirectBufferBinding(buffer);
}
void Context::bindElementArrayBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.getVertexArray()->setElementArrayBuffer(buffer);
}
......@@ -981,7 +965,7 @@ void Context::bindTexture(GLenum target, GLuint handle)
}
else
{
texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
}
ASSERT(texture);
......@@ -1010,13 +994,13 @@ void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
{
ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Sampler *sampler =
mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
mGLState.setSamplerBinding(textureUnit, sampler);
}
void Context::bindGenericUniformBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setGenericUniformBufferBinding(buffer);
}
......@@ -1025,13 +1009,13 @@ void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
GLintptr offset,
GLsizeiptr size)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
}
void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
}
......@@ -1040,31 +1024,31 @@ void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
GLintptr offset,
GLsizeiptr size)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
}
void Context::bindCopyReadBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setCopyReadBufferBinding(buffer);
}
void Context::bindCopyWriteBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setCopyWriteBufferBinding(buffer);
}
void Context::bindPixelPackBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setPixelPackBufferBinding(buffer);
}
void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
{
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setPixelUnpackBufferBinding(buffer);
}
......@@ -1742,7 +1726,7 @@ void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj)
return;
......@@ -1754,7 +1738,7 @@ void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj)
return;
......@@ -1766,7 +1750,7 @@ void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
void Context::coverFillPath(GLuint path, GLenum coverMode)
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj)
return;
......@@ -1778,7 +1762,7 @@ void Context::coverFillPath(GLuint path, GLenum coverMode)
void Context::coverStrokePath(GLuint path, GLenum coverMode)
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj)
return;
......@@ -1790,7 +1774,7 @@ void Context::coverStrokePath(GLuint path, GLenum coverMode)
void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj)
return;
......@@ -1805,7 +1789,7 @@ void Context::stencilThenCoverStrokePath(GLuint path,
GLuint mask,
GLenum coverMode)
{
const auto *pathObj = mResourceManager->getPath(path);
const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj)
return;
......@@ -1823,8 +1807,7 @@ void Context::coverFillPathInstanced(GLsizei numPaths,
GLenum transformType,
const GLfloat *transformValues)
{
const auto &pathObjects =
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
......@@ -1840,8 +1823,7 @@ void Context::coverStrokePathInstanced(GLsizei numPaths,
GLenum transformType,
const GLfloat *transformValues)
{
const auto &pathObjects =
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
......@@ -1859,8 +1841,7 @@ void Context::stencilFillPathInstanced(GLsizei numPaths,
GLenum transformType,
const GLfloat *transformValues)
{
const auto &pathObjects =
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
......@@ -1878,8 +1859,7 @@ void Context::stencilStrokePathInstanced(GLsizei numPaths,
GLenum transformType,
const GLfloat *transformValues)
{
const auto &pathObjects =
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
......@@ -1898,8 +1878,7 @@ void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
GLenum transformType,
const GLfloat *transformValues)
{
const auto &pathObjects =
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
......@@ -1918,8 +1897,7 @@ void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
GLenum transformType,
const GLfloat *transformValues)
{
const auto &pathObjects =
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState();
......@@ -2224,42 +2202,42 @@ void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameteri(samplerObject, pname, param);
}
void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
{
Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameteriv(samplerObject, pname, param);
}
void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{
Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameterf(samplerObject, pname, param);
}
void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
{
Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameterfv(samplerObject, pname, param);
}
void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
{
const Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
QuerySamplerParameteriv(samplerObject, pname, params);
}
void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
{
const Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
QuerySamplerParameterfv(samplerObject, pname, params);
}
......@@ -3594,8 +3572,8 @@ void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, con
void Context::attachShader(GLuint program, GLuint shader)
{
auto programObject = mResourceManager->getProgram(program);
auto shaderObject = mResourceManager->getShader(shader);
auto programObject = mState.mShaderPrograms->getProgram(program);
auto shaderObject = mState.mShaderPrograms->getShader(shader);
ASSERT(programObject && shaderObject);
programObject->attachShader(shaderObject);
}
......@@ -3708,7 +3686,7 @@ void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
{
ASSERT(target == GL_RENDERBUFFER);
Renderbuffer *object =
mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
mGLState.setRenderbufferBinding(object);
}
......
......@@ -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.cpp: Implements the gl::ResourceManager class, which tracks and
// retrieves objects which may be shared by multiple Contexts.
// ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and
// lifetime of GL objects.
#include "libANGLE/ResourceManager.h"
......@@ -21,60 +21,71 @@
namespace gl
{
ResourceManager::ResourceManager() : mRefCount(1)
namespace
{
}
ResourceManager::~ResourceManager()
template <typename ResourceType>
GLuint AllocateEmptyObject(HandleAllocator *handleAllocator, ResourceMap<ResourceType> *objectMap)
{
while (!mBufferMap.empty())
{
deleteBuffer(mBufferMap.begin()->first);
}
GLuint handle = handleAllocator->allocate();
(*objectMap)[handle] = nullptr;
return handle;
}
while (!mProgramMap.empty())
{
deleteProgram(mProgramMap.begin()->first);
}
template <typename ResourceType, typename CreationFunction>
GLuint InsertObject(HandleAllocator *handleAllocator,
ResourceMap<ResourceType> *objectMap,
const CreationFunction &func)
{
GLuint handle = handleAllocator->allocate();
(*objectMap)[handle] = func(handle);
return handle;
}
while (!mShaderMap.empty())
template <typename ResourceType, typename DeletionFunction>
void DeleteObject(HandleAllocator *handleAllocator,
ResourceMap<ResourceType> *objectMap,
GLuint handle,
const DeletionFunction &deletionFunc)
{
auto objectIter = objectMap->find(handle);
if (objectIter == objectMap->end())
{
deleteShader(mShaderMap.begin()->first);
return;
}
while (!mRenderbufferMap.empty())
if (objectIter->second != nullptr)
{
deleteRenderbuffer(mRenderbufferMap.begin()->first);
deletionFunc(objectIter->second);
}
while (!mTextureMap.empty())
{
deleteTexture(mTextureMap.begin()->first);
}
handleAllocator->release(objectIter->first);
objectMap->erase(objectIter);
}
while (!mSamplerMap.empty())
{
deleteSampler(mSamplerMap.begin()->first);
}
template <typename ResourceType>
ResourceType *GetObject(const ResourceMap<ResourceType> &objectMap, GLuint handle)
{
auto iter = objectMap.find(handle);
return iter != objectMap.end() ? iter->second : nullptr;
}
while (!mFenceSyncMap.empty())
{
deleteFenceSync(mFenceSyncMap.begin()->first);
}
} // anonymous namespace
for (auto it = mPathMap.begin(); it != mPathMap.end(); ++it)
{
const auto *p = it->second;
delete p;
}
template <typename HandleAllocatorType>
ResourceManagerBase<HandleAllocatorType>::ResourceManagerBase() : mRefCount(1)
{
}
void ResourceManager::addRef()
template <typename HandleAllocatorType>
void ResourceManagerBase<HandleAllocatorType>::addRef()
{
mRefCount++;
}
void ResourceManager::release()
template <typename HandleAllocatorType>
void ResourceManagerBase<HandleAllocatorType>::release()
{
if (--mRefCount == 0)
{
......@@ -82,481 +93,396 @@ void ResourceManager::release()
}
}
// Returns an unused buffer name
GLuint ResourceManager::createBuffer()
{
GLuint handle = mBufferHandleAllocator.allocate();
mBufferMap[handle] = nullptr;
return handle;
}
// Returns an unused shader/program name
GLuint ResourceManager::createShader(rx::GLImplFactory *factory,
const gl::Limitations &rendererLimitations,
GLenum type)
template <typename ResourceType, typename HandleAllocatorType>
TypedResourceManager<ResourceType, HandleAllocatorType>::~TypedResourceManager()
{
ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER);
GLuint handle = mProgramShaderHandleAllocator.allocate();
mShaderMap[handle] = new Shader(this, factory, rendererLimitations, type, handle);
return handle;
while (!mObjectMap.empty())
{
deleteObject(mObjectMap.begin()->first);
}
}
// Returns an unused program/shader name
GLuint ResourceManager::createProgram(rx::GLImplFactory *factory)
template <typename ResourceType, typename HandleAllocatorType>
void TypedResourceManager<ResourceType, HandleAllocatorType>::deleteObject(GLuint handle)
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
mProgramMap[handle] = new Program(factory, this, handle);
return handle;
DeleteObject(&this->mHandleAllocator, &mObjectMap, handle,
[](ResourceType *object) { object->release(); });
}
// Returns an unused texture name
GLuint ResourceManager::createTexture()
{
GLuint handle = mTextureHandleAllocator.allocate();
mTextureMap[handle] = nullptr;
// Instantiations of ResourceManager
template class ResourceManagerBase<HandleAllocator>;
template class ResourceManagerBase<HandleRangeAllocator>;
template class TypedResourceManager<Buffer, HandleAllocator>;
template class TypedResourceManager<Texture, HandleAllocator>;
template class TypedResourceManager<Renderbuffer, HandleAllocator>;
template class TypedResourceManager<Sampler, HandleAllocator>;
template class TypedResourceManager<FenceSync, HandleAllocator>;
return handle;
}
// Returns an unused renderbuffer name
GLuint ResourceManager::createRenderbuffer()
GLuint BufferManager::createBuffer()
{
GLuint handle = mRenderbufferHandleAllocator.allocate();
mRenderbufferMap[handle] = nullptr;
return handle;
return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
}
// Returns an unused sampler name
GLuint ResourceManager::createSampler()
void BufferManager::deleteBuffer(GLuint buffer)
{
GLuint handle = mSamplerHandleAllocator.allocate();
mSamplerMap[handle] = nullptr;
return handle;
deleteObject(buffer);
}
// Returns the next unused fence name, and allocates the fence
GLuint ResourceManager::createFenceSync(rx::GLImplFactory *factory)
Buffer *BufferManager::getBuffer(GLuint handle) const
{
GLuint handle = mFenceSyncHandleAllocator.allocate();
FenceSync *fenceSync = new FenceSync(factory->createFenceSync(), handle);
fenceSync->addRef();
mFenceSyncMap[handle] = fenceSync;
return handle;
return GetObject(mObjectMap, handle);
}
ErrorOrResult<GLuint> ResourceManager::createPaths(rx::GLImplFactory *factory, GLsizei range)
Buffer *BufferManager::checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle)
{
// Allocate client side handles.
const GLuint client = mPathHandleAllocator.allocateRange(static_cast<GLuint>(range));
if (client == HandleRangeAllocator::kInvalidHandle)
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate path handle range.");
const auto &paths = factory->createPaths(range);
if (paths.empty())
if (handle == 0)
{
mPathHandleAllocator.releaseRange(client, range);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate path objects.");
return nullptr;
}
auto hint = mPathMap.begin();
auto objectMapIter = mObjectMap.find(handle);
bool handleAllocated = (objectMapIter != mObjectMap.end());
for (GLsizei i = 0; i < range; ++i)
if (handleAllocated && objectMapIter->second != nullptr)
{
const auto impl = paths[static_cast<unsigned>(i)];
const auto id = client + i;
hint = mPathMap.insert(hint, std::make_pair(id, new Path(impl)));
return objectMapIter->second;
}
return client;
}
void ResourceManager::deleteBuffer(GLuint buffer)
{
auto bufferObject = mBufferMap.find(buffer);
Buffer *object = new Buffer(factory, handle);
object->addRef();
if (bufferObject != mBufferMap.end())
if (handleAllocated)
{
mBufferHandleAllocator.release(bufferObject->first);
if (bufferObject->second) bufferObject->second->release();
mBufferMap.erase(bufferObject);
objectMapIter->second = object;
}
}
void ResourceManager::deleteShader(GLuint shader)
{
auto shaderObject = mShaderMap.find(shader);
if (shaderObject != mShaderMap.end())
else
{
if (shaderObject->second->getRefCount() == 0)
{
mProgramShaderHandleAllocator.release(shaderObject->first);
delete shaderObject->second;
mShaderMap.erase(shaderObject);
}
else
{
shaderObject->second->flagForDeletion();
}
mHandleAllocator.reserve(handle);
mObjectMap[handle] = object;
}
return object;
}
void ResourceManager::deleteProgram(GLuint program)
bool BufferManager::isBufferGenerated(GLuint buffer) const
{
auto programObject = mProgramMap.find(program);
if (programObject != mProgramMap.end())
{
if (programObject->second->getRefCount() == 0)
{
mProgramShaderHandleAllocator.release(programObject->first);
delete programObject->second;
mProgramMap.erase(programObject);
}
else
{
programObject->second->flagForDeletion();
}
}
return buffer == 0 || mObjectMap.find(buffer) != mObjectMap.end();
}
void ResourceManager::deleteTexture(GLuint texture)
ShaderProgramManager::~ShaderProgramManager()
{
auto textureObject = mTextureMap.find(texture);
if (textureObject != mTextureMap.end())
while (!mPrograms.empty())
{
mTextureHandleAllocator.release(textureObject->first);
if (textureObject->second) textureObject->second->release();
mTextureMap.erase(textureObject);
deleteProgram(mPrograms.begin()->first);
}
}
void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
{
auto renderbufferObject = mRenderbufferMap.find(renderbuffer);
if (renderbufferObject != mRenderbufferMap.end())
while (!mShaders.empty())
{
mRenderbufferHandleAllocator.release(renderbufferObject->first);
if (renderbufferObject->second) renderbufferObject->second->release();
mRenderbufferMap.erase(renderbufferObject);
deleteShader(mShaders.begin()->first);
}
}
void ResourceManager::deleteSampler(GLuint sampler)
GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
const gl::Limitations &rendererLimitations,
GLenum type)
{
auto samplerObject = mSamplerMap.find(sampler);
if (samplerObject != mSamplerMap.end())
{
mSamplerHandleAllocator.release(samplerObject->first);
if (samplerObject->second) samplerObject->second->release();
mSamplerMap.erase(samplerObject);
}
ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER);
GLuint handle = mHandleAllocator.allocate();
mShaders[handle] = new Shader(this, factory, rendererLimitations, type, handle);
return handle;
}
void ResourceManager::deleteFenceSync(GLuint fenceSync)
void ShaderProgramManager::deleteShader(GLuint shader)
{
auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
if (fenceObjectIt != mFenceSyncMap.end())
{
mFenceSyncHandleAllocator.release(fenceObjectIt->first);
if (fenceObjectIt->second) fenceObjectIt->second->release();
mFenceSyncMap.erase(fenceObjectIt);
}
deleteObject(&mShaders, shader);
}
void ResourceManager::deletePaths(GLuint first, GLsizei range)
Shader *ShaderProgramManager::getShader(GLuint handle) const
{
for (GLsizei i = 0; i < range; ++i)
{
const auto id = first + i;
const auto it = mPathMap.find(id);
if (it == mPathMap.end())
continue;
Path *p = it->second;
delete p;
mPathMap.erase(it);
}
mPathHandleAllocator.releaseRange(first, static_cast<GLuint>(range));
return GetObject(mShaders, handle);
}
Buffer *ResourceManager::getBuffer(unsigned int handle)
GLuint ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
{
auto buffer = mBufferMap.find(handle);
if (buffer == mBufferMap.end())
{
return nullptr;
}
else
{
return buffer->second;
}
GLuint handle = mHandleAllocator.allocate();
mPrograms[handle] = new Program(factory, this, handle);
return handle;
}
Shader *ResourceManager::getShader(unsigned int handle) const
void ShaderProgramManager::deleteProgram(GLuint program)
{
auto shader = mShaderMap.find(handle);
if (shader == mShaderMap.end())
{
return nullptr;
}
else
{
return shader->second;
}
deleteObject(&mPrograms, program);
}
Texture *ResourceManager::getTexture(unsigned int handle)
Program *ShaderProgramManager::getProgram(GLuint handle) const
{
if (handle == 0)
return nullptr;
auto texture = mTextureMap.find(handle);
if (texture == mTextureMap.end())
{
return nullptr;
}
else
{
return texture->second;
}
return GetObject(mPrograms, handle);
}
Program *ResourceManager::getProgram(unsigned int handle) const
template <typename ObjectType>
void ShaderProgramManager::deleteObject(ResourceMap<ObjectType> *objectMap, GLuint id)
{
auto program = mProgramMap.find(handle);
auto iter = objectMap->find(id);
if (iter == objectMap->end())
{
return;
}
if (program == mProgramMap.end())
auto object = iter->second;
if (object->getRefCount() == 0)
{
return nullptr;
mHandleAllocator.release(id);
SafeDelete(object);
objectMap->erase(iter);
}
else
{
return program->second;
object->flagForDeletion();
}
}
Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
GLuint TextureManager::createTexture()
{
auto renderbuffer = mRenderbufferMap.find(handle);
return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
}
if (renderbuffer == mRenderbufferMap.end())
{
return nullptr;
}
else
{
return renderbuffer->second;
}
void TextureManager::deleteTexture(GLuint texture)
{
deleteObject(texture);
}
Sampler *ResourceManager::getSampler(unsigned int handle)
Texture *TextureManager::getTexture(GLuint handle) const
{
auto sampler = mSamplerMap.find(handle);
ASSERT(GetObject(mObjectMap, 0) == nullptr);
return GetObject(mObjectMap, handle);
}
if (sampler == mSamplerMap.end())
Texture *TextureManager::checkTextureAllocation(rx::GLImplFactory *factory,
GLuint handle,
GLenum type)
{
if (handle == 0)
{
return nullptr;
}
else
auto objectMapIter = mObjectMap.find(handle);
bool handleAllocated = (objectMapIter != mObjectMap.end());
if (handleAllocated && objectMapIter->second != nullptr)
{
return sampler->second;
return objectMapIter->second;
}
}
FenceSync *ResourceManager::getFenceSync(unsigned int handle)
{
auto fenceObjectIt = mFenceSyncMap.find(handle);
Texture *object = new Texture(factory, handle, type);
object->addRef();
if (fenceObjectIt == mFenceSyncMap.end())
if (handleAllocated)
{
return nullptr;
objectMapIter->second = object;
}
else
{
return fenceObjectIt->second;
mHandleAllocator.reserve(handle);
mObjectMap[handle] = object;
}
return object;
}
const Path *ResourceManager::getPath(GLuint handle) const
bool TextureManager::isTextureGenerated(GLuint texture) const
{
auto it = mPathMap.find(handle);
if (it == std::end(mPathMap))
return nullptr;
return it->second;
return texture == 0 || mObjectMap.find(texture) != mObjectMap.end();
}
Path *ResourceManager::getPath(GLuint handle)
GLuint RenderbufferManager::createRenderbuffer()
{
auto it = mPathMap.find(handle);
if (it == std::end(mPathMap))
return nullptr;
return it->second;
return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
}
bool ResourceManager::hasPath(GLuint handle) const
void RenderbufferManager::deleteRenderbuffer(GLuint renderbuffer)
{
return mPathHandleAllocator.isUsed(handle);
deleteObject(renderbuffer);
}
void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
Renderbuffer *RenderbufferManager::getRenderbuffer(GLuint handle)
{
mRenderbufferMap[handle] = buffer;
return GetObject(mObjectMap, handle);
}
Buffer *ResourceManager::checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle)
Renderbuffer *RenderbufferManager::checkRenderbufferAllocation(rx::GLImplFactory *factory,
GLuint handle)
{
if (handle == 0)
{
return nullptr;
}
auto bufferMapIt = mBufferMap.find(handle);
bool handleAllocated = (bufferMapIt != mBufferMap.end());
auto objectMapIter = mObjectMap.find(handle);
bool handleAllocated = (objectMapIter != mObjectMap.end());
if (handleAllocated && bufferMapIt->second != nullptr)
if (handleAllocated && objectMapIter->second != nullptr)
{
return bufferMapIt->second;
return objectMapIter->second;
}
Buffer *buffer = new Buffer(factory, handle);
buffer->addRef();
Renderbuffer *object = new Renderbuffer(factory->createRenderbuffer(), handle);
object->addRef();
if (handleAllocated)
{
bufferMapIt->second = buffer;
objectMapIter->second = object;
}
else
{
mBufferHandleAllocator.reserve(handle);
mBufferMap[handle] = buffer;
mHandleAllocator.reserve(handle);
mObjectMap[handle] = object;
}
return buffer;
return object;
}
Texture *ResourceManager::checkTextureAllocation(rx::GLImplFactory *factory,
GLuint handle,
GLenum type)
bool RenderbufferManager::isRenderbufferGenerated(GLuint renderbuffer) const
{
return renderbuffer == 0 || mObjectMap.find(renderbuffer) != mObjectMap.end();
}
GLuint SamplerManager::createSampler()
{
return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
}
void SamplerManager::deleteSampler(GLuint sampler)
{
deleteObject(sampler);
}
Sampler *SamplerManager::getSampler(GLuint handle)
{
return GetObject(mObjectMap, handle);
}
Sampler *SamplerManager::checkSamplerAllocation(rx::GLImplFactory *factory, GLuint handle)
{
if (handle == 0)
{
return nullptr;
}
auto textureMapIt = mTextureMap.find(handle);
bool handleAllocated = (textureMapIt != mTextureMap.end());
auto objectMapIter = mObjectMap.find(handle);
bool handleAllocated = (objectMapIter != mObjectMap.end());
if (handleAllocated && textureMapIt->second != nullptr)
if (handleAllocated && objectMapIter->second != nullptr)
{
return textureMapIt->second;
return objectMapIter->second;
}
Texture *texture = new Texture(factory, handle, type);
texture->addRef();
Sampler *object = new Sampler(factory, handle);
object->addRef();
if (handleAllocated)
{
textureMapIt->second = texture;
objectMapIter->second = object;
}
else
{
mTextureHandleAllocator.reserve(handle);
mTextureMap[handle] = texture;
mHandleAllocator.reserve(handle);
mObjectMap[handle] = object;
}
return texture;
return object;
}
Renderbuffer *ResourceManager::checkRenderbufferAllocation(rx::GLImplFactory *factory,
GLuint handle)
bool SamplerManager::isSampler(GLuint sampler)
{
if (handle == 0)
return mObjectMap.find(sampler) != mObjectMap.end();
}
GLuint FenceSyncManager::createFenceSync(rx::GLImplFactory *factory)
{
struct fenceSyncAllocator
{
return nullptr;
}
fenceSyncAllocator(rx::GLImplFactory *factory) : factory(factory) {}
auto renderbufferMapIt = mRenderbufferMap.find(handle);
bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
rx::GLImplFactory *factory;
if (handleAllocated && renderbufferMapIt->second != nullptr)
{
return renderbufferMapIt->second;
}
FenceSync *operator()(GLuint handle) const
{
FenceSync *fenceSync = new FenceSync(factory->createFenceSync(), handle);
fenceSync->addRef();
return fenceSync;
}
};
Renderbuffer *renderbuffer = new Renderbuffer(factory->createRenderbuffer(), handle);
renderbuffer->addRef();
return InsertObject(&mHandleAllocator, &mObjectMap, fenceSyncAllocator(factory));
}
if (handleAllocated)
{
renderbufferMapIt->second = renderbuffer;
}
else
{
mRenderbufferHandleAllocator.reserve(handle);
mRenderbufferMap[handle] = renderbuffer;
}
void FenceSyncManager::deleteFenceSync(GLuint fenceSync)
{
deleteObject(fenceSync);
}
return renderbuffer;
FenceSync *FenceSyncManager::getFenceSync(GLuint handle)
{
return GetObject(mObjectMap, handle);
}
Sampler *ResourceManager::checkSamplerAllocation(rx::GLImplFactory *factory, GLuint samplerHandle)
ErrorOrResult<GLuint> PathManager::createPaths(rx::GLImplFactory *factory, GLsizei range)
{
// Samplers cannot be created via Bind
if (samplerHandle == 0)
// Allocate client side handles.
const GLuint client = mHandleAllocator.allocateRange(static_cast<GLuint>(range));
if (client == HandleRangeAllocator::kInvalidHandle)
return Error(GL_OUT_OF_MEMORY, "Failed to allocate path handle range.");
const auto &paths = factory->createPaths(range);
if (paths.empty())
{
return nullptr;
mHandleAllocator.releaseRange(client, range);
return Error(GL_OUT_OF_MEMORY, "Failed to allocate path objects.");
}
Sampler *sampler = getSampler(samplerHandle);
auto hint = mPaths.begin();
if (!sampler)
for (GLsizei i = 0; i < range; ++i)
{
sampler = new Sampler(factory, samplerHandle);
mSamplerMap[samplerHandle] = sampler;
sampler->addRef();
const auto impl = paths[static_cast<unsigned>(i)];
const auto id = client + i;
hint = mPaths.insert(hint, std::make_pair(id, new Path(impl)));
}
return sampler;
return client;
}
bool ResourceManager::isSampler(GLuint sampler)
void PathManager::deletePaths(GLuint first, GLsizei range)
{
return mSamplerMap.find(sampler) != mSamplerMap.end();
for (GLsizei i = 0; i < range; ++i)
{
const auto id = first + i;
const auto it = mPaths.find(id);
if (it == mPaths.end())
continue;
Path *p = it->second;
delete p;
mPaths.erase(it);
}
mHandleAllocator.releaseRange(first, static_cast<GLuint>(range));
}
bool ResourceManager::isTextureGenerated(GLuint texture) const
Path *PathManager::getPath(GLuint handle) const
{
return texture == 0 || mTextureMap.find(texture) != mTextureMap.end();
auto iter = mPaths.find(handle);
return iter != mPaths.end() ? iter->second : nullptr;
}
bool ResourceManager::isBufferGenerated(GLuint buffer) const
bool PathManager::hasPath(GLuint handle) const
{
return buffer == 0 || mBufferMap.find(buffer) != mBufferMap.end();
return mHandleAllocator.isUsed(handle);
}
bool ResourceManager::isRenderbufferGenerated(GLuint renderbuffer) const
PathManager::~PathManager()
{
return renderbuffer == 0 || mRenderbufferMap.find(renderbuffer) != mRenderbufferMap.end();
for (auto path : mPaths)
{
SafeDelete(path.second);
}
}
} // namespace gl
//
// 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