Hash :
520c4ae2
Author :
Date :
2015-05-05T13:12:36
Add a Buffer::getIndexRange function. Instead of exposing the index range cache, add a more generic method that allows the buffers to handle their own caching of index ranges. BufferImpl::getData can be hard to implement for BufferGL because there isn't a way to tell the buffer to unmap and glGetBufferSubData can be very expensive, requiring an extra copy of the data. BUG=angleproject:881 Change-Id: Idec645219056132e0d72a410fbe7b971fa02c9e9 Reviewed-on: https://chromium-review.googlesource.com/261892 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Olli Etuaho <oetuaho@nvidia.com> Tested-by: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
//
// 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/Buffer.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<GLenum>(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