// // Copyright (c) 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/Caps.h" #include "libANGLE/TransformFeedback.h" #include "libANGLE/renderer/BufferImpl_mock.h" #include "libANGLE/renderer/TransformFeedbackImpl_mock.h" using ::testing::_; using ::testing::Return; using ::testing::SetArgumentPointee; namespace { class TransformFeedbackTest : public testing::Test { protected: virtual void SetUp() { // Set a reasonable number of tf attributes mCaps.maxTransformFeedbackSeparateAttributes = 8; mImpl = new rx::MockTransformFeedbackImpl; EXPECT_CALL(*mImpl, destructor()); mFeedback = new gl::TransformFeedback(mImpl, 1, mCaps); mFeedback->addRef(); } virtual void TearDown() { mFeedback->release(); } rx::MockTransformFeedbackImpl* mImpl; gl::TransformFeedback* mFeedback; 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) { testing::InSequence seq; EXPECT_FALSE(mFeedback->isActive()); EXPECT_CALL(*mImpl, begin(GL_TRIANGLES)); mFeedback->begin(GL_TRIANGLES); EXPECT_TRUE(mFeedback->isActive()); EXPECT_EQ(static_cast(GL_TRIANGLES), mFeedback->getPrimitiveMode()); EXPECT_CALL(*mImpl, end()); mFeedback->end(); EXPECT_FALSE(mFeedback->isActive()); } TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume) { testing::InSequence seq; EXPECT_FALSE(mFeedback->isActive()); EXPECT_CALL(*mImpl, begin(GL_TRIANGLES)); mFeedback->begin(GL_TRIANGLES); EXPECT_FALSE(mFeedback->isPaused()); EXPECT_CALL(*mImpl, pause()); mFeedback->pause(); EXPECT_TRUE(mFeedback->isPaused()); EXPECT_CALL(*mImpl, resume()); mFeedback->resume(); EXPECT_FALSE(mFeedback->isPaused()); EXPECT_CALL(*mImpl, end()); mFeedback->end(); } TEST_F(TransformFeedbackTest, BufferBinding) { rx::MockBufferImpl *bufferImpl = new rx::MockBufferImpl; gl::Buffer *buffer = new gl::Buffer(bufferImpl, 1); EXPECT_CALL(*bufferImpl, destructor()).Times(1).RetiresOnSaturation(); static const size_t bindIndex = 0; rx::MockTransformFeedbackImpl *feedbackImpl = new rx::MockTransformFeedbackImpl; EXPECT_CALL(*feedbackImpl, destructor()).Times(1).RetiresOnSaturation(); gl::TransformFeedback *feedback = new gl::TransformFeedback(feedbackImpl, 1, mCaps); EXPECT_EQ(feedback->getIndexedBufferCount(), mCaps.maxTransformFeedbackSeparateAttributes); EXPECT_CALL(*feedbackImpl, bindGenericBuffer(_)); feedback->bindGenericBuffer(buffer); EXPECT_EQ(feedback->getGenericBuffer().get(), buffer); EXPECT_CALL(*feedbackImpl, bindIndexedBuffer(_, _)); feedback->bindIndexedBuffer(bindIndex, buffer, 0, 1); for (size_t i = 0; i < feedback->getIndexedBufferCount(); i++) { if (i == bindIndex) { EXPECT_EQ(feedback->getIndexedBuffer(i).get(), buffer); } else { EXPECT_EQ(feedback->getIndexedBuffer(i).get(), nullptr); } } feedback->addRef(); feedback->release(); testing::Mock::VerifyAndClear(bufferImpl); } } // namespace