diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 05:08:14 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 05:08:14 +0000 |
commit | 79767392a5fcd34e980a4908762327af0eb3d9dd (patch) | |
tree | 3bd2687fde45080c0d9ddc17f1d8bee8d4ba8667 /gpu | |
parent | b9677868770ec5fce03781d5d062522b0b1161e9 (diff) | |
download | chromium_src-79767392a5fcd34e980a4908762327af0eb3d9dd.zip chromium_src-79767392a5fcd34e980a4908762327af0eb3d9dd.tar.gz chromium_src-79767392a5fcd34e980a4908762327af0eb3d9dd.tar.bz2 |
Add AsyncFlush when transferbuffer is > a certain size
TEST=unit tests
BUG=113241
R=jbauman@chromium.org
Review URL: http://codereview.chromium.org/9387014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121849 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/client/client_test_helper.cc | 26 | ||||
-rw-r--r-- | gpu/command_buffer/client/client_test_helper.h | 14 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.cc | 3 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation_unittest.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/client/transfer_buffer.cc | 15 | ||||
-rw-r--r-- | gpu/command_buffer/client/transfer_buffer.h | 12 | ||||
-rw-r--r-- | gpu/command_buffer/client/transfer_buffer_unittest.cc | 58 |
8 files changed, 114 insertions, 23 deletions
diff --git a/gpu/command_buffer/client/client_test_helper.cc b/gpu/command_buffer/client/client_test_helper.cc index e6ddfad..d9942ef 100644 --- a/gpu/command_buffer/client/client_test_helper.cc +++ b/gpu/command_buffer/client/client_test_helper.cc @@ -30,10 +30,6 @@ CommandBuffer::State MockCommandBufferBase::GetLastState() { return state_; } -void MockCommandBufferBase::Flush(int32 put_offset) { - state_.put_offset = put_offset; -} - void MockCommandBufferBase::SetGetOffset(int32 get_offset) { state_.get_offset = get_offset; } @@ -98,6 +94,10 @@ int32 MockCommandBufferBase::RegisterTransferBuffer( return -1; } +void MockCommandBufferBase::FlushHelper(int32 put_offset) { + state_.put_offset = put_offset; +} + void MockCommandBufferBase::SetToken(int32 token) { GPU_NOTREACHED(); state_.token = token; @@ -127,12 +127,30 @@ MockClientCommandBuffer::MockClientCommandBuffer() { MockClientCommandBuffer::~MockClientCommandBuffer() { } +void MockClientCommandBuffer::Flush(int32 put_offset) { + FlushHelper(put_offset); +} + void MockClientCommandBuffer::DelegateToFake() { ON_CALL(*this, DestroyTransferBuffer(_)) .WillByDefault(Invoke( this, &MockCommandBufferBase::DestroyTransferBufferHelper)); } +MockClientCommandBufferMockFlush::MockClientCommandBufferMockFlush() { + DelegateToFake(); +} + +MockClientCommandBufferMockFlush::~MockClientCommandBufferMockFlush() { +} + +void MockClientCommandBufferMockFlush::DelegateToFake() { + MockClientCommandBuffer::DelegateToFake(); + ON_CALL(*this, Flush(_)) + .WillByDefault(Invoke( + this, &MockCommandBufferBase::FlushHelper)); +} + } // namespace gpu diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h index 1b32c24..25d1014 100644 --- a/gpu/command_buffer/client/client_test_helper.h +++ b/gpu/command_buffer/client/client_test_helper.h @@ -29,7 +29,6 @@ class MockCommandBufferBase : public CommandBuffer { virtual bool Initialize() OVERRIDE; virtual State GetState() OVERRIDE; virtual State GetLastState() OVERRIDE; - virtual void Flush(int32 put_offset) OVERRIDE; virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE; virtual void SetGetBuffer(int transfer_buffer_id) OVERRIDE; virtual void SetGetOffset(int32 get_offset) OVERRIDE; @@ -46,6 +45,7 @@ class MockCommandBufferBase : public CommandBuffer { // by CreateTransferBuffer. This is useful for testing expected ids. int32 GetNextFreeTransferBufferId(); + void FlushHelper(int32 put_offset); void DestroyTransferBufferHelper(int32 id); virtual void OnFlush() = 0; @@ -67,6 +67,18 @@ class MockClientCommandBuffer : public MockCommandBufferBase { MOCK_METHOD0(OnFlush, void()); MOCK_METHOD1(DestroyTransferBuffer, void(int32 id)); + virtual void Flush(int32 put_offset) OVERRIDE; + + void DelegateToFake(); +}; + +class MockClientCommandBufferMockFlush : public MockClientCommandBuffer { + public: + MockClientCommandBufferMockFlush(); + virtual ~MockClientCommandBufferMockFlush(); + + MOCK_METHOD1(Flush, void(int32 put_offset)); + void DelegateToFake(); }; diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index c58b38c..7093cd8 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -628,7 +628,8 @@ bool GLES2Implementation::Initialize( kStartingOffset, min_transfer_buffer_size, max_transfer_buffer_size, - kAlignment)) { + kAlignment, + kSizeToFlush)) { return false; } diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index d8adc44..97622ea 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -143,6 +143,9 @@ class GLES2Implementation { // used for testing only. If more things are reseved add them here. static const unsigned int kStartingOffset = kMaxSizeOfSimpleResult; + // Size in bytes to issue async flush for transfer buffer. + static const unsigned int kSizeToFlush = 256 * 1024; + // The bucket used for results. Public for testing only. static const uint32 kResultBucketId = 1; diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index feeebbb..b018a50 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -116,7 +116,8 @@ class MockTransferBuffer : public TransferBufferInterface { unsigned int result_size, unsigned int /* min_buffer_size */, unsigned int /* max_buffer_size */, - unsigned int alignment) OVERRIDE; + unsigned int alignment, + unsigned int size_to_flush) OVERRIDE; virtual int GetShmId() OVERRIDE; virtual void* GetResultBuffer() OVERRIDE; virtual int GetResultOffset() OVERRIDE; @@ -224,7 +225,8 @@ bool MockTransferBuffer::Initialize( unsigned int result_size, unsigned int /* min_buffer_size */, unsigned int /* max_buffer_size */, - unsigned int alignment) { + unsigned int alignment, + unsigned int /* size_to_flush */) { // Just check they match. return size_ == starting_buffer_size && result_size_ == result_size && diff --git a/gpu/command_buffer/client/transfer_buffer.cc b/gpu/command_buffer/client/transfer_buffer.cc index 28bb0e6..df2811f 100644 --- a/gpu/command_buffer/client/transfer_buffer.cc +++ b/gpu/command_buffer/client/transfer_buffer.cc @@ -18,7 +18,9 @@ TransferBuffer::TransferBuffer( result_size_(0), min_buffer_size_(0), max_buffer_size_(0), - alignment_(), + alignment_(0), + size_to_flush_(0), + bytes_since_last_flush_(0), buffer_id_(-1), result_buffer_(NULL), result_shm_offset_(0), @@ -34,11 +36,13 @@ bool TransferBuffer::Initialize( unsigned int result_size, unsigned int min_buffer_size, unsigned int max_buffer_size, - unsigned int alignment) { + unsigned int alignment, + unsigned int size_to_flush) { result_size_ = result_size; min_buffer_size_ = min_buffer_size; max_buffer_size_ = max_buffer_size; alignment_ = alignment; + size_to_flush_ = size_to_flush; ReallocateRingBuffer(starting_buffer_size - result_size); return HaveBuffer(); } @@ -53,6 +57,7 @@ void TransferBuffer::Free() { result_buffer_ = NULL; result_shm_offset_ = 0; ring_buffer_.reset(); + bytes_since_last_flush_ = 0; } } @@ -66,6 +71,10 @@ RingBuffer::Offset TransferBuffer::GetOffset(void* pointer) const { void TransferBuffer::FreePendingToken(void* p, unsigned int token) { ring_buffer_->FreePendingToken(p, token); + if (bytes_since_last_flush_ >= size_to_flush_ && size_to_flush_ > 0) { + helper_->Flush(); + bytes_since_last_flush_ = 0; + } } void TransferBuffer::AllocateRingBuffer(unsigned int size) { @@ -149,6 +158,7 @@ void* TransferBuffer::AllocUpTo( unsigned int max_size = ring_buffer_->GetLargestFreeOrPendingSize(); *size_allocated = std::min(max_size, size); + bytes_since_last_flush_ += *size_allocated; return ring_buffer_->Alloc(*size_allocated); } @@ -164,6 +174,7 @@ void* TransferBuffer::Alloc(unsigned int size) { return NULL; } + bytes_since_last_flush_ += size; return ring_buffer_->Alloc(size); } diff --git a/gpu/command_buffer/client/transfer_buffer.h b/gpu/command_buffer/client/transfer_buffer.h index 654465c..b3a58d2d 100644 --- a/gpu/command_buffer/client/transfer_buffer.h +++ b/gpu/command_buffer/client/transfer_buffer.h @@ -60,7 +60,8 @@ class TransferBufferInterface { unsigned int result_size, unsigned int min_buffer_size, unsigned int max_buffer_size, - unsigned int alignment) = 0; + unsigned int alignment, + unsigned int size_to_flush) = 0; virtual int GetShmId() = 0; virtual void* GetResultBuffer() = 0; @@ -94,7 +95,8 @@ class TransferBuffer : public TransferBufferInterface { unsigned int result_size, unsigned int min_buffer_size, unsigned int max_buffer_size, - unsigned int alignment) OVERRIDE; + unsigned int alignment, + unsigned int size_to_flush) OVERRIDE; virtual int GetShmId() OVERRIDE; virtual void* GetResultBuffer() OVERRIDE; virtual int GetResultOffset() OVERRIDE; @@ -131,6 +133,12 @@ class TransferBuffer : public TransferBufferInterface { // alignment for allocations unsigned int alignment_; + // Size at which to do an async flush. 0 = never. + unsigned int size_to_flush_; + + // Number of bytes since we last flushed. + unsigned int bytes_since_last_flush_; + // the current buffer. gpu::Buffer buffer_; diff --git a/gpu/command_buffer/client/transfer_buffer_unittest.cc b/gpu/command_buffer/client/transfer_buffer_unittest.cc index 26b2057..75a1b60 100644 --- a/gpu/command_buffer/client/transfer_buffer_unittest.cc +++ b/gpu/command_buffer/client/transfer_buffer_unittest.cc @@ -20,6 +20,7 @@ using ::testing::StrictMock; namespace gpu { + class TransferBufferTest : public testing::Test { protected: static const int32 kNumCommandEntries = 400; @@ -36,18 +37,28 @@ class TransferBufferTest : public testing::Test { virtual void SetUp() OVERRIDE; virtual void TearDown() OVERRIDE; - MockClientCommandBuffer* command_buffer() const { + virtual void Initialize(unsigned int size_to_flush) { + ASSERT_TRUE(transfer_buffer_->Initialize( + kTransferBufferSize, + kStartingOffset, + kTransferBufferSize, + kTransferBufferSize, + kAlignment, + size_to_flush)); + } + + MockClientCommandBufferMockFlush* command_buffer() const { return command_buffer_.get(); } - scoped_ptr<MockClientCommandBuffer> command_buffer_; + scoped_ptr<MockClientCommandBufferMockFlush> command_buffer_; scoped_ptr<CommandBufferHelper> helper_; scoped_ptr<TransferBuffer> transfer_buffer_; int32 transfer_buffer_id_; }; void TransferBufferTest::SetUp() { - command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); + command_buffer_.reset(new StrictMock<MockClientCommandBufferMockFlush>()); ASSERT_TRUE(command_buffer_->Initialize()); helper_.reset(new CommandBufferHelper(command_buffer())); @@ -56,12 +67,6 @@ void TransferBufferTest::SetUp() { transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId(); transfer_buffer_.reset(new TransferBuffer(helper_.get())); - ASSERT_TRUE(transfer_buffer_->Initialize( - kTransferBufferSize, - kStartingOffset, - kTransferBufferSize, - kTransferBufferSize, - kAlignment)); } void TransferBufferTest::TearDown() { @@ -86,6 +91,7 @@ const size_t TransferBufferTest::kTransferBufferSize; #endif TEST_F(TransferBufferTest, Basic) { + Initialize(0); EXPECT_TRUE(transfer_buffer_->HaveBuffer()); EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); EXPECT_EQ( @@ -94,6 +100,7 @@ TEST_F(TransferBufferTest, Basic) { } TEST_F(TransferBufferTest, Free) { + Initialize(0); EXPECT_TRUE(transfer_buffer_->HaveBuffer()); EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); @@ -172,6 +179,7 @@ TEST_F(TransferBufferTest, Free) { } TEST_F(TransferBufferTest, TooLargeAllocation) { + Initialize(0); // Check that we can't allocate large than max size. void* ptr = transfer_buffer_->Alloc(kTransferBufferSize + 1); EXPECT_TRUE(ptr == NULL); @@ -184,7 +192,33 @@ TEST_F(TransferBufferTest, TooLargeAllocation) { transfer_buffer_->FreePendingToken(ptr, 1); } -class MockClientCommandBufferCanFail : public MockClientCommandBuffer { +TEST_F(TransferBufferTest, Flush) { + Initialize(16u); + unsigned int size_allocated = 0; + for (int i = 0; i < 8; ++i) { + void* ptr = transfer_buffer_->AllocUpTo(8u, &size_allocated); + ASSERT_TRUE(ptr != NULL); + EXPECT_EQ(8u, size_allocated); + if (i % 2) { + EXPECT_CALL(*command_buffer(), Flush(_)) + .Times(1) + .RetiresOnSaturation(); + } + transfer_buffer_->FreePendingToken(ptr, 1); + } + for (int i = 0; i < 8; ++i) { + void* ptr = transfer_buffer_->Alloc(8u); + ASSERT_TRUE(ptr != NULL); + if (i % 2) { + EXPECT_CALL(*command_buffer(), Flush(_)) + .Times(1) + .RetiresOnSaturation(); + } + transfer_buffer_->FreePendingToken(ptr, 1); + } +} + +class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush { public: MockClientCommandBufferCanFail() { } @@ -255,7 +289,8 @@ void TransferBufferExpandContractTest::SetUp() { kStartingOffset, kMinTransferBufferSize, kMaxTransferBufferSize, - kAlignment)); + kAlignment, + 0)); } void TransferBufferExpandContractTest::TearDown() { @@ -429,6 +464,7 @@ TEST_F(TransferBufferExpandContractTest, OutOfMemory) { EXPECT_FALSE(transfer_buffer_->HaveBuffer()); } + } // namespace gpu |