Commit 3f01e6c2 by Jamie Madill Committed by Commit Bot

Return pointers from check*Allocation.

This avoids the need to consult the resource maps twice per bind. It improves performance in applications which call Bind* often. BUG=angleproject:1333 Change-Id: I7b733cc89e50e24a2e38a2eb2dc7fd658d612e27 Reviewed-on: https://chromium-review.googlesource.com/331386Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 7d8585b8
...@@ -692,23 +692,21 @@ bool Context::isSampler(GLuint samplerName) const ...@@ -692,23 +692,21 @@ bool Context::isSampler(GLuint samplerName) const
return mResourceManager->isSampler(samplerName); return mResourceManager->isSampler(samplerName);
} }
void Context::bindArrayBuffer(unsigned int buffer) void Context::bindArrayBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.setArrayBufferBinding(buffer);
mState.setArrayBufferBinding(getBuffer(buffer));
} }
void Context::bindElementArrayBuffer(unsigned int buffer) void Context::bindElementArrayBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.getVertexArray()->setElementArrayBuffer(buffer);
mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
} }
void Context::bindTexture(GLenum target, GLuint handle) void Context::bindTexture(GLenum target, GLuint handle)
{ {
Texture *texture = NULL; Texture *texture = nullptr;
if (handle == 0) if (handle == 0)
{ {
...@@ -716,12 +714,10 @@ void Context::bindTexture(GLenum target, GLuint handle) ...@@ -716,12 +714,10 @@ void Context::bindTexture(GLenum target, GLuint handle)
} }
else else
{ {
mResourceManager->checkTextureAllocation(handle, target); texture = mResourceManager->checkTextureAllocation(handle, target);
texture = getTexture(handle);
} }
ASSERT(texture); ASSERT(texture);
mState.setSamplerTexture(target, texture); mState.setSamplerTexture(target, texture);
} }
...@@ -737,82 +733,77 @@ void Context::bindDrawFramebuffer(GLuint framebufferHandle) ...@@ -737,82 +733,77 @@ void Context::bindDrawFramebuffer(GLuint framebufferHandle)
mState.setDrawFramebufferBinding(framebuffer); mState.setDrawFramebufferBinding(framebuffer);
} }
void Context::bindRenderbuffer(GLuint renderbuffer) void Context::bindRenderbuffer(GLuint renderbufferHandle)
{ {
mResourceManager->checkRenderbufferAllocation(renderbuffer); Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle);
mState.setRenderbufferBinding(renderbuffer);
mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
} }
void Context::bindVertexArray(GLuint vertexArray) void Context::bindVertexArray(GLuint vertexArrayHandle)
{ {
checkVertexArrayAllocation(vertexArray); VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
mState.setVertexArrayBinding(vertexArray);
mState.setVertexArrayBinding(getVertexArray(vertexArray));
} }
void Context::bindSampler(GLuint textureUnit, GLuint sampler) void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
{ {
ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits); ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
mResourceManager->checkSamplerAllocation(sampler); Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle);
mState.setSamplerBinding(textureUnit, sampler);
mState.setSamplerBinding(textureUnit, getSampler(sampler));
} }
void Context::bindGenericUniformBuffer(GLuint buffer) void Context::bindGenericUniformBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.setGenericUniformBufferBinding(buffer);
mState.setGenericUniformBufferBinding(getBuffer(buffer));
} }
void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
GLuint index,
GLintptr offset,
GLsizeiptr size)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
} }
void Context::bindGenericTransformFeedbackBuffer(GLuint buffer) void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer));
} }
void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
GLuint index,
GLintptr offset,
GLsizeiptr size)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size);
} }
void Context::bindCopyReadBuffer(GLuint buffer) void Context::bindCopyReadBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.setCopyReadBufferBinding(buffer);
mState.setCopyReadBufferBinding(getBuffer(buffer));
} }
void Context::bindCopyWriteBuffer(GLuint buffer) void Context::bindCopyWriteBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.setCopyWriteBufferBinding(buffer);
mState.setCopyWriteBufferBinding(getBuffer(buffer));
} }
void Context::bindPixelPackBuffer(GLuint buffer) void Context::bindPixelPackBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.setPixelPackBufferBinding(buffer);
mState.setPixelPackBufferBinding(getBuffer(buffer));
} }
void Context::bindPixelUnpackBuffer(GLuint buffer) void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
{ {
mResourceManager->checkBufferAllocation(buffer); Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
mState.setPixelUnpackBufferBinding(buffer);
mState.setPixelUnpackBufferBinding(getBuffer(buffer));
} }
void Context::useProgram(GLuint program) void Context::useProgram(GLuint program)
...@@ -820,11 +811,11 @@ void Context::useProgram(GLuint program) ...@@ -820,11 +811,11 @@ void Context::useProgram(GLuint program)
mState.setProgram(getProgram(program)); mState.setProgram(getProgram(program));
} }
void Context::bindTransformFeedback(GLuint transformFeedback) void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
{ {
checkTransformFeedbackAllocation(transformFeedback); TransformFeedback *transformFeedback =
checkTransformFeedbackAllocation(transformFeedbackHandle);
mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback)); mState.setTransformFeedbackBinding(transformFeedback);
} }
Error Context::beginQuery(GLenum target, GLuint query) Error Context::beginQuery(GLenum target, GLuint query)
...@@ -1734,27 +1725,31 @@ EGLenum Context::getRenderBuffer() const ...@@ -1734,27 +1725,31 @@ EGLenum Context::getRenderBuffer() const
} }
} }
void Context::checkVertexArrayAllocation(GLuint vertexArray) VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
{ {
// Only called after a prior call to Gen. // Only called after a prior call to Gen.
if (!getVertexArray(vertexArray)) VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
if (!vertexArray)
{ {
VertexArray *vertexArrayObject = vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS); mVertexArrayMap[vertexArrayHandle] = vertexArray;
mVertexArrayMap[vertexArray] = vertexArrayObject;
} }
return vertexArray;
} }
void Context::checkTransformFeedbackAllocation(GLuint transformFeedback) TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
{ {
// Only called after a prior call to Gen. // Only called after a prior call to Gen.
if (!getTransformFeedback(transformFeedback)) TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
if (!transformFeedback)
{ {
TransformFeedback *transformFeedbackObject = transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
new TransformFeedback(mRenderer->createTransformFeedback(), transformFeedback, mCaps); transformFeedback->addRef();
transformFeedbackObject->addRef(); mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
mTransformFeedbackMap[transformFeedback] = transformFeedbackObject;
} }
return transformFeedback;
} }
Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer) Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
......
...@@ -108,24 +108,30 @@ class Context final : public ValidationContext ...@@ -108,24 +108,30 @@ class Context final : public ValidationContext
GLuint createVertexArray(); GLuint createVertexArray();
void deleteVertexArray(GLuint vertexArray); void deleteVertexArray(GLuint vertexArray);
void bindArrayBuffer(GLuint buffer); void bindArrayBuffer(GLuint bufferHandle);
void bindElementArrayBuffer(GLuint buffer); void bindElementArrayBuffer(GLuint bufferHandle);
void bindTexture(GLenum target, GLuint handle); void bindTexture(GLenum target, GLuint handle);
void bindReadFramebuffer(GLuint framebufferHandle); void bindReadFramebuffer(GLuint framebufferHandle);
void bindDrawFramebuffer(GLuint framebufferHandle); void bindDrawFramebuffer(GLuint framebufferHandle);
void bindRenderbuffer(GLuint renderbuffer); void bindRenderbuffer(GLuint renderbufferHandle);
void bindVertexArray(GLuint vertexArray); void bindVertexArray(GLuint vertexArrayHandle);
void bindSampler(GLuint textureUnit, GLuint sampler); void bindSampler(GLuint textureUnit, GLuint samplerHandle);
void bindGenericUniformBuffer(GLuint buffer); void bindGenericUniformBuffer(GLuint bufferHandle);
void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); void bindIndexedUniformBuffer(GLuint bufferHandle,
void bindGenericTransformFeedbackBuffer(GLuint buffer); GLuint index,
void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); GLintptr offset,
void bindCopyReadBuffer(GLuint buffer); GLsizeiptr size);
void bindCopyWriteBuffer(GLuint buffer); void bindGenericTransformFeedbackBuffer(GLuint bufferHandle);
void bindPixelPackBuffer(GLuint buffer); void bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
void bindPixelUnpackBuffer(GLuint buffer); GLuint index,
GLintptr offset,
GLsizeiptr size);
void bindCopyReadBuffer(GLuint bufferHandle);
void bindCopyWriteBuffer(GLuint bufferHandle);
void bindPixelPackBuffer(GLuint bufferHandle);
void bindPixelUnpackBuffer(GLuint bufferHandle);
void useProgram(GLuint program); void useProgram(GLuint program);
void bindTransformFeedback(GLuint transformFeedback); void bindTransformFeedback(GLuint transformFeedbackHandle);
Error beginQuery(GLenum target, GLuint query); Error beginQuery(GLenum target, GLuint query);
Error endQuery(GLenum target); Error endQuery(GLenum target);
...@@ -397,8 +403,8 @@ class Context final : public ValidationContext ...@@ -397,8 +403,8 @@ class Context final : public ValidationContext
void syncStateForTexImage(); void syncStateForTexImage();
void syncStateForClear(); void syncStateForClear();
void syncStateForBlit(); void syncStateForBlit();
void checkVertexArrayAllocation(GLuint vertexArray); VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle);
void checkTransformFeedbackAllocation(GLuint transformFeedback); TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback);
Framebuffer *checkFramebufferAllocation(GLuint framebufferHandle); Framebuffer *checkFramebufferAllocation(GLuint framebufferHandle);
void detachBuffer(GLuint buffer); void detachBuffer(GLuint buffer);
......
...@@ -356,96 +356,117 @@ void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) ...@@ -356,96 +356,117 @@ void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
mRenderbufferMap[handle] = buffer; mRenderbufferMap[handle] = buffer;
} }
void ResourceManager::checkBufferAllocation(GLuint handle) Buffer *ResourceManager::checkBufferAllocation(GLuint handle)
{ {
if (handle != 0) if (handle == 0)
{ {
auto bufferMapIt = mBufferMap.find(handle); return nullptr;
bool handleAllocated = (bufferMapIt != mBufferMap.end()); }
if (handleAllocated && bufferMapIt->second != nullptr) auto bufferMapIt = mBufferMap.find(handle);
{ bool handleAllocated = (bufferMapIt != mBufferMap.end());
return;
}
Buffer *buffer = new Buffer(mFactory->createBuffer(), handle); if (handleAllocated && bufferMapIt->second != nullptr)
buffer->addRef(); {
return bufferMapIt->second;
}
if (handleAllocated) Buffer *buffer = new Buffer(mFactory->createBuffer(), handle);
{ buffer->addRef();
bufferMapIt->second = buffer;
} if (handleAllocated)
else {
{ bufferMapIt->second = buffer;
mBufferHandleAllocator.reserve(handle);
mBufferMap[handle] = buffer;
}
} }
else
{
mBufferHandleAllocator.reserve(handle);
mBufferMap[handle] = buffer;
}
return buffer;
} }
void ResourceManager::checkTextureAllocation(GLuint handle, GLenum type) Texture *ResourceManager::checkTextureAllocation(GLuint handle, GLenum type)
{ {
if (handle != 0) if (handle == 0)
{ {
auto textureMapIt = mTextureMap.find(handle); return nullptr;
bool handleAllocated = (textureMapIt != mTextureMap.end()); }
if (handleAllocated && textureMapIt->second != nullptr) auto textureMapIt = mTextureMap.find(handle);
{ bool handleAllocated = (textureMapIt != mTextureMap.end());
return;
}
Texture *texture = new Texture(mFactory->createTexture(type), handle, type); if (handleAllocated && textureMapIt->second != nullptr)
texture->addRef(); {
return textureMapIt->second;
}
if (handleAllocated) Texture *texture = new Texture(mFactory->createTexture(type), handle, type);
{ texture->addRef();
textureMapIt->second = texture;
} if (handleAllocated)
else {
{ textureMapIt->second = texture;
mTextureHandleAllocator.reserve(handle); }
mTextureMap[handle] = texture; else
} {
mTextureHandleAllocator.reserve(handle);
mTextureMap[handle] = texture;
} }
return texture;
} }
void ResourceManager::checkRenderbufferAllocation(GLuint handle) Renderbuffer *ResourceManager::checkRenderbufferAllocation(GLuint handle)
{ {
if (handle != 0) if (handle == 0)
{ {
auto renderbufferMapIt = mRenderbufferMap.find(handle); return nullptr;
bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end()); }
if (handleAllocated && renderbufferMapIt->second != nullptr) auto renderbufferMapIt = mRenderbufferMap.find(handle);
{ bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
return;
}
Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle); if (handleAllocated && renderbufferMapIt->second != nullptr)
renderbuffer->addRef(); {
return renderbufferMapIt->second;
}
if (handleAllocated) Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle);
{ renderbuffer->addRef();
renderbufferMapIt->second = renderbuffer;
} if (handleAllocated)
else {
{ renderbufferMapIt->second = renderbuffer;
mRenderbufferHandleAllocator.reserve(handle);
mRenderbufferMap[handle] = renderbuffer;
}
} }
else
{
mRenderbufferHandleAllocator.reserve(handle);
mRenderbufferMap[handle] = renderbuffer;
}
return renderbuffer;
} }
void ResourceManager::checkSamplerAllocation(GLuint sampler) Sampler *ResourceManager::checkSamplerAllocation(GLuint samplerHandle)
{ {
if (sampler != 0 && !getSampler(sampler)) // Samplers cannot be created via Bind
if (samplerHandle == 0)
{ {
Sampler *samplerObject = new Sampler(mFactory, sampler); return nullptr;
mSamplerMap[sampler] = samplerObject;
samplerObject->addRef();
// Samplers cannot be created via Bind
} }
Sampler *sampler = getSampler(samplerHandle);
if (!sampler)
{
sampler = new Sampler(mFactory, samplerHandle);
mSamplerMap[samplerHandle] = sampler;
sampler->addRef();
}
return sampler;
} }
bool ResourceManager::isSampler(GLuint sampler) bool ResourceManager::isSampler(GLuint sampler)
...@@ -453,4 +474,4 @@ bool ResourceManager::isSampler(GLuint sampler) ...@@ -453,4 +474,4 @@ bool ResourceManager::isSampler(GLuint sampler)
return mSamplerMap.find(sampler) != mSamplerMap.end(); return mSamplerMap.find(sampler) != mSamplerMap.end();
} }
} } // namespace gl
...@@ -69,10 +69,10 @@ class ResourceManager : angle::NonCopyable ...@@ -69,10 +69,10 @@ class ResourceManager : angle::NonCopyable
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer); void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
void checkBufferAllocation(GLuint handle); Buffer *checkBufferAllocation(GLuint handle);
void checkTextureAllocation(GLuint handle, GLenum type); Texture *checkTextureAllocation(GLuint handle, GLenum type);
void checkRenderbufferAllocation(GLuint handle); Renderbuffer *checkRenderbufferAllocation(GLuint handle);
void checkSamplerAllocation(GLuint sampler); Sampler *checkSamplerAllocation(GLuint samplerHandle);
bool isSampler(GLuint sampler); bool isSampler(GLuint sampler);
...@@ -110,6 +110,6 @@ class ResourceManager : angle::NonCopyable ...@@ -110,6 +110,6 @@ class ResourceManager : angle::NonCopyable
HandleAllocator mFenceSyncHandleAllocator; HandleAllocator mFenceSyncHandleAllocator;
}; };
} } // namespace gl
#endif // LIBANGLE_RESOURCEMANAGER_H_ #endif // LIBANGLE_RESOURCEMANAGER_H_
...@@ -8,14 +8,15 @@ ...@@ -8,14 +8,15 @@
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/renderer/ImplFactory.h"
#include "libANGLE/renderer/TransformFeedbackImpl.h" #include "libANGLE/renderer/TransformFeedbackImpl.h"
namespace gl namespace gl
{ {
TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl *impl, GLuint id, const Caps &caps) TransformFeedback::TransformFeedback(rx::ImplFactory *implFactory, GLuint id, const Caps &caps)
: RefCountObject(id), : RefCountObject(id),
mImplementation(impl), mImplementation(implFactory->createTransformFeedback()),
mLabel(), mLabel(),
mActive(false), mActive(false),
mPrimitiveMode(GL_NONE), mPrimitiveMode(GL_NONE),
...@@ -23,7 +24,7 @@ TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl *impl, GLuint id, ...@@ -23,7 +24,7 @@ TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl *impl, GLuint id,
mGenericBuffer(), mGenericBuffer(),
mIndexedBuffers(caps.maxTransformFeedbackSeparateAttributes) mIndexedBuffers(caps.maxTransformFeedbackSeparateAttributes)
{ {
ASSERT(impl != NULL); ASSERT(mImplementation != nullptr);
} }
TransformFeedback::~TransformFeedback() TransformFeedback::~TransformFeedback()
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace rx namespace rx
{ {
class ImplFactory;
class TransformFeedbackImpl; class TransformFeedbackImpl;
} }
...@@ -27,7 +28,7 @@ struct Caps; ...@@ -27,7 +28,7 @@ struct Caps;
class TransformFeedback final : public RefCountObject, public LabeledObject class TransformFeedback final : public RefCountObject, public LabeledObject
{ {
public: public:
TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id, const Caps &caps); TransformFeedback(rx::ImplFactory *implFactory, GLuint id, const Caps &caps);
virtual ~TransformFeedback(); virtual ~TransformFeedback();
void setLabel(const std::string &label) override; void setLabel(const std::string &label) override;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/TransformFeedback.h" #include "libANGLE/TransformFeedback.h"
#include "libANGLE/renderer/BufferImpl_mock.h" #include "libANGLE/renderer/BufferImpl_mock.h"
#include "libANGLE/renderer/TransformFeedbackImpl_mock.h" #include "libANGLE/renderer/TransformFeedbackImpl_mock.h"
#include "tests/angle_unittests_utils.h"
using ::testing::_; using ::testing::_;
using ::testing::Return; using ::testing::Return;
...@@ -19,45 +20,51 @@ using ::testing::SetArgumentPointee; ...@@ -19,45 +20,51 @@ using ::testing::SetArgumentPointee;
namespace namespace
{ {
class MockFactory : public rx::NullFactory
{
public:
MOCK_METHOD0(createTransformFeedback, rx::TransformFeedbackImpl *());
};
class TransformFeedbackTest : public testing::Test class TransformFeedbackTest : public testing::Test
{ {
protected: protected:
virtual void SetUp() TransformFeedbackTest() : mImpl(nullptr), mFeedback(nullptr) {}
void SetUp() override
{ {
mImpl = new rx::MockTransformFeedbackImpl;
EXPECT_CALL(mMockFactory, createTransformFeedback())
.WillOnce(Return(mImpl))
.RetiresOnSaturation();
// Set a reasonable number of tf attributes // Set a reasonable number of tf attributes
mCaps.maxTransformFeedbackSeparateAttributes = 8; mCaps.maxTransformFeedbackSeparateAttributes = 8;
mImpl = new rx::MockTransformFeedbackImpl;
EXPECT_CALL(*mImpl, destructor()); EXPECT_CALL(*mImpl, destructor());
mFeedback = new gl::TransformFeedback(mImpl, 1, mCaps); mFeedback = new gl::TransformFeedback(&mMockFactory, 1, mCaps);
mFeedback->addRef(); mFeedback->addRef();
} }
virtual void TearDown() void TearDown() override
{ {
mFeedback->release(); if (mFeedback)
{
mFeedback->release();
}
// Only needed because the mock is leaked if bugs are present,
// which logs an error, but does not cause the test to fail.
// Ordinarily mocks are verified when destroyed.
testing::Mock::VerifyAndClear(mImpl);
} }
MockFactory mMockFactory;
rx::MockTransformFeedbackImpl* mImpl; rx::MockTransformFeedbackImpl* mImpl;
gl::TransformFeedback* mFeedback; gl::TransformFeedback* mFeedback;
gl::Caps mCaps; gl::Caps mCaps;
}; };
TEST_F(TransformFeedbackTest, DestructionDeletesImpl)
{
rx::MockTransformFeedbackImpl* impl = new rx::MockTransformFeedbackImpl;
EXPECT_CALL(*impl, destructor()).Times(1).RetiresOnSaturation();
gl::TransformFeedback* feedback = new gl::TransformFeedback(impl, 1, mCaps);
feedback->addRef();
feedback->release();
// Only needed because the mock is leaked if bugs are present,
// which logs an error, but does not cause the test to fail.
// Ordinarily mocks are verified when destroyed.
testing::Mock::VerifyAndClear(impl);
}
TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop) TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop)
{ {
testing::InSequence seq; testing::InSequence seq;
...@@ -98,35 +105,36 @@ TEST_F(TransformFeedbackTest, BufferBinding) ...@@ -98,35 +105,36 @@ TEST_F(TransformFeedbackTest, BufferBinding)
static const size_t bindIndex = 0; static const size_t bindIndex = 0;
rx::MockTransformFeedbackImpl *feedbackImpl = new rx::MockTransformFeedbackImpl; EXPECT_EQ(mFeedback->getIndexedBufferCount(), mCaps.maxTransformFeedbackSeparateAttributes);
EXPECT_CALL(*feedbackImpl, destructor()).Times(1).RetiresOnSaturation();
gl::TransformFeedback *feedback = new gl::TransformFeedback(feedbackImpl, 1, mCaps);
EXPECT_EQ(feedback->getIndexedBufferCount(), mCaps.maxTransformFeedbackSeparateAttributes); EXPECT_CALL(*mImpl, bindGenericBuffer(_));
mFeedback->bindGenericBuffer(buffer);
EXPECT_EQ(mFeedback->getGenericBuffer().get(), buffer);
EXPECT_CALL(*feedbackImpl, bindGenericBuffer(_)); EXPECT_CALL(*mImpl, bindIndexedBuffer(_, _));
feedback->bindGenericBuffer(buffer); mFeedback->bindIndexedBuffer(bindIndex, buffer, 0, 1);
EXPECT_EQ(feedback->getGenericBuffer().get(), buffer); for (size_t i = 0; i < mFeedback->getIndexedBufferCount(); i++)
EXPECT_CALL(*feedbackImpl, bindIndexedBuffer(_, _));
feedback->bindIndexedBuffer(bindIndex, buffer, 0, 1);
for (size_t i = 0; i < feedback->getIndexedBufferCount(); i++)
{ {
if (i == bindIndex) if (i == bindIndex)
{ {
EXPECT_EQ(feedback->getIndexedBuffer(i).get(), buffer); EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), buffer);
} }
else else
{ {
EXPECT_EQ(feedback->getIndexedBuffer(i).get(), nullptr); EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), nullptr);
} }
} }
feedback->addRef(); // force-release the feedback object to ensure the buffer is released.
feedback->release(); const size_t releaseCount = mFeedback->getRefCount();
for (size_t count = 0; count < releaseCount; ++count)
{
mFeedback->release();
}
mFeedback = nullptr;
testing::Mock::VerifyAndClear(bufferImpl); testing::Mock::VerifyAndClear(bufferImpl);
} }
} // namespace } // anonymous namespace
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