Commit 6c1f671b by Jamie Madill Committed by Commit Bot

Add destroy hooks for several GL objects.

These hooks allow the back-end renderer to free object resources without having to store pointers to shared device handles for each and every object. This will allow us to save memory on back-ends that really care about memory overhead. There is a downside in that there is more boilerplate in passing gl::Context handles around everywhere. BUG=angleproject:1684 Change-Id: I89463bba8d23f92920e8956650cb73c7fc6d66b7 Reviewed-on: https://chromium-review.googlesource.com/426401 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent abf38572
...@@ -44,6 +44,13 @@ Buffer::~Buffer() ...@@ -44,6 +44,13 @@ Buffer::~Buffer()
SafeDelete(mImpl); SafeDelete(mImpl);
} }
void Buffer::destroy(const Context *context)
{
// In tests, mImpl might be null.
if (mImpl)
mImpl->destroy(rx::SafeGetImpl(context));
}
void Buffer::setLabel(const std::string &label) void Buffer::setLabel(const std::string &label)
{ {
mState.mLabel = label; mState.mLabel = label;
......
...@@ -65,6 +65,7 @@ class Buffer final : public RefCountObject, public LabeledObject ...@@ -65,6 +65,7 @@ class Buffer final : public RefCountObject, public LabeledObject
public: public:
Buffer(rx::GLImplFactory *factory, GLuint id); Buffer(rx::GLImplFactory *factory, GLuint id);
~Buffer() override; ~Buffer() override;
void destroy(const Context *context) override;
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
const std::string &getLabel() const override; const std::string &getLabel() const override;
......
...@@ -385,7 +385,7 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -385,7 +385,7 @@ Context::Context(rx::EGLImplFactory *implFactory,
void Context::destroy(egl::Display *display) void Context::destroy(egl::Display *display)
{ {
mGLState.reset(); mGLState.reset(this);
for (auto fence : mFenceNVMap) for (auto fence : mFenceNVMap)
{ {
...@@ -409,7 +409,7 @@ void Context::destroy(egl::Display *display) ...@@ -409,7 +409,7 @@ void Context::destroy(egl::Display *display)
{ {
if (transformFeedback.second != nullptr) if (transformFeedback.second != nullptr)
{ {
transformFeedback.second->release(); transformFeedback.second->release(this);
} }
} }
...@@ -424,6 +424,15 @@ void Context::destroy(egl::Display *display) ...@@ -424,6 +424,15 @@ void Context::destroy(egl::Display *display)
releaseSurface(display); releaseSurface(display);
SafeDelete(mCompiler); SafeDelete(mCompiler);
mState.mBuffers->release(this);
mState.mShaderPrograms->release(this);
mState.mTextures->release(this);
mState.mRenderbuffers->release(this);
mState.mSamplers->release(this);
mState.mFenceSyncs->release(this);
mState.mPaths->release(this);
mState.mFramebuffers->release(this);
} }
Context::~Context() Context::~Context()
...@@ -616,17 +625,17 @@ void Context::deleteBuffer(GLuint buffer) ...@@ -616,17 +625,17 @@ void Context::deleteBuffer(GLuint buffer)
detachBuffer(buffer); detachBuffer(buffer);
} }
mState.mBuffers->deleteObject(buffer); mState.mBuffers->deleteObject(this, buffer);
} }
void Context::deleteShader(GLuint shader) void Context::deleteShader(GLuint shader)
{ {
mState.mShaderPrograms->deleteShader(shader); mState.mShaderPrograms->deleteShader(this, shader);
} }
void Context::deleteProgram(GLuint program) void Context::deleteProgram(GLuint program)
{ {
mState.mShaderPrograms->deleteProgram(program); mState.mShaderPrograms->deleteProgram(this, program);
} }
void Context::deleteTexture(GLuint texture) void Context::deleteTexture(GLuint texture)
...@@ -636,7 +645,7 @@ void Context::deleteTexture(GLuint texture) ...@@ -636,7 +645,7 @@ void Context::deleteTexture(GLuint texture)
detachTexture(texture); detachTexture(texture);
} }
mState.mTextures->deleteObject(texture); mState.mTextures->deleteObject(this, texture);
} }
void Context::deleteRenderbuffer(GLuint renderbuffer) void Context::deleteRenderbuffer(GLuint renderbuffer)
...@@ -646,7 +655,7 @@ void Context::deleteRenderbuffer(GLuint renderbuffer) ...@@ -646,7 +655,7 @@ void Context::deleteRenderbuffer(GLuint renderbuffer)
detachRenderbuffer(renderbuffer); detachRenderbuffer(renderbuffer);
} }
mState.mRenderbuffers->deleteObject(renderbuffer); mState.mRenderbuffers->deleteObject(this, renderbuffer);
} }
void Context::deleteFenceSync(GLsync fenceSync) void Context::deleteFenceSync(GLsync fenceSync)
...@@ -655,7 +664,8 @@ void Context::deleteFenceSync(GLsync fenceSync) ...@@ -655,7 +664,8 @@ 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.
mState.mFenceSyncs->deleteObject(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync))); mState.mFenceSyncs->deleteObject(this,
static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
} }
void Context::deletePaths(GLuint first, GLsizei range) void Context::deletePaths(GLuint first, GLsizei range)
...@@ -772,7 +782,7 @@ void Context::deleteSampler(GLuint sampler) ...@@ -772,7 +782,7 @@ void Context::deleteSampler(GLuint sampler)
detachSampler(sampler); detachSampler(sampler);
} }
mState.mSamplers->deleteObject(sampler); mState.mSamplers->deleteObject(this, sampler);
} }
void Context::deleteTransformFeedback(GLuint transformFeedback) void Context::deleteTransformFeedback(GLuint transformFeedback)
...@@ -784,7 +794,7 @@ void Context::deleteTransformFeedback(GLuint transformFeedback) ...@@ -784,7 +794,7 @@ void Context::deleteTransformFeedback(GLuint transformFeedback)
if (transformFeedbackObject != nullptr) if (transformFeedbackObject != nullptr)
{ {
detachTransformFeedback(transformFeedback); detachTransformFeedback(transformFeedback);
transformFeedbackObject->release(); transformFeedbackObject->release(this);
} }
mTransformFeedbackMap.erase(iter); mTransformFeedbackMap.erase(iter);
...@@ -799,7 +809,7 @@ void Context::deleteFramebuffer(GLuint framebuffer) ...@@ -799,7 +809,7 @@ void Context::deleteFramebuffer(GLuint framebuffer)
detachFramebuffer(framebuffer); detachFramebuffer(framebuffer);
} }
mState.mFramebuffers->deleteObject(framebuffer); mState.mFramebuffers->deleteObject(this, framebuffer);
} }
void Context::deleteFenceNV(GLuint fence) void Context::deleteFenceNV(GLuint fence)
...@@ -1068,7 +1078,7 @@ void Context::bindPixelUnpackBuffer(GLuint bufferHandle) ...@@ -1068,7 +1078,7 @@ void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
void Context::useProgram(GLuint program) void Context::useProgram(GLuint program)
{ {
mGLState.setProgram(getProgram(program)); mGLState.setProgram(this, getProgram(program));
} }
void Context::bindTransformFeedback(GLuint transformFeedbackHandle) void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
...@@ -2378,7 +2388,7 @@ void Context::beginTransformFeedback(GLenum primitiveMode) ...@@ -2378,7 +2388,7 @@ void Context::beginTransformFeedback(GLenum primitiveMode)
ASSERT(transformFeedback != nullptr); ASSERT(transformFeedback != nullptr);
ASSERT(!transformFeedback->isPaused()); ASSERT(!transformFeedback->isPaused());
transformFeedback->begin(primitiveMode, mGLState.getProgram()); transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
} }
bool Context::hasActiveTransformFeedback(GLuint program) const bool Context::hasActiveTransformFeedback(GLuint program) const
......
...@@ -95,14 +95,7 @@ ContextState::ContextState(uintptr_t contextIn, ...@@ -95,14 +95,7 @@ ContextState::ContextState(uintptr_t contextIn,
ContextState::~ContextState() ContextState::~ContextState()
{ {
mBuffers->release(); // Handles are released by the Context.
mShaderPrograms->release();
mTextures->release();
mRenderbuffers->release();
mSamplers->release();
mFenceSyncs->release();
mPaths->release();
mFramebuffers->release();
} }
const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const
......
...@@ -646,6 +646,7 @@ Error Display::createContext(const Config *configuration, gl::Context *shareCont ...@@ -646,6 +646,7 @@ Error Display::createContext(const Config *configuration, gl::Context *shareCont
ANGLE_TRY(restoreLostDevice()); ANGLE_TRY(restoreLostDevice());
} }
// This display texture sharing will allow the first context to create the texture share group.
bool usingDisplayTextureShareGroup = bool usingDisplayTextureShareGroup =
attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE; attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
gl::TextureManager *shareTextures = nullptr; gl::TextureManager *shareTextures = nullptr;
...@@ -748,7 +749,7 @@ void Display::destroyContext(gl::Context *context) ...@@ -748,7 +749,7 @@ void Display::destroyContext(gl::Context *context)
{ {
// If this is the last context using the global share group, destroy the global texture // If this is the last context using the global share group, destroy the global texture
// manager so that the textures can be destroyed while a context still exists // manager so that the textures can be destroyed while a context still exists
mTextureManager->release(); mTextureManager->release(context);
mTextureManager = nullptr; mTextureManager = nullptr;
} }
mGlobalTextureShareGroupUsers--; mGlobalTextureShareGroupUsers--;
......
...@@ -178,6 +178,6 @@ class Display final : angle::NonCopyable ...@@ -178,6 +178,6 @@ class Display final : angle::NonCopyable
size_t mGlobalTextureShareGroupUsers; size_t mGlobalTextureShareGroupUsers;
}; };
} } // namespace egl
#endif // LIBANGLE_DISPLAY_H_ #endif // LIBANGLE_DISPLAY_H_
...@@ -54,6 +54,8 @@ class FenceSync final : public RefCountObject, public LabeledObject ...@@ -54,6 +54,8 @@ class FenceSync final : public RefCountObject, public LabeledObject
FenceSync(rx::FenceSyncImpl *impl, GLuint id); FenceSync(rx::FenceSyncImpl *impl, GLuint id);
virtual ~FenceSync(); virtual ~FenceSync();
void destroy(const Context *context) override {}
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
const std::string &getLabel() const override; const std::string &getLabel() const override;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Config.h" #include "libANGLE/Config.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Renderbuffer.h" #include "libANGLE/Renderbuffer.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
...@@ -322,6 +323,16 @@ Framebuffer::~Framebuffer() ...@@ -322,6 +323,16 @@ Framebuffer::~Framebuffer()
SafeDelete(mImpl); SafeDelete(mImpl);
} }
void Framebuffer::destroy(const Context *context)
{
mImpl->destroy(rx::SafeGetImpl(context));
}
void Framebuffer::destroyDefault(const egl::Display *display)
{
mImpl->destroyDefault(rx::SafeGetImpl(display));
}
void Framebuffer::setLabel(const std::string &label) void Framebuffer::setLabel(const std::string &label)
{ {
mState.mLabel = label; mState.mLabel = label;
......
...@@ -32,6 +32,7 @@ class SurfaceImpl; ...@@ -32,6 +32,7 @@ class SurfaceImpl;
namespace egl namespace egl
{ {
class Display;
class Surface; class Surface;
} }
...@@ -107,6 +108,8 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver ...@@ -107,6 +108,8 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver
Framebuffer(rx::GLImplFactory *factory); Framebuffer(rx::GLImplFactory *factory);
virtual ~Framebuffer(); virtual ~Framebuffer();
void destroy(const Context *context);
void destroyDefault(const egl::Display *display);
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
const std::string &getLabel() const override; const std::string &getLabel() const override;
......
...@@ -254,20 +254,7 @@ ProgramState::ProgramState() ...@@ -254,20 +254,7 @@ ProgramState::ProgramState()
ProgramState::~ProgramState() ProgramState::~ProgramState()
{ {
if (mAttachedVertexShader != nullptr) ASSERT(!mAttachedVertexShader && !mAttachedFragmentShader && !mAttachedComputeShader);
{
mAttachedVertexShader->release();
}
if (mAttachedFragmentShader != nullptr)
{
mAttachedFragmentShader->release();
}
if (mAttachedComputeShader != nullptr)
{
mAttachedComputeShader->release();
}
} }
const std::string &ProgramState::getLabel() const std::string &ProgramState::getLabel()
...@@ -397,11 +384,34 @@ Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLui ...@@ -397,11 +384,34 @@ Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLui
Program::~Program() Program::~Program()
{ {
unlink(true); ASSERT(!mState.mAttachedVertexShader && !mState.mAttachedFragmentShader &&
!mState.mAttachedComputeShader);
SafeDelete(mProgram); SafeDelete(mProgram);
} }
void Program::destroy(const Context *context)
{
if (mState.mAttachedVertexShader != nullptr)
{
mState.mAttachedVertexShader->release(context);
mState.mAttachedVertexShader = nullptr;
}
if (mState.mAttachedFragmentShader != nullptr)
{
mState.mAttachedFragmentShader->release(context);
mState.mAttachedFragmentShader = nullptr;
}
if (mState.mAttachedComputeShader != nullptr)
{
mState.mAttachedComputeShader->release(context);
mState.mAttachedComputeShader = nullptr;
}
mProgram->destroy(rx::SafeGetImpl(context));
}
void Program::setLabel(const std::string &label) void Program::setLabel(const std::string &label)
{ {
mState.mLabel = label; mState.mLabel = label;
...@@ -442,7 +452,7 @@ void Program::attachShader(Shader *shader) ...@@ -442,7 +452,7 @@ void Program::attachShader(Shader *shader)
} }
} }
bool Program::detachShader(Shader *shader) bool Program::detachShader(const Context *context, Shader *shader)
{ {
switch (shader->getType()) switch (shader->getType())
{ {
...@@ -453,7 +463,7 @@ bool Program::detachShader(Shader *shader) ...@@ -453,7 +463,7 @@ bool Program::detachShader(Shader *shader)
return false; return false;
} }
shader->release(); shader->release(context);
mState.mAttachedVertexShader = nullptr; mState.mAttachedVertexShader = nullptr;
break; break;
} }
...@@ -464,7 +474,7 @@ bool Program::detachShader(Shader *shader) ...@@ -464,7 +474,7 @@ bool Program::detachShader(Shader *shader)
return false; return false;
} }
shader->release(); shader->release(context);
mState.mAttachedFragmentShader = nullptr; mState.mAttachedFragmentShader = nullptr;
break; break;
} }
...@@ -475,7 +485,7 @@ bool Program::detachShader(Shader *shader) ...@@ -475,7 +485,7 @@ bool Program::detachShader(Shader *shader)
return false; return false;
} }
shader->release(); shader->release(context);
mState.mAttachedComputeShader = nullptr; mState.mAttachedComputeShader = nullptr;
break; break;
} }
...@@ -586,7 +596,7 @@ Error Program::link(const gl::Context *context) ...@@ -586,7 +596,7 @@ Error Program::link(const gl::Context *context)
{ {
const auto &data = context->getContextState(); const auto &data = context->getContextState();
unlink(false); unlink();
mInfoLog.reset(); mInfoLog.reset();
resetUniformBlockBindings(); resetUniformBlockBindings();
...@@ -724,29 +734,8 @@ Error Program::link(const gl::Context *context) ...@@ -724,29 +734,8 @@ Error Program::link(const gl::Context *context)
} }
// Returns the program object to an unlinked state, before re-linking, or at destruction // Returns the program object to an unlinked state, before re-linking, or at destruction
void Program::unlink(bool destroy) void Program::unlink()
{ {
if (destroy) // Object being destructed
{
if (mState.mAttachedFragmentShader)
{
mState.mAttachedFragmentShader->release();
mState.mAttachedFragmentShader = nullptr;
}
if (mState.mAttachedVertexShader)
{
mState.mAttachedVertexShader->release();
mState.mAttachedVertexShader = nullptr;
}
if (mState.mAttachedComputeShader)
{
mState.mAttachedComputeShader->release();
mState.mAttachedComputeShader = nullptr;
}
}
mState.mAttributes.clear(); mState.mAttributes.clear();
mState.mActiveAttribLocationsMask.reset(); mState.mActiveAttribLocationsMask.reset();
mState.mTransformFeedbackVaryingVars.clear(); mState.mTransformFeedbackVaryingVars.clear();
...@@ -772,7 +761,7 @@ Error Program::loadBinary(const Context *context, ...@@ -772,7 +761,7 @@ Error Program::loadBinary(const Context *context,
const void *binary, const void *binary,
GLsizei length) GLsizei length)
{ {
unlink(false); unlink();
#if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED #if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED
return NoError(); return NoError();
...@@ -1103,13 +1092,13 @@ bool Program::getBinaryRetrievableHint() const ...@@ -1103,13 +1092,13 @@ bool Program::getBinaryRetrievableHint() const
return mState.mBinaryRetrieveableHint; return mState.mBinaryRetrieveableHint;
} }
void Program::release() void Program::release(const Context *context)
{ {
mRefCount--; mRefCount--;
if (mRefCount == 0 && mDeleteStatus) if (mRefCount == 0 && mDeleteStatus)
{ {
mResourceManager->deleteProgram(mHandle); mResourceManager->deleteProgram(context, mHandle);
} }
} }
......
...@@ -263,6 +263,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -263,6 +263,7 @@ class Program final : angle::NonCopyable, public LabeledObject
public: public:
Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle); Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle);
~Program(); ~Program();
void destroy(const Context *context);
GLuint id() const { return mHandle; } GLuint id() const { return mHandle; }
...@@ -272,7 +273,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -272,7 +273,7 @@ class Program final : angle::NonCopyable, public LabeledObject
rx::ProgramImpl *getImplementation() const { return mProgram; } rx::ProgramImpl *getImplementation() const { return mProgram; }
void attachShader(Shader *shader); void attachShader(Shader *shader);
bool detachShader(Shader *shader); bool detachShader(const Context *context, Shader *shader);
int getAttachedShadersCount() const; int getAttachedShadersCount() const;
const Shader *getAttachedVertexShader() const { return mState.mAttachedVertexShader; } const Shader *getAttachedVertexShader() const { return mState.mAttachedVertexShader; }
...@@ -384,7 +385,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -384,7 +385,7 @@ class Program final : angle::NonCopyable, public LabeledObject
static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
void addRef(); void addRef();
void release(); void release(const Context *context);
unsigned int getRefCount() const; unsigned int getRefCount() const;
void flagForDeletion(); void flagForDeletion();
bool isFlaggedForDeletion() const; bool isFlaggedForDeletion() const;
...@@ -430,7 +431,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -430,7 +431,7 @@ class Program final : angle::NonCopyable, public LabeledObject
using MergedVaryings = std::map<std::string, VaryingRef>; using MergedVaryings = std::map<std::string, VaryingRef>;
void unlink(bool destroy = false); void unlink();
void resetUniformBlockBindings(); void resetUniformBlockBindings();
bool linkAttributes(const ContextState &data, InfoLog &infoLog); bool linkAttributes(const ContextState &data, InfoLog &infoLog);
......
...@@ -18,6 +18,11 @@ ...@@ -18,6 +18,11 @@
#include <cstddef> #include <cstddef>
namespace gl
{
class Context;
}
class RefCountObjectNoID : angle::NonCopyable class RefCountObjectNoID : angle::NonCopyable
{ {
public: public:
...@@ -35,10 +40,22 @@ class RefCountObjectNoID : angle::NonCopyable ...@@ -35,10 +40,22 @@ class RefCountObjectNoID : angle::NonCopyable
} }
} }
// A specialized release method for objects which need a destroy context.
void release(const gl::Context *context)
{
ASSERT(mRefCount > 0);
if (--mRefCount == 0)
{
destroy(context);
delete this;
}
}
size_t getRefCount() const { return mRefCount; } size_t getRefCount() const { return mRefCount; }
protected: protected:
virtual ~RefCountObjectNoID() { ASSERT(mRefCount == 0); } virtual ~RefCountObjectNoID() { ASSERT(mRefCount == 0); }
virtual void destroy(const gl::Context *context) {}
private: private:
mutable std::size_t mRefCount; mutable std::size_t mRefCount;
......
...@@ -35,6 +35,8 @@ class Renderbuffer final : public egl::ImageSibling, ...@@ -35,6 +35,8 @@ class Renderbuffer final : public egl::ImageSibling,
Renderbuffer(rx::RenderbufferImpl *impl, GLuint id); Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
virtual ~Renderbuffer(); virtual ~Renderbuffer();
void destroy(const Context *context) override {}
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
const std::string &getLabel() const override; const std::string &getLabel() const override;
......
...@@ -54,10 +54,11 @@ void ResourceManagerBase<HandleAllocatorType>::addRef() ...@@ -54,10 +54,11 @@ void ResourceManagerBase<HandleAllocatorType>::addRef()
} }
template <typename HandleAllocatorType> template <typename HandleAllocatorType>
void ResourceManagerBase<HandleAllocatorType>::release() void ResourceManagerBase<HandleAllocatorType>::release(const Context *context)
{ {
if (--mRefCount == 0) if (--mRefCount == 0)
{ {
reset(context);
delete this; delete this;
} }
} }
...@@ -65,14 +66,23 @@ void ResourceManagerBase<HandleAllocatorType>::release() ...@@ -65,14 +66,23 @@ void ResourceManagerBase<HandleAllocatorType>::release()
template <typename ResourceType, typename HandleAllocatorType, typename ImplT> template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::~TypedResourceManager() TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::~TypedResourceManager()
{ {
ASSERT(mObjectMap.empty());
}
template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::reset(const Context *context)
{
while (!mObjectMap.empty()) while (!mObjectMap.empty())
{ {
deleteObject(mObjectMap.begin()->first); deleteObject(context, mObjectMap.begin()->first);
} }
mObjectMap.clear();
} }
template <typename ResourceType, typename HandleAllocatorType, typename ImplT> template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObject(GLuint handle) void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObject(
const Context *context,
GLuint handle)
{ {
auto objectIter = mObjectMap.find(handle); auto objectIter = mObjectMap.find(handle);
if (objectIter == mObjectMap.end()) if (objectIter == mObjectMap.end())
...@@ -82,6 +92,7 @@ void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObjec ...@@ -82,6 +92,7 @@ void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObjec
if (objectIter->second != nullptr) if (objectIter->second != nullptr)
{ {
objectIter->second->destroy(context);
ImplT::DeleteObject(objectIter->second); ImplT::DeleteObject(objectIter->second);
} }
...@@ -181,14 +192,22 @@ bool BufferManager::isBufferGenerated(GLuint buffer) const ...@@ -181,14 +192,22 @@ bool BufferManager::isBufferGenerated(GLuint buffer) const
ShaderProgramManager::~ShaderProgramManager() ShaderProgramManager::~ShaderProgramManager()
{ {
ASSERT(mPrograms.empty());
ASSERT(mShaders.empty());
}
void ShaderProgramManager::reset(const Context *context)
{
while (!mPrograms.empty()) while (!mPrograms.empty())
{ {
deleteProgram(mPrograms.begin()->first); deleteProgram(context, mPrograms.begin()->first);
} }
mPrograms.clear();
while (!mShaders.empty()) while (!mShaders.empty())
{ {
deleteShader(mShaders.begin()->first); deleteShader(context, mShaders.begin()->first);
} }
mShaders.clear();
} }
GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory, GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
...@@ -201,9 +220,9 @@ GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory, ...@@ -201,9 +220,9 @@ GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
return handle; return handle;
} }
void ShaderProgramManager::deleteShader(GLuint shader) void ShaderProgramManager::deleteShader(const Context *context, GLuint shader)
{ {
deleteObject(&mShaders, shader); deleteObject(context, &mShaders, shader);
} }
Shader *ShaderProgramManager::getShader(GLuint handle) const Shader *ShaderProgramManager::getShader(GLuint handle) const
...@@ -218,9 +237,9 @@ GLuint ShaderProgramManager::createProgram(rx::GLImplFactory *factory) ...@@ -218,9 +237,9 @@ GLuint ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
return handle; return handle;
} }
void ShaderProgramManager::deleteProgram(GLuint program) void ShaderProgramManager::deleteProgram(const gl::Context *context, GLuint program)
{ {
deleteObject(&mPrograms, program); deleteObject(context, &mPrograms, program);
} }
Program *ShaderProgramManager::getProgram(GLuint handle) const Program *ShaderProgramManager::getProgram(GLuint handle) const
...@@ -229,7 +248,9 @@ Program *ShaderProgramManager::getProgram(GLuint handle) const ...@@ -229,7 +248,9 @@ Program *ShaderProgramManager::getProgram(GLuint handle) const
} }
template <typename ObjectType> template <typename ObjectType>
void ShaderProgramManager::deleteObject(ResourceMap<ObjectType> *objectMap, GLuint id) void ShaderProgramManager::deleteObject(const Context *context,
ResourceMap<ObjectType> *objectMap,
GLuint id)
{ {
auto iter = objectMap->find(id); auto iter = objectMap->find(id);
if (iter == objectMap->end()) if (iter == objectMap->end())
...@@ -241,6 +262,7 @@ void ShaderProgramManager::deleteObject(ResourceMap<ObjectType> *objectMap, GLui ...@@ -241,6 +262,7 @@ void ShaderProgramManager::deleteObject(ResourceMap<ObjectType> *objectMap, GLui
if (object->getRefCount() == 0) if (object->getRefCount() == 0)
{ {
mHandleAllocator.release(id); mHandleAllocator.release(id);
object->destroy(context);
SafeDelete(object); SafeDelete(object);
objectMap->erase(iter); objectMap->erase(iter);
} }
...@@ -421,10 +443,16 @@ bool PathManager::hasPath(GLuint handle) const ...@@ -421,10 +443,16 @@ bool PathManager::hasPath(GLuint handle) const
PathManager::~PathManager() PathManager::~PathManager()
{ {
ASSERT(mPaths.empty());
}
void PathManager::reset(const Context *context)
{
for (auto path : mPaths) for (auto path : mPaths)
{ {
SafeDelete(path.second); SafeDelete(path.second);
} }
mPaths.clear();
} }
// FramebufferManager Implementation. // FramebufferManager Implementation.
......
...@@ -26,6 +26,7 @@ namespace gl ...@@ -26,6 +26,7 @@ namespace gl
{ {
class Buffer; class Buffer;
struct Caps; struct Caps;
class Context;
class FenceSync; class FenceSync;
class Framebuffer; class Framebuffer;
struct Limitations; struct Limitations;
...@@ -43,9 +44,10 @@ class ResourceManagerBase : angle::NonCopyable ...@@ -43,9 +44,10 @@ class ResourceManagerBase : angle::NonCopyable
ResourceManagerBase(); ResourceManagerBase();
void addRef(); void addRef();
void release(); void release(const Context *context);
protected: protected:
virtual void reset(const Context *context) = 0;
virtual ~ResourceManagerBase() {} virtual ~ResourceManagerBase() {}
HandleAllocatorType mHandleAllocator; HandleAllocatorType mHandleAllocator;
...@@ -60,7 +62,7 @@ class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType> ...@@ -60,7 +62,7 @@ class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType>
public: public:
TypedResourceManager() {} TypedResourceManager() {}
void deleteObject(GLuint handle); void deleteObject(const Context *context, GLuint handle);
protected: protected:
~TypedResourceManager() override; ~TypedResourceManager() override;
...@@ -90,6 +92,8 @@ class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType> ...@@ -90,6 +92,8 @@ class TypedResourceManager : public ResourceManagerBase<HandleAllocatorType>
GLuint handle, GLuint handle,
ArgTypes... args); ArgTypes... args);
void reset(const Context *context) override;
ResourceMap<ResourceType> mObjectMap; ResourceMap<ResourceType> mObjectMap;
}; };
...@@ -117,13 +121,13 @@ class ShaderProgramManager : public ResourceManagerBase<HandleAllocator> ...@@ -117,13 +121,13 @@ class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
{ {
public: public:
GLuint createShader(rx::GLImplFactory *factory, GLuint createShader(rx::GLImplFactory *factory,
const gl::Limitations &rendererLimitations, const Limitations &rendererLimitations,
GLenum type); GLenum type);
void deleteShader(GLuint shader); void deleteShader(const Context *context, GLuint shader);
Shader *getShader(GLuint handle) const; Shader *getShader(GLuint handle) const;
GLuint createProgram(rx::GLImplFactory *factory); GLuint createProgram(rx::GLImplFactory *factory);
void deleteProgram(GLuint program); void deleteProgram(const Context *context, GLuint program);
Program *getProgram(GLuint handle) const; Program *getProgram(GLuint handle) const;
protected: protected:
...@@ -131,7 +135,9 @@ class ShaderProgramManager : public ResourceManagerBase<HandleAllocator> ...@@ -131,7 +135,9 @@ class ShaderProgramManager : public ResourceManagerBase<HandleAllocator>
private: private:
template <typename ObjectType> template <typename ObjectType>
void deleteObject(ResourceMap<ObjectType> *objectMap, GLuint id); void deleteObject(const Context *context, ResourceMap<ObjectType> *objectMap, GLuint id);
void reset(const Context *context) override;
ResourceMap<Shader> mShaders; ResourceMap<Shader> mShaders;
ResourceMap<Program> mPrograms; ResourceMap<Program> mPrograms;
...@@ -217,6 +223,7 @@ class PathManager : public ResourceManagerBase<HandleRangeAllocator> ...@@ -217,6 +223,7 @@ class PathManager : public ResourceManagerBase<HandleRangeAllocator>
protected: protected:
~PathManager() override; ~PathManager() override;
void reset(const Context *context) override;
private: private:
ResourceMap<Path> mPaths; ResourceMap<Path> mPaths;
......
...@@ -32,9 +32,9 @@ class ResourceManagerTest : public testing::Test ...@@ -32,9 +32,9 @@ class ResourceManagerTest : public testing::Test
void TearDown() override void TearDown() override
{ {
mTextureManager->release(); mTextureManager->release(nullptr);
mBufferManager->release(); mBufferManager->release(nullptr);
mRenderbuffermanager->release(); mRenderbuffermanager->release(nullptr);
} }
MockGLFactory mMockFactory; MockGLFactory mMockFactory;
......
...@@ -29,6 +29,8 @@ class Sampler final : public RefCountObject, public LabeledObject ...@@ -29,6 +29,8 @@ class Sampler final : public RefCountObject, public LabeledObject
Sampler(rx::GLImplFactory *factory, GLuint id); Sampler(rx::GLImplFactory *factory, GLuint id);
~Sampler() override; ~Sampler() override;
void destroy(const Context *context) override {}
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
const std::string &getLabel() const override; const std::string &getLabel() const override;
......
...@@ -352,13 +352,13 @@ void Shader::addRef() ...@@ -352,13 +352,13 @@ void Shader::addRef()
mRefCount++; mRefCount++;
} }
void Shader::release() void Shader::release(const Context *context)
{ {
mRefCount--; mRefCount--;
if (mRefCount == 0 && mDeleteStatus) if (mRefCount == 0 && mDeleteStatus)
{ {
mResourceManager->deleteShader(mHandle); mResourceManager->deleteShader(context, mHandle);
} }
} }
......
...@@ -89,6 +89,7 @@ class Shader final : angle::NonCopyable, public LabeledObject ...@@ -89,6 +89,7 @@ class Shader final : angle::NonCopyable, public LabeledObject
GLenum type, GLenum type,
GLuint handle); GLuint handle);
void destroy(const Context *context) {}
virtual ~Shader(); virtual ~Shader();
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
...@@ -115,7 +116,7 @@ class Shader final : angle::NonCopyable, public LabeledObject ...@@ -115,7 +116,7 @@ class Shader final : angle::NonCopyable, public LabeledObject
bool isCompiled() const { return mCompiled; } bool isCompiled() const { return mCompiled; }
void addRef(); void addRef();
void release(); void release(const Context *context);
unsigned int getRefCount() const; unsigned int getRefCount() const;
bool isFlaggedForDeletion() const; bool isFlaggedForDeletion() const;
void flagForDeletion(); void flagForDeletion();
......
...@@ -67,7 +67,6 @@ State::State() ...@@ -67,7 +67,6 @@ State::State()
State::~State() State::~State()
{ {
reset();
} }
void State::initialize(const Caps &caps, void State::initialize(const Caps &caps,
...@@ -212,7 +211,7 @@ void State::initialize(const Caps &caps, ...@@ -212,7 +211,7 @@ void State::initialize(const Caps &caps,
mPathStencilMask = std::numeric_limits<GLuint>::max(); mPathStencilMask = std::numeric_limits<GLuint>::max();
} }
void State::reset() void State::reset(const Context *context)
{ {
for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
{ {
...@@ -233,7 +232,7 @@ void State::reset() ...@@ -233,7 +232,7 @@ void State::reset()
if (mProgram) if (mProgram)
{ {
mProgram->release(); mProgram->release(context);
} }
mProgram = NULL; mProgram = NULL;
...@@ -1018,13 +1017,13 @@ bool State::removeVertexArrayBinding(GLuint vertexArray) ...@@ -1018,13 +1017,13 @@ bool State::removeVertexArrayBinding(GLuint vertexArray)
return false; return false;
} }
void State::setProgram(Program *newProgram) void State::setProgram(const Context *context, Program *newProgram)
{ {
if (mProgram != newProgram) if (mProgram != newProgram)
{ {
if (mProgram) if (mProgram)
{ {
mProgram->release(); mProgram->release(context);
} }
mProgram = newProgram; mProgram = newProgram;
......
...@@ -45,7 +45,7 @@ class State : angle::NonCopyable ...@@ -45,7 +45,7 @@ class State : angle::NonCopyable
const Version &clientVersion, const Version &clientVersion,
bool debug, bool debug,
bool bindGeneratesResource); bool bindGeneratesResource);
void reset(); void reset(const Context *context);
// State chunk getters // State chunk getters
const RasterizerState &getRasterizerState() const; const RasterizerState &getRasterizerState() const;
...@@ -194,7 +194,7 @@ class State : angle::NonCopyable ...@@ -194,7 +194,7 @@ class State : angle::NonCopyable
bool removeVertexArrayBinding(GLuint vertexArray); bool removeVertexArrayBinding(GLuint vertexArray);
// Program binding manipulation // Program binding manipulation
void setProgram(Program *newProgram); void setProgram(const Context *context, Program *newProgram);
Program *getProgram() const; Program *getProgram() const;
// Transform feedback object (not buffer) binding manipulation // Transform feedback object (not buffer) binding manipulation
......
...@@ -89,6 +89,19 @@ Surface::~Surface() ...@@ -89,6 +89,19 @@ Surface::~Surface()
SafeDelete(mImplementation); SafeDelete(mImplementation);
} }
void Surface::destroy(const Display *display)
{
if (mState.defaultFramebuffer)
{
mState.defaultFramebuffer->destroyDefault(display);
}
if (mImplementation)
{
mImplementation->destroy(rx::SafeGetImpl(display));
}
delete this;
}
Error Surface::initialize(const Display &display) Error Surface::initialize(const Display &display)
{ {
ANGLE_TRY(mImplementation->initialize(display.getImplementation())); ANGLE_TRY(mImplementation->initialize(display.getImplementation()));
...@@ -116,11 +129,7 @@ void Surface::setIsCurrent(Display *display, bool isCurrent) ...@@ -116,11 +129,7 @@ void Surface::setIsCurrent(Display *display, bool isCurrent)
mCurrentCount--; mCurrentCount--;
if (mCurrentCount == 0 && mDestroyed) if (mCurrentCount == 0 && mDestroyed)
{ {
if (mImplementation) destroy(display);
{
mImplementation->destroy(rx::SafeGetImpl(display));
}
delete this;
} }
} }
...@@ -129,11 +138,7 @@ void Surface::onDestroy(Display *display) ...@@ -129,11 +138,7 @@ void Surface::onDestroy(Display *display)
mDestroyed = true; mDestroyed = true;
if (mCurrentCount == 0) if (mCurrentCount == 0)
{ {
if (mImplementation) destroy(display);
{
mImplementation->destroy(rx::SafeGetImpl(display));
}
delete this;
} }
} }
......
...@@ -141,6 +141,9 @@ class Surface : public gl::FramebufferAttachmentObject ...@@ -141,6 +141,9 @@ class Surface : public gl::FramebufferAttachmentObject
gl::Format mBackFormat; gl::Format mBackFormat;
gl::Format mDSFormat; gl::Format mDSFormat;
private:
void destroy(const egl::Display *display);
}; };
class WindowSurface final : public Surface class WindowSurface final : public Surface
......
...@@ -184,6 +184,8 @@ class Texture final : public egl::ImageSibling, ...@@ -184,6 +184,8 @@ class Texture final : public egl::ImageSibling,
Texture(rx::GLImplFactory *factory, GLuint id, GLenum target); Texture(rx::GLImplFactory *factory, GLuint id, GLenum target);
~Texture() override; ~Texture() override;
void destroy(const Context *context) override {}
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
const std::string &getLabel() const override; const std::string &getLabel() const override;
......
...@@ -50,13 +50,18 @@ TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, ...@@ -50,13 +50,18 @@ TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory, GLuint id,
ASSERT(mImplementation != nullptr); ASSERT(mImplementation != nullptr);
} }
TransformFeedback::~TransformFeedback() void TransformFeedback::destroy(const Context *context)
{ {
if (mState.mProgram) if (mState.mProgram)
{ {
mState.mProgram->release(); mState.mProgram->release(context);
mState.mProgram = nullptr; mState.mProgram = nullptr;
} }
}
TransformFeedback::~TransformFeedback()
{
ASSERT(!mState.mProgram);
mState.mGenericBuffer.set(nullptr); mState.mGenericBuffer.set(nullptr);
for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++) for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++)
{ {
...@@ -76,16 +81,16 @@ const std::string &TransformFeedback::getLabel() const ...@@ -76,16 +81,16 @@ const std::string &TransformFeedback::getLabel() const
return mState.mLabel; return mState.mLabel;
} }
void TransformFeedback::begin(GLenum primitiveMode, Program *program) void TransformFeedback::begin(const Context *context, GLenum primitiveMode, Program *program)
{ {
mState.mActive = true; mState.mActive = true;
mState.mPrimitiveMode = primitiveMode; mState.mPrimitiveMode = primitiveMode;
mState.mPaused = false; mState.mPaused = false;
mImplementation->begin(primitiveMode); mImplementation->begin(primitiveMode);
bindProgram(program); bindProgram(context, program);
} }
void TransformFeedback::end() void TransformFeedback::end(const Context *context)
{ {
mState.mActive = false; mState.mActive = false;
mState.mPrimitiveMode = GL_NONE; mState.mPrimitiveMode = GL_NONE;
...@@ -93,7 +98,7 @@ void TransformFeedback::end() ...@@ -93,7 +98,7 @@ void TransformFeedback::end()
mImplementation->end(); mImplementation->end();
if (mState.mProgram) if (mState.mProgram)
{ {
mState.mProgram->release(); mState.mProgram->release(context);
mState.mProgram = nullptr; mState.mProgram = nullptr;
} }
} }
...@@ -125,13 +130,13 @@ GLenum TransformFeedback::getPrimitiveMode() const ...@@ -125,13 +130,13 @@ GLenum TransformFeedback::getPrimitiveMode() const
return mState.mPrimitiveMode; return mState.mPrimitiveMode;
} }
void TransformFeedback::bindProgram(Program *program) void TransformFeedback::bindProgram(const Context *context, Program *program)
{ {
if (mState.mProgram != program) if (mState.mProgram != program)
{ {
if (mState.mProgram != nullptr) if (mState.mProgram != nullptr)
{ {
mState.mProgram->release(); mState.mProgram->release(context);
} }
mState.mProgram = program; mState.mProgram = program;
if (mState.mProgram != nullptr) if (mState.mProgram != nullptr)
......
...@@ -24,6 +24,7 @@ namespace gl ...@@ -24,6 +24,7 @@ namespace gl
{ {
class Buffer; class Buffer;
struct Caps; struct Caps;
class Context;
class Program; class Program;
class TransformFeedbackState final : public angle::NonCopyable class TransformFeedbackState final : public angle::NonCopyable
...@@ -55,12 +56,13 @@ class TransformFeedback final : public RefCountObject, public LabeledObject ...@@ -55,12 +56,13 @@ class TransformFeedback final : public RefCountObject, public LabeledObject
public: public:
TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps); TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps);
virtual ~TransformFeedback(); virtual ~TransformFeedback();
void destroy(const Context *context) override;
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
const std::string &getLabel() const override; const std::string &getLabel() const override;
void begin(GLenum primitiveMode, Program *program); void begin(const Context *context, GLenum primitiveMode, Program *program);
void end(); void end(const Context *context);
void pause(); void pause();
void resume(); void resume();
...@@ -83,7 +85,7 @@ class TransformFeedback final : public RefCountObject, public LabeledObject ...@@ -83,7 +85,7 @@ class TransformFeedback final : public RefCountObject, public LabeledObject
const rx::TransformFeedbackImpl *getImplementation() const; const rx::TransformFeedbackImpl *getImplementation() const;
private: private:
void bindProgram(Program *program); void bindProgram(const Context *context, Program *program);
TransformFeedbackState mState; TransformFeedbackState mState;
rx::TransformFeedbackImpl* mImplementation; rx::TransformFeedbackImpl* mImplementation;
......
...@@ -72,11 +72,11 @@ TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop) ...@@ -72,11 +72,11 @@ TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop)
EXPECT_FALSE(mFeedback->isActive()); EXPECT_FALSE(mFeedback->isActive());
EXPECT_CALL(*mImpl, begin(GL_TRIANGLES)); EXPECT_CALL(*mImpl, begin(GL_TRIANGLES));
mFeedback->begin(GL_TRIANGLES, nullptr); mFeedback->begin(nullptr, GL_TRIANGLES, nullptr);
EXPECT_TRUE(mFeedback->isActive()); EXPECT_TRUE(mFeedback->isActive());
EXPECT_EQ(static_cast<GLenum>(GL_TRIANGLES), mFeedback->getPrimitiveMode()); EXPECT_EQ(static_cast<GLenum>(GL_TRIANGLES), mFeedback->getPrimitiveMode());
EXPECT_CALL(*mImpl, end()); EXPECT_CALL(*mImpl, end());
mFeedback->end(); mFeedback->end(nullptr);
EXPECT_FALSE(mFeedback->isActive()); EXPECT_FALSE(mFeedback->isActive());
} }
...@@ -86,7 +86,7 @@ TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume) ...@@ -86,7 +86,7 @@ TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume)
EXPECT_FALSE(mFeedback->isActive()); EXPECT_FALSE(mFeedback->isActive());
EXPECT_CALL(*mImpl, begin(GL_TRIANGLES)); EXPECT_CALL(*mImpl, begin(GL_TRIANGLES));
mFeedback->begin(GL_TRIANGLES, nullptr); mFeedback->begin(nullptr, GL_TRIANGLES, nullptr);
EXPECT_FALSE(mFeedback->isPaused()); EXPECT_FALSE(mFeedback->isPaused());
EXPECT_CALL(*mImpl, pause()); EXPECT_CALL(*mImpl, pause());
mFeedback->pause(); mFeedback->pause();
...@@ -95,7 +95,7 @@ TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume) ...@@ -95,7 +95,7 @@ TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume)
mFeedback->resume(); mFeedback->resume();
EXPECT_FALSE(mFeedback->isPaused()); EXPECT_FALSE(mFeedback->isPaused());
EXPECT_CALL(*mImpl, end()); EXPECT_CALL(*mImpl, end());
mFeedback->end(); mFeedback->end(nullptr);
} }
TEST_F(TransformFeedbackTest, BufferBinding) TEST_F(TransformFeedbackTest, BufferBinding)
......
...@@ -29,6 +29,7 @@ class BufferImpl : angle::NonCopyable ...@@ -29,6 +29,7 @@ class BufferImpl : angle::NonCopyable
public: public:
BufferImpl(const gl::BufferState &state) : mState(state) {} BufferImpl(const gl::BufferState &state) : mState(state) {}
virtual ~BufferImpl() { } virtual ~BufferImpl() { }
virtual void destroy(ContextImpl *contextImpl) {}
virtual gl::Error setData(ContextImpl *context, virtual gl::Error setData(ContextImpl *context,
GLenum target, GLenum target,
......
...@@ -24,12 +24,15 @@ struct Rectangle; ...@@ -24,12 +24,15 @@ struct Rectangle;
namespace rx namespace rx
{ {
class DisplayImpl;
class FramebufferImpl : angle::NonCopyable class FramebufferImpl : angle::NonCopyable
{ {
public: public:
explicit FramebufferImpl(const gl::FramebufferState &state) : mState(state) {} explicit FramebufferImpl(const gl::FramebufferState &state) : mState(state) {}
virtual ~FramebufferImpl() { } virtual ~FramebufferImpl() { }
virtual void destroy(ContextImpl *contextImpl) {}
virtual void destroyDefault(DisplayImpl *displayImpl) {}
virtual gl::Error discard(size_t count, const GLenum *attachments) = 0; virtual gl::Error discard(size_t count, const GLenum *attachments) = 0;
virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0; virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0;
......
...@@ -21,7 +21,7 @@ class MockFramebufferImpl : public rx::FramebufferImpl ...@@ -21,7 +21,7 @@ class MockFramebufferImpl : public rx::FramebufferImpl
{ {
public: public:
MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState()) {} MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState()) {}
virtual ~MockFramebufferImpl() { destroy(); } virtual ~MockFramebufferImpl() { destructor(); }
MOCK_METHOD2(discard, gl::Error(size_t, const GLenum *)); MOCK_METHOD2(discard, gl::Error(size_t, const GLenum *));
MOCK_METHOD2(invalidate, gl::Error(size_t, const GLenum *)); MOCK_METHOD2(invalidate, gl::Error(size_t, const GLenum *));
...@@ -48,7 +48,7 @@ class MockFramebufferImpl : public rx::FramebufferImpl ...@@ -48,7 +48,7 @@ class MockFramebufferImpl : public rx::FramebufferImpl
MOCK_METHOD1(syncState, void(const gl::Framebuffer::DirtyBits &)); MOCK_METHOD1(syncState, void(const gl::Framebuffer::DirtyBits &));
MOCK_METHOD0(destroy, void()); MOCK_METHOD0(destructor, void());
}; };
inline ::testing::NiceMock<MockFramebufferImpl> *MakeFramebufferMock() inline ::testing::NiceMock<MockFramebufferImpl> *MakeFramebufferMock()
...@@ -59,7 +59,7 @@ inline ::testing::NiceMock<MockFramebufferImpl> *MakeFramebufferMock() ...@@ -59,7 +59,7 @@ inline ::testing::NiceMock<MockFramebufferImpl> *MakeFramebufferMock()
ON_CALL(*framebufferImpl, checkStatus()).WillByDefault(::testing::Return(true)); ON_CALL(*framebufferImpl, checkStatus()).WillByDefault(::testing::Return(true));
// We must mock the destructor since NiceMock doesn't work for destructors. // We must mock the destructor since NiceMock doesn't work for destructors.
EXPECT_CALL(*framebufferImpl, destroy()).Times(1).RetiresOnSaturation(); EXPECT_CALL(*framebufferImpl, destructor()).Times(1).RetiresOnSaturation();
return framebufferImpl; return framebufferImpl;
} }
......
...@@ -33,13 +33,12 @@ class ContextImpl; ...@@ -33,13 +33,12 @@ class ContextImpl;
using LinkResult = gl::ErrorOrResult<bool>; using LinkResult = gl::ErrorOrResult<bool>;
class ContextImpl;
class ProgramImpl : angle::NonCopyable class ProgramImpl : angle::NonCopyable
{ {
public: public:
ProgramImpl(const gl::ProgramState &state) : mState(state) {} ProgramImpl(const gl::ProgramState &state) : mState(state) {}
virtual ~ProgramImpl() {} virtual ~ProgramImpl() {}
virtual void destroy(const ContextImpl *contextImpl) {}
virtual LinkResult load(const ContextImpl *contextImpl, virtual LinkResult load(const ContextImpl *contextImpl,
gl::InfoLog &infoLog, gl::InfoLog &infoLog,
......
...@@ -21,7 +21,7 @@ class MockProgramImpl : public rx::ProgramImpl ...@@ -21,7 +21,7 @@ class MockProgramImpl : public rx::ProgramImpl
{ {
public: public:
MockProgramImpl() : ProgramImpl(gl::ProgramState()) {} MockProgramImpl() : ProgramImpl(gl::ProgramState()) {}
virtual ~MockProgramImpl() { destroy(); } virtual ~MockProgramImpl() { destructor(); }
MOCK_METHOD3(load, LinkResult(const ContextImpl *, gl::InfoLog &, gl::BinaryInputStream *)); MOCK_METHOD3(load, LinkResult(const ContextImpl *, gl::InfoLog &, gl::BinaryInputStream *));
MOCK_METHOD1(save, gl::Error(gl::BinaryOutputStream *)); MOCK_METHOD1(save, gl::Error(gl::BinaryOutputStream *));
...@@ -59,7 +59,7 @@ class MockProgramImpl : public rx::ProgramImpl ...@@ -59,7 +59,7 @@ class MockProgramImpl : public rx::ProgramImpl
MOCK_METHOD4(setPathFragmentInputGen, MOCK_METHOD4(setPathFragmentInputGen,
void(const std::string &, GLenum, GLint, const GLfloat *)); void(const std::string &, GLenum, GLint, const GLfloat *));
MOCK_METHOD0(destroy, void()); MOCK_METHOD0(destructor, void());
}; };
inline ::testing::NiceMock<MockProgramImpl> *MakeProgramMock() inline ::testing::NiceMock<MockProgramImpl> *MakeProgramMock()
...@@ -67,7 +67,7 @@ inline ::testing::NiceMock<MockProgramImpl> *MakeProgramMock() ...@@ -67,7 +67,7 @@ inline ::testing::NiceMock<MockProgramImpl> *MakeProgramMock()
::testing::NiceMock<MockProgramImpl> *programImpl = new ::testing::NiceMock<MockProgramImpl>(); ::testing::NiceMock<MockProgramImpl> *programImpl = new ::testing::NiceMock<MockProgramImpl>();
// TODO(jmadill): add ON_CALLS for returning methods // TODO(jmadill): add ON_CALLS for returning methods
// We must mock the destructor since NiceMock doesn't work for destructors. // We must mock the destructor since NiceMock doesn't work for destructors.
EXPECT_CALL(*programImpl, destroy()).Times(1).RetiresOnSaturation(); EXPECT_CALL(*programImpl, destructor()).Times(1).RetiresOnSaturation();
return programImpl; return programImpl;
} }
......
...@@ -97,7 +97,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) ...@@ -97,7 +97,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
state.setVertexArrayBinding(vertexArray); state.setVertexArrayBinding(vertexArray);
state.setDrawFramebufferBinding(framebuffer); state.setDrawFramebufferBinding(framebuffer);
state.setProgram(program); state.setProgram(nullptr, program);
NiceMock<MockValidationContext> testContext(nullptr, nullptr, Version(3, 0), &state, caps, NiceMock<MockValidationContext> testContext(nullptr, nullptr, Version(3, 0), &state, caps,
textureCaps, extensions, limitations, false); textureCaps, extensions, limitations, false);
...@@ -119,7 +119,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) ...@@ -119,7 +119,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
state.setVertexArrayBinding(nullptr); state.setVertexArrayBinding(nullptr);
state.setDrawFramebufferBinding(nullptr); state.setDrawFramebufferBinding(nullptr);
state.setProgram(nullptr); state.setProgram(nullptr, nullptr);
SafeDelete(vertexArray); SafeDelete(vertexArray);
SafeDelete(framebuffer); SafeDelete(framebuffer);
......
...@@ -715,7 +715,7 @@ void GL_APIENTRY DetachShader(GLuint program, GLuint shader) ...@@ -715,7 +715,7 @@ void GL_APIENTRY DetachShader(GLuint program, GLuint shader)
return; return;
} }
if (!programObject->detachShader(shaderObject)) if (!programObject->detachShader(context, shaderObject))
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return; return;
......
...@@ -692,7 +692,7 @@ void GL_APIENTRY EndTransformFeedback(void) ...@@ -692,7 +692,7 @@ void GL_APIENTRY EndTransformFeedback(void)
return; return;
} }
transformFeedback->end(); transformFeedback->end(context);
} }
} }
......
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