blob: e3bb35070a61f54ebf61abd54b2467ebafa05452 [file] [log] [blame]
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "libANGLE/Fence.h"
#include "libANGLE/renderer/FenceNVImpl.h"
#include "libANGLE/renderer/SyncImpl.h"
using ::testing::_;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgumentPointee;
namespace
{
//
// FenceNV tests
//
class MockFenceNVImpl : public rx::FenceNVImpl
{
public:
virtual ~MockFenceNVImpl() { destroy(); }
MOCK_METHOD2(set, angle::Result(const gl::Context *, GLenum));
MOCK_METHOD2(test, angle::Result(const gl::Context *, GLboolean *));
MOCK_METHOD1(finish, angle::Result(const gl::Context *));
MOCK_METHOD0(destroy, void());
};
class FenceNVTest : public testing::Test
{
protected:
virtual void SetUp()
{
mImpl = new MockFenceNVImpl;
EXPECT_CALL(*mImpl, destroy());
mFence = new gl::FenceNV(mImpl);
}
virtual void TearDown() { delete mFence; }
MockFenceNVImpl *mImpl;
gl::FenceNV *mFence;
};
TEST_F(FenceNVTest, DestructionDeletesImpl)
{
MockFenceNVImpl *impl = new MockFenceNVImpl;
EXPECT_CALL(*impl, destroy()).Times(1).RetiresOnSaturation();
gl::FenceNV *fence = new gl::FenceNV(impl);
delete fence;
// 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(FenceNVTest, SetAndTestBehavior)
{
EXPECT_CALL(*mImpl, set(_, _)).WillOnce(Return(angle::Result::Continue)).RetiresOnSaturation();
EXPECT_FALSE(mFence->isSet());
EXPECT_EQ(angle::Result::Continue, mFence->set(nullptr, GL_ALL_COMPLETED_NV));
EXPECT_TRUE(mFence->isSet());
// Fake the behavior of testing the fence before and after it's passed.
EXPECT_CALL(*mImpl, test(_, _))
.WillOnce(DoAll(SetArgumentPointee<1>(static_cast<GLboolean>(GL_FALSE)),
Return(angle::Result::Continue)))
.WillOnce(DoAll(SetArgumentPointee<1>(static_cast<GLboolean>(GL_TRUE)),
Return(angle::Result::Continue)))
.RetiresOnSaturation();
GLboolean out;
EXPECT_EQ(angle::Result::Continue, mFence->test(nullptr, &out));
EXPECT_EQ(GL_FALSE, out);
EXPECT_EQ(angle::Result::Continue, mFence->test(nullptr, &out));
EXPECT_EQ(GL_TRUE, out);
}
//
// Sync tests
//
class MockSyncImpl : public rx::SyncImpl
{
public:
virtual ~MockSyncImpl() { destroy(); }
MOCK_METHOD3(set, angle::Result(const gl::Context *, GLenum, GLbitfield));
MOCK_METHOD4(clientWait, angle::Result(const gl::Context *, GLbitfield, GLuint64, GLenum *));
MOCK_METHOD3(serverWait, angle::Result(const gl::Context *, GLbitfield, GLuint64));
MOCK_METHOD2(getStatus, angle::Result(const gl::Context *, GLint *));
MOCK_METHOD0(destroy, void());
};
class FenceSyncTest : public testing::Test
{
protected:
virtual void SetUp()
{
mImpl = new MockSyncImpl;
EXPECT_CALL(*mImpl, destroy());
mFence = new gl::Sync(mImpl, 1);
mFence->addRef();
}
virtual void TearDown() { mFence->release(nullptr); }
MockSyncImpl *mImpl;
gl::Sync *mFence;
};
TEST_F(FenceSyncTest, DestructionDeletesImpl)
{
MockSyncImpl *impl = new MockSyncImpl;
EXPECT_CALL(*impl, destroy()).Times(1).RetiresOnSaturation();
gl::Sync *fence = new gl::Sync(impl, 1);
fence->addRef();
fence->release(nullptr);
// 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(FenceSyncTest, SetAndGetStatusBehavior)
{
EXPECT_CALL(*mImpl, set(_, _, _))
.WillOnce(Return(angle::Result::Continue))
.RetiresOnSaturation();
EXPECT_EQ(angle::Result::Continue, mFence->set(nullptr, GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
EXPECT_EQ(static_cast<GLenum>(GL_SYNC_GPU_COMMANDS_COMPLETE), mFence->getCondition());
// Fake the behavior of testing the fence before and after it's passed.
EXPECT_CALL(*mImpl, getStatus(_, _))
.WillOnce(DoAll(SetArgumentPointee<1>(GL_UNSIGNALED), Return(angle::Result::Continue)))
.WillOnce(DoAll(SetArgumentPointee<1>(GL_SIGNALED), Return(angle::Result::Continue)))
.RetiresOnSaturation();
GLint out;
EXPECT_EQ(angle::Result::Continue, mFence->getStatus(nullptr, &out));
EXPECT_EQ(GL_UNSIGNALED, out);
EXPECT_EQ(angle::Result::Continue, mFence->getStatus(nullptr, &out));
EXPECT_EQ(GL_SIGNALED, out);
}
} // namespace