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 ...@@ -46,7 +46,7 @@ namespace
{ {
template <typename T> template <typename T>
std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager, std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
GLsizei numPaths, GLsizei numPaths,
const void *paths, const void *paths,
GLuint pathBase) GLuint pathBase)
...@@ -66,7 +66,7 @@ std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager, ...@@ -66,7 +66,7 @@ std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
return ret; return ret;
} }
std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager, std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
GLsizei numPaths, GLsizei numPaths,
GLenum pathNameType, GLenum pathNameType,
const void *paths, const void *paths,
...@@ -239,12 +239,12 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -239,12 +239,12 @@ Context::Context(rx::EGLImplFactory *implFactory,
const Context *shareContext, const Context *shareContext,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
: ValidationContext(GetClientVersion(attribs), : ValidationContext(shareContext,
GetClientVersion(attribs),
&mGLState, &mGLState,
mCaps, mCaps,
mTextureCaps, mTextureCaps,
mExtensions, mExtensions,
nullptr,
mLimitations, mLimitations,
mFramebufferMap, mFramebufferMap,
GetNoError(attribs)), GetNoError(attribs)),
...@@ -258,8 +258,7 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -258,8 +258,7 @@ Context::Context(rx::EGLImplFactory *implFactory,
mContextLostForced(false), mContextLostForced(false),
mResetStrategy(GetResetStrategy(attribs)), mResetStrategy(GetResetStrategy(attribs)),
mRobustAccess(GetRobustAccess(attribs)), mRobustAccess(GetRobustAccess(attribs)),
mCurrentSurface(nullptr), mCurrentSurface(nullptr)
mResourceManager(nullptr)
{ {
if (mRobustAccess) if (mRobustAccess)
{ {
...@@ -274,18 +273,6 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -274,18 +273,6 @@ Context::Context(rx::EGLImplFactory *implFactory,
mFenceNVHandleAllocator.setBaseHandle(0); 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: // [OpenGL ES 2.0.24] section 3.7 page 83:
// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
// and cube map texture state vectors respectively associated with them. // and cube map texture state vectors respectively associated with them.
...@@ -444,11 +431,6 @@ Context::~Context() ...@@ -444,11 +431,6 @@ Context::~Context()
releaseSurface(); releaseSurface();
} }
if (mResourceManager)
{
mResourceManager->release();
}
SafeDelete(mCompiler); SafeDelete(mCompiler);
} }
...@@ -521,39 +503,39 @@ void Context::releaseSurface() ...@@ -521,39 +503,39 @@ void Context::releaseSurface()
GLuint Context::createBuffer() GLuint Context::createBuffer()
{ {
return mResourceManager->createBuffer(); return mState.mBuffers->createBuffer();
} }
GLuint Context::createProgram() GLuint Context::createProgram()
{ {
return mResourceManager->createProgram(mImplementation.get()); return mState.mShaderPrograms->createProgram(mImplementation.get());
} }
GLuint Context::createShader(GLenum type) GLuint Context::createShader(GLenum type)
{ {
return mResourceManager->createShader(mImplementation.get(), mLimitations, type); return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
} }
GLuint Context::createTexture() GLuint Context::createTexture()
{ {
return mResourceManager->createTexture(); return mState.mTextures->createTexture();
} }
GLuint Context::createRenderbuffer() GLuint Context::createRenderbuffer()
{ {
return mResourceManager->createRenderbuffer(); return mState.mRenderbuffers->createRenderbuffer();
} }
GLsync Context::createFenceSync() 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)); return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
} }
GLuint Context::createPaths(GLsizei range) GLuint Context::createPaths(GLsizei range)
{ {
auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range); auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
if (resultOrError.isError()) if (resultOrError.isError())
{ {
handleError(resultOrError.getError()); handleError(resultOrError.getError());
...@@ -571,7 +553,7 @@ GLuint Context::createVertexArray() ...@@ -571,7 +553,7 @@ GLuint Context::createVertexArray()
GLuint Context::createSampler() GLuint Context::createSampler()
{ {
return mResourceManager->createSampler(); return mState.mSamplers->createSampler();
} }
GLuint Context::createTransformFeedback() GLuint Context::createTransformFeedback()
...@@ -612,42 +594,42 @@ GLuint Context::createQuery() ...@@ -612,42 +594,42 @@ GLuint Context::createQuery()
void Context::deleteBuffer(GLuint buffer) void Context::deleteBuffer(GLuint buffer)
{ {
if (mResourceManager->getBuffer(buffer)) if (mState.mBuffers->getBuffer(buffer))
{ {
detachBuffer(buffer); detachBuffer(buffer);
} }
mResourceManager->deleteBuffer(buffer); mState.mBuffers->deleteBuffer(buffer);
} }
void Context::deleteShader(GLuint shader) void Context::deleteShader(GLuint shader)
{ {
mResourceManager->deleteShader(shader); mState.mShaderPrograms->deleteShader(shader);
} }
void Context::deleteProgram(GLuint program) void Context::deleteProgram(GLuint program)
{ {
mResourceManager->deleteProgram(program); mState.mShaderPrograms->deleteProgram(program);
} }
void Context::deleteTexture(GLuint texture) void Context::deleteTexture(GLuint texture)
{ {
if (mResourceManager->getTexture(texture)) if (mState.mTextures->getTexture(texture))
{ {
detachTexture(texture); detachTexture(texture);
} }
mResourceManager->deleteTexture(texture); mState.mTextures->deleteTexture(texture);
} }
void Context::deleteRenderbuffer(GLuint renderbuffer) void Context::deleteRenderbuffer(GLuint renderbuffer)
{ {
if (mResourceManager->getRenderbuffer(renderbuffer)) if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
{ {
detachRenderbuffer(renderbuffer); detachRenderbuffer(renderbuffer);
} }
mResourceManager->deleteRenderbuffer(renderbuffer); mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
} }
void Context::deleteFenceSync(GLsync fenceSync) void Context::deleteFenceSync(GLsync fenceSync)
...@@ -656,17 +638,18 @@ 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, // 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 // and since our API is currently designed for being called from a single thread, we can delete
// the fence immediately. // 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) void Context::deletePaths(GLuint first, GLsizei range)
{ {
mResourceManager->deletePaths(first, range); mState.mPaths->deletePaths(first, range);
} }
bool Context::hasPathData(GLuint path) const bool Context::hasPathData(GLuint path) const
{ {
const auto *pathObj = mResourceManager->getPath(path); const auto *pathObj = mState.mPaths->getPath(path);
if (pathObj == nullptr) if (pathObj == nullptr)
return false; return false;
...@@ -675,7 +658,7 @@ bool Context::hasPathData(GLuint path) const ...@@ -675,7 +658,7 @@ bool Context::hasPathData(GLuint path) const
bool Context::hasPath(GLuint path) const bool Context::hasPath(GLuint path) const
{ {
return mResourceManager->hasPath(path); return mState.mPaths->hasPath(path);
} }
void Context::setPathCommands(GLuint path, void Context::setPathCommands(GLuint path,
...@@ -685,14 +668,14 @@ void Context::setPathCommands(GLuint path, ...@@ -685,14 +668,14 @@ void Context::setPathCommands(GLuint path,
GLenum coordType, GLenum coordType,
const void *coords) const void *coords)
{ {
auto *pathObject = mResourceManager->getPath(path); auto *pathObject = mState.mPaths->getPath(path);
handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords)); handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
} }
void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value) void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
{ {
auto *pathObj = mResourceManager->getPath(path); auto *pathObj = mState.mPaths->getPath(path);
switch (pname) switch (pname)
{ {
...@@ -719,7 +702,7 @@ void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value) ...@@ -719,7 +702,7 @@ void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const 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) switch (pname)
{ {
...@@ -768,12 +751,12 @@ void Context::deleteVertexArray(GLuint vertexArray) ...@@ -768,12 +751,12 @@ void Context::deleteVertexArray(GLuint vertexArray)
void Context::deleteSampler(GLuint sampler) void Context::deleteSampler(GLuint sampler)
{ {
if (mResourceManager->getSampler(sampler)) if (mState.mSamplers->getSampler(sampler))
{ {
detachSampler(sampler); detachSampler(sampler);
} }
mResourceManager->deleteSampler(sampler); mState.mSamplers->deleteSampler(sampler);
} }
void Context::deleteTransformFeedback(GLuint transformFeedback) void Context::deleteTransformFeedback(GLuint transformFeedback)
...@@ -835,22 +818,23 @@ void Context::deleteQuery(GLuint query) ...@@ -835,22 +818,23 @@ void Context::deleteQuery(GLuint query)
Buffer *Context::getBuffer(GLuint handle) const Buffer *Context::getBuffer(GLuint handle) const
{ {
return mResourceManager->getBuffer(handle); return mState.mBuffers->getBuffer(handle);
} }
Texture *Context::getTexture(GLuint handle) const Texture *Context::getTexture(GLuint handle) const
{ {
return mResourceManager->getTexture(handle); return mState.mTextures->getTexture(handle);
} }
Renderbuffer *Context::getRenderbuffer(GLuint handle) const Renderbuffer *Context::getRenderbuffer(GLuint handle) const
{ {
return mResourceManager->getRenderbuffer(handle); return mState.mRenderbuffers->getRenderbuffer(handle);
} }
FenceSync *Context::getFenceSync(GLsync handle) const 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 VertexArray *Context::getVertexArray(GLuint handle) const
...@@ -861,7 +845,7 @@ VertexArray *Context::getVertexArray(GLuint handle) const ...@@ -861,7 +845,7 @@ VertexArray *Context::getVertexArray(GLuint handle) const
Sampler *Context::getSampler(GLuint handle) const Sampler *Context::getSampler(GLuint handle) const
{ {
return mResourceManager->getSampler(handle); return mState.mSamplers->getSampler(handle);
} }
TransformFeedback *Context::getTransformFeedback(GLuint handle) const TransformFeedback *Context::getTransformFeedback(GLuint handle) const
...@@ -950,24 +934,24 @@ void Context::getObjectPtrLabel(const void *ptr, ...@@ -950,24 +934,24 @@ void Context::getObjectPtrLabel(const void *ptr,
bool Context::isSampler(GLuint samplerName) const bool Context::isSampler(GLuint samplerName) const
{ {
return mResourceManager->isSampler(samplerName); return mState.mSamplers->isSampler(samplerName);
} }
void Context::bindArrayBuffer(GLuint bufferHandle) void Context::bindArrayBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setArrayBufferBinding(buffer); mGLState.setArrayBufferBinding(buffer);
} }
void Context::bindDrawIndirectBuffer(GLuint bufferHandle) void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setDrawIndirectBufferBinding(buffer); mGLState.setDrawIndirectBufferBinding(buffer);
} }
void Context::bindElementArrayBuffer(GLuint bufferHandle) void Context::bindElementArrayBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.getVertexArray()->setElementArrayBuffer(buffer); mGLState.getVertexArray()->setElementArrayBuffer(buffer);
} }
...@@ -981,7 +965,7 @@ void Context::bindTexture(GLenum target, GLuint handle) ...@@ -981,7 +965,7 @@ void Context::bindTexture(GLenum target, GLuint handle)
} }
else else
{ {
texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target); texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
} }
ASSERT(texture); ASSERT(texture);
...@@ -1010,13 +994,13 @@ void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle) ...@@ -1010,13 +994,13 @@ void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
{ {
ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits); ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Sampler *sampler = Sampler *sampler =
mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle); mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
mGLState.setSamplerBinding(textureUnit, sampler); mGLState.setSamplerBinding(textureUnit, sampler);
} }
void Context::bindGenericUniformBuffer(GLuint bufferHandle) void Context::bindGenericUniformBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setGenericUniformBufferBinding(buffer); mGLState.setGenericUniformBufferBinding(buffer);
} }
...@@ -1025,13 +1009,13 @@ void Context::bindIndexedUniformBuffer(GLuint bufferHandle, ...@@ -1025,13 +1009,13 @@ void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
GLintptr offset, GLintptr offset,
GLsizeiptr size) GLsizeiptr size)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size); mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
} }
void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle) void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer); mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
} }
...@@ -1040,31 +1024,31 @@ void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle, ...@@ -1040,31 +1024,31 @@ void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
GLintptr offset, GLintptr offset,
GLsizeiptr size) GLsizeiptr size)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size); mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
} }
void Context::bindCopyReadBuffer(GLuint bufferHandle) void Context::bindCopyReadBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setCopyReadBufferBinding(buffer); mGLState.setCopyReadBufferBinding(buffer);
} }
void Context::bindCopyWriteBuffer(GLuint bufferHandle) void Context::bindCopyWriteBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setCopyWriteBufferBinding(buffer); mGLState.setCopyWriteBufferBinding(buffer);
} }
void Context::bindPixelPackBuffer(GLuint bufferHandle) void Context::bindPixelPackBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setPixelPackBufferBinding(buffer); mGLState.setPixelPackBufferBinding(buffer);
} }
void Context::bindPixelUnpackBuffer(GLuint bufferHandle) void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
{ {
Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle); Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
mGLState.setPixelUnpackBufferBinding(buffer); mGLState.setPixelUnpackBufferBinding(buffer);
} }
...@@ -1742,7 +1726,7 @@ void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode) ...@@ -1742,7 +1726,7 @@ void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask) void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
{ {
const auto *pathObj = mResourceManager->getPath(path); const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj) if (!pathObj)
return; return;
...@@ -1754,7 +1738,7 @@ void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask) ...@@ -1754,7 +1738,7 @@ void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
void Context::stencilStrokePath(GLuint path, GLint reference, 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) if (!pathObj)
return; return;
...@@ -1766,7 +1750,7 @@ void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask) ...@@ -1766,7 +1750,7 @@ void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
void Context::coverFillPath(GLuint path, GLenum coverMode) void Context::coverFillPath(GLuint path, GLenum coverMode)
{ {
const auto *pathObj = mResourceManager->getPath(path); const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj) if (!pathObj)
return; return;
...@@ -1778,7 +1762,7 @@ void Context::coverFillPath(GLuint path, GLenum coverMode) ...@@ -1778,7 +1762,7 @@ void Context::coverFillPath(GLuint path, GLenum coverMode)
void Context::coverStrokePath(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) if (!pathObj)
return; return;
...@@ -1790,7 +1774,7 @@ void Context::coverStrokePath(GLuint path, GLenum coverMode) ...@@ -1790,7 +1774,7 @@ void Context::coverStrokePath(GLuint path, GLenum coverMode)
void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, 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) if (!pathObj)
return; return;
...@@ -1805,7 +1789,7 @@ void Context::stencilThenCoverStrokePath(GLuint path, ...@@ -1805,7 +1789,7 @@ void Context::stencilThenCoverStrokePath(GLuint path,
GLuint mask, GLuint mask,
GLenum coverMode) GLenum coverMode)
{ {
const auto *pathObj = mResourceManager->getPath(path); const auto *pathObj = mState.mPaths->getPath(path);
if (!pathObj) if (!pathObj)
return; return;
...@@ -1823,8 +1807,7 @@ void Context::coverFillPathInstanced(GLsizei numPaths, ...@@ -1823,8 +1807,7 @@ void Context::coverFillPathInstanced(GLsizei numPaths,
GLenum transformType, GLenum transformType,
const GLfloat *transformValues) const GLfloat *transformValues)
{ {
const auto &pathObjects = const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState(); syncRendererState();
...@@ -1840,8 +1823,7 @@ void Context::coverStrokePathInstanced(GLsizei numPaths, ...@@ -1840,8 +1823,7 @@ void Context::coverStrokePathInstanced(GLsizei numPaths,
GLenum transformType, GLenum transformType,
const GLfloat *transformValues) const GLfloat *transformValues)
{ {
const auto &pathObjects = const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState(); syncRendererState();
...@@ -1859,8 +1841,7 @@ void Context::stencilFillPathInstanced(GLsizei numPaths, ...@@ -1859,8 +1841,7 @@ void Context::stencilFillPathInstanced(GLsizei numPaths,
GLenum transformType, GLenum transformType,
const GLfloat *transformValues) const GLfloat *transformValues)
{ {
const auto &pathObjects = const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState(); syncRendererState();
...@@ -1878,8 +1859,7 @@ void Context::stencilStrokePathInstanced(GLsizei numPaths, ...@@ -1878,8 +1859,7 @@ void Context::stencilStrokePathInstanced(GLsizei numPaths,
GLenum transformType, GLenum transformType,
const GLfloat *transformValues) const GLfloat *transformValues)
{ {
const auto &pathObjects = const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState(); syncRendererState();
...@@ -1898,8 +1878,7 @@ void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths, ...@@ -1898,8 +1878,7 @@ void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
GLenum transformType, GLenum transformType,
const GLfloat *transformValues) const GLfloat *transformValues)
{ {
const auto &pathObjects = const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState(); syncRendererState();
...@@ -1918,8 +1897,7 @@ void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths, ...@@ -1918,8 +1897,7 @@ void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
GLenum transformType, GLenum transformType,
const GLfloat *transformValues) const GLfloat *transformValues)
{ {
const auto &pathObjects = const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
// TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
syncRendererState(); syncRendererState();
...@@ -2224,42 +2202,42 @@ void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) ...@@ -2224,42 +2202,42 @@ void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
{ {
Sampler *samplerObject = Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler); mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameteri(samplerObject, pname, param); SetSamplerParameteri(samplerObject, pname, param);
} }
void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param) void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
{ {
Sampler *samplerObject = Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler); mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameteriv(samplerObject, pname, param); SetSamplerParameteriv(samplerObject, pname, param);
} }
void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param) void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{ {
Sampler *samplerObject = Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler); mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameterf(samplerObject, pname, param); SetSamplerParameterf(samplerObject, pname, param);
} }
void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param) void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
{ {
Sampler *samplerObject = Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler); mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
SetSamplerParameterfv(samplerObject, pname, param); SetSamplerParameterfv(samplerObject, pname, param);
} }
void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
{ {
const Sampler *samplerObject = const Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler); mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
QuerySamplerParameteriv(samplerObject, pname, params); QuerySamplerParameteriv(samplerObject, pname, params);
} }
void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
{ {
const Sampler *samplerObject = const Sampler *samplerObject =
mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler); mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
QuerySamplerParameterfv(samplerObject, pname, params); QuerySamplerParameterfv(samplerObject, pname, params);
} }
...@@ -3594,8 +3572,8 @@ void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, con ...@@ -3594,8 +3572,8 @@ void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, con
void Context::attachShader(GLuint program, GLuint shader) void Context::attachShader(GLuint program, GLuint shader)
{ {
auto programObject = mResourceManager->getProgram(program); auto programObject = mState.mShaderPrograms->getProgram(program);
auto shaderObject = mResourceManager->getShader(shader); auto shaderObject = mState.mShaderPrograms->getShader(shader);
ASSERT(programObject && shaderObject); ASSERT(programObject && shaderObject);
programObject->attachShader(shaderObject); programObject->attachShader(shaderObject);
} }
...@@ -3708,7 +3686,7 @@ void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer) ...@@ -3708,7 +3686,7 @@ void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
{ {
ASSERT(target == GL_RENDERBUFFER); ASSERT(target == GL_RENDERBUFFER);
Renderbuffer *object = Renderbuffer *object =
mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer); mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
mGLState.setRenderbufferBinding(object); mGLState.setRenderbufferBinding(object);
} }
......
...@@ -49,7 +49,6 @@ class Renderbuffer; ...@@ -49,7 +49,6 @@ class Renderbuffer;
class FenceNV; class FenceNV;
class FenceSync; class FenceSync;
class Query; class Query;
class ResourceManager;
class Buffer; class Buffer;
struct VertexAttribute; struct VertexAttribute;
class VertexArray; class VertexArray;
...@@ -704,8 +703,6 @@ class Context final : public ValidationContext ...@@ -704,8 +703,6 @@ class Context final : public ValidationContext
bool mRobustAccess; bool mRobustAccess;
egl::Surface *mCurrentSurface; egl::Surface *mCurrentSurface;
ResourceManager *mResourceManager;
State::DirtyBits mTexImageDirtyBits; State::DirtyBits mTexImageDirtyBits;
State::DirtyObjects mTexImageDirtyObjects; State::DirtyObjects mTexImageDirtyObjects;
State::DirtyBits mReadPixelsDirtyBits; State::DirtyBits mReadPixelsDirtyBits;
......
...@@ -14,13 +14,37 @@ ...@@ -14,13 +14,37 @@
namespace gl 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, ContextState::ContextState(uintptr_t contextIn,
const ContextState *shareContextState,
const Version &clientVersion, const Version &clientVersion,
State *stateIn, State *stateIn,
const Caps &capsIn, const Caps &capsIn,
const TextureCapsMap &textureCapsIn, const TextureCapsMap &textureCapsIn,
const Extensions &extensionsIn, const Extensions &extensionsIn,
const ResourceManager *resourceManagerIn,
const Limitations &limitationsIn, const Limitations &limitationsIn,
const ResourceMap<Framebuffer> &framebufferMap) const ResourceMap<Framebuffer> &framebufferMap)
: mClientVersion(clientVersion), : mClientVersion(clientVersion),
...@@ -29,14 +53,30 @@ ContextState::ContextState(uintptr_t contextIn, ...@@ -29,14 +53,30 @@ ContextState::ContextState(uintptr_t contextIn,
mCaps(capsIn), mCaps(capsIn),
mTextureCaps(textureCapsIn), mTextureCaps(textureCapsIn),
mExtensions(extensionsIn), mExtensions(extensionsIn),
mResourceManager(resourceManagerIn),
mLimitations(limitationsIn), 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() ContextState::~ContextState()
{ {
mBuffers->release();
mShaderPrograms->release();
mTextures->release();
mRenderbuffers->release();
mSamplers->release();
mFenceSyncs->release();
mPaths->release();
} }
const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
...@@ -44,22 +84,22 @@ const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const ...@@ -44,22 +84,22 @@ const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
return mTextureCaps.get(internalFormat); return mTextureCaps.get(internalFormat);
} }
ValidationContext::ValidationContext(const Version &clientVersion, ValidationContext::ValidationContext(const ValidationContext *shareContext,
const Version &clientVersion,
State *state, State *state,
const Caps &caps, const Caps &caps,
const TextureCapsMap &textureCaps, const TextureCapsMap &textureCaps,
const Extensions &extensions, const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations, const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap, const ResourceMap<Framebuffer> &framebufferMap,
bool skipValidation) bool skipValidation)
: mState(reinterpret_cast<uintptr_t>(this), : mState(reinterpret_cast<uintptr_t>(this),
shareContext ? &shareContext->mState : nullptr,
clientVersion, clientVersion,
state, state,
caps, caps,
textureCaps, textureCaps,
extensions, extensions,
resourceManager,
limitations, limitations,
framebufferMap), framebufferMap),
mSkipValidation(skipValidation) mSkipValidation(skipValidation)
...@@ -598,27 +638,27 @@ bool ValidationContext::getIndexedQueryParameterInfo(GLenum target, ...@@ -598,27 +638,27 @@ bool ValidationContext::getIndexedQueryParameterInfo(GLenum target,
Program *ValidationContext::getProgram(GLuint handle) const Program *ValidationContext::getProgram(GLuint handle) const
{ {
return mState.mResourceManager->getProgram(handle); return mState.mShaderPrograms->getProgram(handle);
} }
Shader *ValidationContext::getShader(GLuint handle) const Shader *ValidationContext::getShader(GLuint handle) const
{ {
return mState.mResourceManager->getShader(handle); return mState.mShaderPrograms->getShader(handle);
} }
bool ValidationContext::isTextureGenerated(GLuint texture) const bool ValidationContext::isTextureGenerated(GLuint texture) const
{ {
return mState.mResourceManager->isTextureGenerated(texture); return mState.mTextures->isTextureGenerated(texture);
} }
bool ValidationContext::isBufferGenerated(GLuint buffer) const bool ValidationContext::isBufferGenerated(GLuint buffer) const
{ {
return mState.mResourceManager->isBufferGenerated(buffer); return mState.mBuffers->isBufferGenerated(buffer);
} }
bool ValidationContext::isRenderbufferGenerated(GLuint renderbuffer) const bool ValidationContext::isRenderbufferGenerated(GLuint renderbuffer) const
{ {
return mState.mResourceManager->isRenderbufferGenerated(renderbuffer); return mState.mRenderbuffers->isRenderbufferGenerated(renderbuffer);
} }
bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const
......
...@@ -15,8 +15,15 @@ ...@@ -15,8 +15,15 @@
namespace gl namespace gl
{ {
class ValidationContext; class BufferManager;
class ContextState; 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_2_0 = Version(2, 0);
static constexpr Version ES_3_0 = Version(3, 0); static constexpr Version ES_3_0 = Version(3, 0);
...@@ -26,12 +33,12 @@ class ContextState final : public angle::NonCopyable ...@@ -26,12 +33,12 @@ class ContextState final : public angle::NonCopyable
{ {
public: public:
ContextState(uintptr_t context, ContextState(uintptr_t context,
const ContextState *shareContextState,
const Version &clientVersion, const Version &clientVersion,
State *state, State *state,
const Caps &caps, const Caps &caps,
const TextureCapsMap &textureCaps, const TextureCapsMap &textureCaps,
const Extensions &extensions, const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations, const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap); const ResourceMap<Framebuffer> &framebufferMap);
~ContextState(); ~ContextState();
...@@ -44,7 +51,6 @@ class ContextState final : public angle::NonCopyable ...@@ -44,7 +51,6 @@ class ContextState final : public angle::NonCopyable
const Caps &getCaps() const { return mCaps; } const Caps &getCaps() const { return mCaps; }
const TextureCapsMap &getTextureCaps() const { return mTextureCaps; } const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
const Extensions &getExtensions() const { return mExtensions; } const Extensions &getExtensions() const { return mExtensions; }
const ResourceManager &getResourceManager() const { return *mResourceManager; }
const Limitations &getLimitations() const { return mLimitations; } const Limitations &getLimitations() const { return mLimitations; }
const TextureCaps &getTextureCap(GLenum internalFormat) const; const TextureCaps &getTextureCap(GLenum internalFormat) const;
...@@ -59,20 +65,27 @@ class ContextState final : public angle::NonCopyable ...@@ -59,20 +65,27 @@ class ContextState final : public angle::NonCopyable
const Caps &mCaps; const Caps &mCaps;
const TextureCapsMap &mTextureCaps; const TextureCapsMap &mTextureCaps;
const Extensions &mExtensions; const Extensions &mExtensions;
const ResourceManager *mResourceManager;
const Limitations &mLimitations; const Limitations &mLimitations;
const ResourceMap<Framebuffer> &mFramebufferMap; const ResourceMap<Framebuffer> &mFramebufferMap;
BufferManager *mBuffers;
ShaderProgramManager *mShaderPrograms;
TextureManager *mTextures;
RenderbufferManager *mRenderbuffers;
SamplerManager *mSamplers;
FenceSyncManager *mFenceSyncs;
PathManager *mPaths;
}; };
class ValidationContext : angle::NonCopyable class ValidationContext : angle::NonCopyable
{ {
public: public:
ValidationContext(const Version &clientVersion, ValidationContext(const ValidationContext *shareContext,
const Version &clientVersion,
State *state, State *state,
const Caps &caps, const Caps &caps,
const TextureCapsMap &textureCaps, const TextureCapsMap &textureCaps,
const Extensions &extensions, const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations, const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap, const ResourceMap<Framebuffer> &framebufferMap,
bool skipValidation); bool skipValidation);
......
...@@ -380,7 +380,7 @@ GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const ...@@ -380,7 +380,7 @@ GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
return uniformIndex - mSamplerUniformRange.start; 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)), : mProgram(factory->createProgram(mState)),
mValidated(false), mValidated(false),
mLinked(false), mLinked(false),
......
...@@ -42,8 +42,8 @@ namespace gl ...@@ -42,8 +42,8 @@ namespace gl
struct Caps; struct Caps;
class Context; class Context;
class ContextState; class ContextState;
class ResourceManager;
class Shader; class Shader;
class ShaderProgramManager;
class InfoLog; class InfoLog;
class Buffer; class Buffer;
class Framebuffer; class Framebuffer;
...@@ -261,7 +261,7 @@ class ProgramState final : angle::NonCopyable ...@@ -261,7 +261,7 @@ class ProgramState final : angle::NonCopyable
class Program final : angle::NonCopyable, public LabeledObject class Program final : angle::NonCopyable, public LabeledObject
{ {
public: public:
Program(rx::GLImplFactory *factory, ResourceManager *manager, GLuint handle); Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle);
~Program(); ~Program();
GLuint id() const { return mHandle; } GLuint id() const { return mHandle; }
...@@ -543,7 +543,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -543,7 +543,7 @@ class Program final : angle::NonCopyable, public LabeledObject
unsigned int mRefCount; unsigned int mRefCount;
ResourceManager *mResourceManager; ShaderProgramManager *mResourceManager;
const GLuint mHandle; const GLuint mHandle;
InfoLog mInfoLog; 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and // ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and
// retrieves objects which may be shared by multiple Contexts. // lifetime of GL objects.
#include "libANGLE/ResourceManager.h" #include "libANGLE/ResourceManager.h"
...@@ -21,60 +21,71 @@ ...@@ -21,60 +21,71 @@
namespace gl namespace gl
{ {
ResourceManager::ResourceManager() : mRefCount(1)
namespace
{ {
}
ResourceManager::~ResourceManager() template <typename ResourceType>
GLuint AllocateEmptyObject(HandleAllocator *handleAllocator, ResourceMap<ResourceType> *objectMap)
{ {
while (!mBufferMap.empty()) GLuint handle = handleAllocator->allocate();
{ (*objectMap)[handle] = nullptr;
deleteBuffer(mBufferMap.begin()->first); return handle;
} }
while (!mProgramMap.empty()) template <typename ResourceType, typename CreationFunction>
{ GLuint InsertObject(HandleAllocator *handleAllocator,
deleteProgram(mProgramMap.begin()->first); 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()) handleAllocator->release(objectIter->first);
{ objectMap->erase(objectIter);
deleteTexture(mTextureMap.begin()->first); }
}
while (!mSamplerMap.empty()) template <typename ResourceType>
{ ResourceType *GetObject(const ResourceMap<ResourceType> &objectMap, GLuint handle)
deleteSampler(mSamplerMap.begin()->first); {
} auto iter = objectMap.find(handle);
return iter != objectMap.end() ? iter->second : nullptr;
}
while (!mFenceSyncMap.empty()) } // anonymous namespace
{
deleteFenceSync(mFenceSyncMap.begin()->first);
}
for (auto it = mPathMap.begin(); it != mPathMap.end(); ++it) template <typename HandleAllocatorType>
{ ResourceManagerBase<HandleAllocatorType>::ResourceManagerBase() : mRefCount(1)
const auto *p = it->second; {
delete p;
}
} }
void ResourceManager::addRef() template <typename HandleAllocatorType>
void ResourceManagerBase<HandleAllocatorType>::addRef()
{ {
mRefCount++; mRefCount++;
} }
void ResourceManager::release() template <typename HandleAllocatorType>
void ResourceManagerBase<HandleAllocatorType>::release()
{ {
if (--mRefCount == 0) if (--mRefCount == 0)
{ {
...@@ -82,481 +93,396 @@ void ResourceManager::release() ...@@ -82,481 +93,396 @@ void ResourceManager::release()
} }
} }
// Returns an unused buffer name template <typename ResourceType, typename HandleAllocatorType>
GLuint ResourceManager::createBuffer() TypedResourceManager<ResourceType, HandleAllocatorType>::~TypedResourceManager()
{ {
GLuint handle = mBufferHandleAllocator.allocate(); while (!mObjectMap.empty())
{
mBufferMap[handle] = nullptr; deleteObject(mObjectMap.begin()->first);
}
return handle;
} }
// Returns an unused shader/program name template <typename ResourceType, typename HandleAllocatorType>
GLuint ResourceManager::createShader(rx::GLImplFactory *factory, void TypedResourceManager<ResourceType, HandleAllocatorType>::deleteObject(GLuint handle)
const gl::Limitations &rendererLimitations,
GLenum type)
{ {
ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER); DeleteObject(&this->mHandleAllocator, &mObjectMap, handle,
GLuint handle = mProgramShaderHandleAllocator.allocate(); [](ResourceType *object) { object->release(); });
mShaderMap[handle] = new Shader(this, factory, rendererLimitations, type, handle);
return handle;
} }
// Returns an unused program/shader name // Instantiations of ResourceManager
GLuint ResourceManager::createProgram(rx::GLImplFactory *factory) template class ResourceManagerBase<HandleAllocator>;
{ template class ResourceManagerBase<HandleRangeAllocator>;
GLuint handle = mProgramShaderHandleAllocator.allocate(); 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>;
mProgramMap[handle] = new Program(factory, this, handle); GLuint BufferManager::createBuffer()
return handle;
}
// Returns an unused texture name
GLuint ResourceManager::createTexture()
{ {
GLuint handle = mTextureHandleAllocator.allocate(); return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
mTextureMap[handle] = nullptr;
return handle;
} }
// Returns an unused renderbuffer name void BufferManager::deleteBuffer(GLuint buffer)
GLuint ResourceManager::createRenderbuffer()
{ {
GLuint handle = mRenderbufferHandleAllocator.allocate(); deleteObject(buffer);
mRenderbufferMap[handle] = nullptr;
return handle;
} }
// Returns an unused sampler name Buffer *BufferManager::getBuffer(GLuint handle) const
GLuint ResourceManager::createSampler()
{ {
GLuint handle = mSamplerHandleAllocator.allocate(); return GetObject(mObjectMap, handle);
mSamplerMap[handle] = nullptr;
return handle;
} }
// Returns the next unused fence name, and allocates the fence Buffer *BufferManager::checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle)
GLuint ResourceManager::createFenceSync(rx::GLImplFactory *factory)
{ {
GLuint handle = mFenceSyncHandleAllocator.allocate(); if (handle == 0)
FenceSync *fenceSync = new FenceSync(factory->createFenceSync(), handle);
fenceSync->addRef();
mFenceSyncMap[handle] = fenceSync;
return handle;
}
ErrorOrResult<GLuint> ResourceManager::createPaths(rx::GLImplFactory *factory, GLsizei range)
{
// 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())
{
mPathHandleAllocator.releaseRange(client, range);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate path objects.");
}
auto hint = mPathMap.begin();
for (GLsizei i = 0; i < range; ++i)
{ {
const auto impl = paths[static_cast<unsigned>(i)]; return nullptr;
const auto id = client + i;
hint = mPathMap.insert(hint, std::make_pair(id, new Path(impl)));
} }
return client;
}
void ResourceManager::deleteBuffer(GLuint buffer) auto objectMapIter = mObjectMap.find(handle);
{ bool handleAllocated = (objectMapIter != mObjectMap.end());
auto bufferObject = mBufferMap.find(buffer);
if (bufferObject != mBufferMap.end()) if (handleAllocated && objectMapIter->second != nullptr)
{ {
mBufferHandleAllocator.release(bufferObject->first); return objectMapIter->second;
if (bufferObject->second) bufferObject->second->release();
mBufferMap.erase(bufferObject);
} }
}
void ResourceManager::deleteShader(GLuint shader) Buffer *object = new Buffer(factory, handle);
{ object->addRef();
auto shaderObject = mShaderMap.find(shader);
if (shaderObject != mShaderMap.end()) if (handleAllocated)
{
if (shaderObject->second->getRefCount() == 0)
{ {
mProgramShaderHandleAllocator.release(shaderObject->first); objectMapIter->second = object;
delete shaderObject->second;
mShaderMap.erase(shaderObject);
} }
else 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); return buffer == 0 || mObjectMap.find(buffer) != mObjectMap.end();
}
if (programObject != mProgramMap.end()) ShaderProgramManager::~ShaderProgramManager()
{ {
if (programObject->second->getRefCount() == 0) while (!mPrograms.empty())
{ {
mProgramShaderHandleAllocator.release(programObject->first); deleteProgram(mPrograms.begin()->first);
delete programObject->second;
mProgramMap.erase(programObject);
} }
else while (!mShaders.empty())
{ {
programObject->second->flagForDeletion(); deleteShader(mShaders.begin()->first);
}
} }
} }
void ResourceManager::deleteTexture(GLuint texture) GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
const gl::Limitations &rendererLimitations,
GLenum type)
{ {
auto textureObject = mTextureMap.find(texture); ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER);
GLuint handle = mHandleAllocator.allocate();
if (textureObject != mTextureMap.end()) mShaders[handle] = new Shader(this, factory, rendererLimitations, type, handle);
{ return handle;
mTextureHandleAllocator.release(textureObject->first);
if (textureObject->second) textureObject->second->release();
mTextureMap.erase(textureObject);
}
} }
void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) void ShaderProgramManager::deleteShader(GLuint shader)
{ {
auto renderbufferObject = mRenderbufferMap.find(renderbuffer); deleteObject(&mShaders, shader);
if (renderbufferObject != mRenderbufferMap.end())
{
mRenderbufferHandleAllocator.release(renderbufferObject->first);
if (renderbufferObject->second) renderbufferObject->second->release();
mRenderbufferMap.erase(renderbufferObject);
}
} }
void ResourceManager::deleteSampler(GLuint sampler) Shader *ShaderProgramManager::getShader(GLuint handle) const
{ {
auto samplerObject = mSamplerMap.find(sampler); return GetObject(mShaders, handle);
if (samplerObject != mSamplerMap.end())
{
mSamplerHandleAllocator.release(samplerObject->first);
if (samplerObject->second) samplerObject->second->release();
mSamplerMap.erase(samplerObject);
}
} }
void ResourceManager::deleteFenceSync(GLuint fenceSync) GLuint ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
{ {
auto fenceObjectIt = mFenceSyncMap.find(fenceSync); GLuint handle = mHandleAllocator.allocate();
mPrograms[handle] = new Program(factory, this, handle);
if (fenceObjectIt != mFenceSyncMap.end()) return handle;
{
mFenceSyncHandleAllocator.release(fenceObjectIt->first);
if (fenceObjectIt->second) fenceObjectIt->second->release();
mFenceSyncMap.erase(fenceObjectIt);
}
} }
void ResourceManager::deletePaths(GLuint first, GLsizei range) void ShaderProgramManager::deleteProgram(GLuint program)
{ {
for (GLsizei i = 0; i < range; ++i) deleteObject(&mPrograms, program);
{
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));
} }
Buffer *ResourceManager::getBuffer(unsigned int handle) Program *ShaderProgramManager::getProgram(GLuint handle) const
{ {
auto buffer = mBufferMap.find(handle); return GetObject(mPrograms, handle);
if (buffer == mBufferMap.end())
{
return nullptr;
}
else
{
return buffer->second;
}
} }
Shader *ResourceManager::getShader(unsigned int handle) const template <typename ObjectType>
void ShaderProgramManager::deleteObject(ResourceMap<ObjectType> *objectMap, GLuint id)
{ {
auto shader = mShaderMap.find(handle); auto iter = objectMap->find(id);
if (iter == objectMap->end())
if (shader == mShaderMap.end())
{ {
return nullptr; return;
} }
else
{
return shader->second;
}
}
Texture *ResourceManager::getTexture(unsigned int handle)
{
if (handle == 0)
return nullptr;
auto texture = mTextureMap.find(handle); auto object = iter->second;
if (object->getRefCount() == 0)
if (texture == mTextureMap.end())
{ {
return nullptr; mHandleAllocator.release(id);
SafeDelete(object);
objectMap->erase(iter);
} }
else else
{ {
return texture->second; object->flagForDeletion();
} }
} }
Program *ResourceManager::getProgram(unsigned int handle) const GLuint TextureManager::createTexture()
{ {
auto program = mProgramMap.find(handle); return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
if (program == mProgramMap.end())
{
return nullptr;
}
else
{
return program->second;
}
} }
Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) void TextureManager::deleteTexture(GLuint texture)
{ {
auto renderbuffer = mRenderbufferMap.find(handle); deleteObject(texture);
if (renderbuffer == mRenderbufferMap.end())
{
return nullptr;
}
else
{
return renderbuffer->second;
}
} }
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; 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) Texture *object = new Texture(factory, handle, type);
{ object->addRef();
auto fenceObjectIt = mFenceSyncMap.find(handle);
if (fenceObjectIt == mFenceSyncMap.end()) if (handleAllocated)
{ {
return nullptr; objectMapIter->second = object;
} }
else 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); return texture == 0 || mObjectMap.find(texture) != mObjectMap.end();
if (it == std::end(mPathMap))
return nullptr;
return it->second;
} }
Path *ResourceManager::getPath(GLuint handle) GLuint RenderbufferManager::createRenderbuffer()
{ {
auto it = mPathMap.find(handle); return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
if (it == std::end(mPathMap))
return nullptr;
return it->second;
} }
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) if (handle == 0)
{ {
return nullptr; return nullptr;
} }
auto bufferMapIt = mBufferMap.find(handle); auto objectMapIter = mObjectMap.find(handle);
bool handleAllocated = (bufferMapIt != mBufferMap.end()); 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); Renderbuffer *object = new Renderbuffer(factory->createRenderbuffer(), handle);
buffer->addRef(); object->addRef();
if (handleAllocated) if (handleAllocated)
{ {
bufferMapIt->second = buffer; objectMapIter->second = object;
} }
else else
{ {
mBufferHandleAllocator.reserve(handle); mHandleAllocator.reserve(handle);
mBufferMap[handle] = buffer; mObjectMap[handle] = object;
} }
return buffer; return object;
} }
Texture *ResourceManager::checkTextureAllocation(rx::GLImplFactory *factory, bool RenderbufferManager::isRenderbufferGenerated(GLuint renderbuffer) const
GLuint handle, {
GLenum type) 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) if (handle == 0)
{ {
return nullptr; return nullptr;
} }
auto textureMapIt = mTextureMap.find(handle); auto objectMapIter = mObjectMap.find(handle);
bool handleAllocated = (textureMapIt != mTextureMap.end()); 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); Sampler *object = new Sampler(factory, handle);
texture->addRef(); object->addRef();
if (handleAllocated) if (handleAllocated)
{ {
textureMapIt->second = texture; objectMapIter->second = object;
} }
else else
{ {
mTextureHandleAllocator.reserve(handle); mHandleAllocator.reserve(handle);
mTextureMap[handle] = texture; mObjectMap[handle] = object;
} }
return texture; return object;
} }
Renderbuffer *ResourceManager::checkRenderbufferAllocation(rx::GLImplFactory *factory, bool SamplerManager::isSampler(GLuint sampler)
GLuint handle)
{ {
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); rx::GLImplFactory *factory;
bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
if (handleAllocated && renderbufferMapIt->second != nullptr) FenceSync *operator()(GLuint handle) const
{ {
return renderbufferMapIt->second; FenceSync *fenceSync = new FenceSync(factory->createFenceSync(), handle);
fenceSync->addRef();
return fenceSync;
} }
};
Renderbuffer *renderbuffer = new Renderbuffer(factory->createRenderbuffer(), handle); return InsertObject(&mHandleAllocator, &mObjectMap, fenceSyncAllocator(factory));
renderbuffer->addRef(); }
if (handleAllocated) void FenceSyncManager::deleteFenceSync(GLuint fenceSync)
{ {
renderbufferMapIt->second = renderbuffer; deleteObject(fenceSync);
} }
else
{
mRenderbufferHandleAllocator.reserve(handle);
mRenderbufferMap[handle] = renderbuffer;
}
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 // Allocate client side handles.
if (samplerHandle == 0) 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); const auto impl = paths[static_cast<unsigned>(i)];
mSamplerMap[samplerHandle] = sampler; const auto id = client + i;
sampler->addRef(); hint = mPaths.insert(hint, std::make_pair(id, new Path(impl)));
} }
return client;
return sampler;
} }
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 } // 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// ResourceManager.h : Defines the ResourceManager class, which tracks objects // ResourceManager.h : Defines the ResourceManager classes, which handle allocation and lifetime of
// shared by multiple GL contexts. // GL objects.
#ifndef LIBANGLE_RESOURCEMANAGER_H_ #ifndef LIBANGLE_RESOURCEMANAGER_H_
#define LIBANGLE_RESOURCEMANAGER_H_ #define LIBANGLE_RESOURCEMANAGER_H_
...@@ -34,89 +34,138 @@ class Sampler; ...@@ -34,89 +34,138 @@ class Sampler;
class Shader; class Shader;
class Texture; class Texture;
class ResourceManager : angle::NonCopyable template <typename HandleAllocatorType>
class ResourceManagerBase : angle::NonCopyable
{ {
public: public:
ResourceManager(); ResourceManagerBase();
~ResourceManager();
void addRef(); void addRef();
void release(); 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(); 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, GLuint createShader(rx::GLImplFactory *factory,
const gl::Limitations &rendererLimitations, const gl::Limitations &rendererLimitations,
GLenum type); 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 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; 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 GLuint createProgram(rx::GLImplFactory *factory);
const Path *getPath(GLuint path) const; void deleteProgram(GLuint program);
Path *getPath(GLuint path); Program *getProgram(GLuint handle) const;
bool hasPath(GLuint path) const;
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer); protected:
~ShaderProgramManager() override;
Buffer *checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle); private:
Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, GLenum type); template <typename ObjectType>
Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, GLuint handle); void deleteObject(ResourceMap<ObjectType> *objectMap, GLuint id);
Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, GLuint samplerHandle);
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 isTextureGenerated(GLuint texture) const;
bool isBufferGenerated(GLuint buffer) const;
bool isRenderbufferGenerated(GLuint renderbuffer) const;
private: protected:
void createTextureInternal(GLuint handle); ~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; protected:
HandleAllocator mBufferHandleAllocator; ~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; protected:
HandleAllocator mProgramShaderHandleAllocator; ~SamplerManager() override {}
};
ResourceMap<Texture> mTextureMap; class FenceSyncManager : public TypedResourceManager<FenceSync, HandleAllocator>
HandleAllocator mTextureHandleAllocator; {
public:
GLuint createFenceSync(rx::GLImplFactory *factory);
void deleteFenceSync(GLuint fenceSync);
FenceSync *getFenceSync(GLuint handle);
ResourceMap<Renderbuffer> mRenderbufferMap; protected:
HandleAllocator mRenderbufferHandleAllocator; ~FenceSyncManager() override {}
};
ResourceMap<Sampler> mSamplerMap; class PathManager : public ResourceManagerBase<HandleRangeAllocator>
HandleAllocator mSamplerHandleAllocator; {
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; protected:
HandleAllocator mFenceSyncHandleAllocator; ~PathManager() override;
ResourceMap<Path> mPathMap; private:
HandleRangeAllocator mPathHandleAllocator; ResourceMap<Path> mPaths;
}; };
} // namespace gl } // namespace gl
......
...@@ -25,24 +25,30 @@ class ResourceManagerTest : public testing::Test ...@@ -25,24 +25,30 @@ class ResourceManagerTest : public testing::Test
protected: protected:
void SetUp() override void SetUp() override
{ {
mResourceManager = new ResourceManager(); mTextureManager = new TextureManager();
mBufferManager = new BufferManager();
mRenderbuffermanager = new RenderbufferManager();
} }
void TearDown() override void TearDown() override
{ {
SafeDelete(mResourceManager); mTextureManager->release();
mBufferManager->release();
mRenderbuffermanager->release();
} }
MockGLFactory mMockFactory; MockGLFactory mMockFactory;
ResourceManager *mResourceManager; TextureManager *mTextureManager;
BufferManager *mBufferManager;
RenderbufferManager *mRenderbuffermanager;
}; };
TEST_F(ResourceManagerTest, ReallocateBoundTexture) TEST_F(ResourceManagerTest, ReallocateBoundTexture)
{ {
EXPECT_CALL(mMockFactory, createTexture(_)).Times(1).RetiresOnSaturation(); EXPECT_CALL(mMockFactory, createTexture(_)).Times(1).RetiresOnSaturation();
mResourceManager->checkTextureAllocation(&mMockFactory, 1, GL_TEXTURE_2D); mTextureManager->checkTextureAllocation(&mMockFactory, 1, GL_TEXTURE_2D);
GLuint newTexture = mResourceManager->createTexture(); GLuint newTexture = mTextureManager->createTexture();
EXPECT_NE(1u, newTexture); EXPECT_NE(1u, newTexture);
} }
...@@ -50,8 +56,8 @@ TEST_F(ResourceManagerTest, ReallocateBoundBuffer) ...@@ -50,8 +56,8 @@ TEST_F(ResourceManagerTest, ReallocateBoundBuffer)
{ {
EXPECT_CALL(mMockFactory, createBuffer(_)).Times(1).RetiresOnSaturation(); EXPECT_CALL(mMockFactory, createBuffer(_)).Times(1).RetiresOnSaturation();
mResourceManager->checkBufferAllocation(&mMockFactory, 1); mBufferManager->checkBufferAllocation(&mMockFactory, 1);
GLuint newBuffer = mResourceManager->createBuffer(); GLuint newBuffer = mBufferManager->createBuffer();
EXPECT_NE(1u, newBuffer); EXPECT_NE(1u, newBuffer);
} }
...@@ -59,8 +65,8 @@ TEST_F(ResourceManagerTest, ReallocateBoundRenderbuffer) ...@@ -59,8 +65,8 @@ TEST_F(ResourceManagerTest, ReallocateBoundRenderbuffer)
{ {
EXPECT_CALL(mMockFactory, createRenderbuffer()).Times(1).RetiresOnSaturation(); EXPECT_CALL(mMockFactory, createRenderbuffer()).Times(1).RetiresOnSaturation();
mResourceManager->checkRenderbufferAllocation(&mMockFactory, 1); mRenderbuffermanager->checkRenderbufferAllocation(&mMockFactory, 1);
GLuint newRenderbuffer = mResourceManager->createRenderbuffer(); GLuint newRenderbuffer = mRenderbuffermanager->createRenderbuffer();
EXPECT_NE(1u, newRenderbuffer); EXPECT_NE(1u, newRenderbuffer);
} }
......
...@@ -83,7 +83,7 @@ ShaderState::~ShaderState() ...@@ -83,7 +83,7 @@ ShaderState::~ShaderState()
{ {
} }
Shader::Shader(ResourceManager *manager, Shader::Shader(ShaderProgramManager *manager,
rx::GLImplFactory *implFactory, rx::GLImplFactory *implFactory,
const gl::Limitations &rendererLimitations, const gl::Limitations &rendererLimitations,
GLenum type, GLenum type,
......
...@@ -35,7 +35,7 @@ namespace gl ...@@ -35,7 +35,7 @@ namespace gl
class Compiler; class Compiler;
class ContextState; class ContextState;
struct Limitations; struct Limitations;
class ResourceManager; class ShaderProgramManager;
class Context; class Context;
class ShaderState final : angle::NonCopyable class ShaderState final : angle::NonCopyable
...@@ -83,7 +83,7 @@ class ShaderState final : angle::NonCopyable ...@@ -83,7 +83,7 @@ class ShaderState final : angle::NonCopyable
class Shader final : angle::NonCopyable, public LabeledObject class Shader final : angle::NonCopyable, public LabeledObject
{ {
public: public:
Shader(ResourceManager *manager, Shader(ShaderProgramManager *manager,
rx::GLImplFactory *implFactory, rx::GLImplFactory *implFactory,
const gl::Limitations &rendererLimitations, const gl::Limitations &rendererLimitations,
GLenum type, GLenum type,
...@@ -145,7 +145,7 @@ class Shader final : angle::NonCopyable, public LabeledObject ...@@ -145,7 +145,7 @@ class Shader final : angle::NonCopyable, public LabeledObject
bool mCompiled; // Indicates if this shader has been successfully compiled bool mCompiled; // Indicates if this shader has been successfully compiled
std::string mInfoLog; std::string mInfoLog;
ResourceManager *mResourceManager; ShaderProgramManager *mResourceManager;
}; };
bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y); bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y);
......
...@@ -30,39 +30,29 @@ namespace ...@@ -30,39 +30,29 @@ namespace
class MockValidationContext : public ValidationContext class MockValidationContext : public ValidationContext
{ {
public: public:
MockValidationContext(const Version &version, MockValidationContext(const ValidationContext *shareContext,
const Version &version,
State *state, State *state,
const Caps &caps, const Caps &caps,
const TextureCapsMap &textureCaps, const TextureCapsMap &textureCaps,
const Extensions &extensions, const Extensions &extensions,
const ResourceManager *resourceManager,
const Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap,
bool 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 Limitations &limitations,
const ResourceMap<Framebuffer> &framebufferMap, const ResourceMap<Framebuffer> &framebufferMap,
bool skipValidation) bool skipValidation)
: ValidationContext(version, : ValidationContext(shareContext,
version,
state, state,
caps, caps,
textureCaps, textureCaps,
extensions, extensions,
resourceManager,
limitations, limitations,
framebufferMap, framebufferMap,
skipValidation) skipValidation)
{ {
} }
MOCK_METHOD1(handleError, void(const Error &));
};
// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value // 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, // larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
...@@ -110,9 +100,8 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) ...@@ -110,9 +100,8 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
state.setDrawFramebufferBinding(framebuffer); state.setDrawFramebufferBinding(framebuffer);
state.setProgram(program); state.setProgram(program);
NiceMock<MockValidationContext> testContext(Version(3, 0), &state, caps, textureCaps, NiceMock<MockValidationContext> testContext(nullptr, Version(3, 0), &state, caps, textureCaps,
extensions, nullptr, limitations, framebufferMap, extensions, limitations, framebufferMap, false);
false);
// Set the expectation for the validation error here. // Set the expectation for the validation error here.
Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage); 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