| Index: content/browser/compositor/buffer_queue_unittest.cc
|
| diff --git a/content/browser/compositor/buffer_queue_unittest.cc b/content/browser/compositor/buffer_queue_unittest.cc
|
| index 88ac146bcffca9391d2c15997aa9419a0e7a3a87..b8655d42f9bc2d385f6c103a75689021ed01e9b4 100644
|
| --- a/content/browser/compositor/buffer_queue_unittest.cc
|
| +++ b/content/browser/compositor/buffer_queue_unittest.cc
|
| @@ -19,24 +19,43 @@ using ::testing::Ne;
|
| using ::testing::Return;
|
|
|
| namespace content {
|
| +class MockBufferQueue : public BufferQueue {
|
| + public:
|
| + MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider,
|
| + unsigned int internalformat)
|
| + : BufferQueue(context_provider, internalformat) {}
|
| + MOCK_METHOD4(CopyBufferDamage,
|
| + void(int, int, const gfx::Rect&, const gfx::Rect&));
|
| +};
|
|
|
| class BufferQueueTest : public ::testing::Test {
|
| public:
|
| + BufferQueueTest() : doublebuffering_(true), first_frame_(true) {}
|
| +
|
| virtual void SetUp() OVERRIDE {
|
| scoped_refptr<cc::TestContextProvider> context_provider =
|
| cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create());
|
| context_provider->BindToCurrentThread();
|
| - output_surface_.reset(new BufferQueue(context_provider, GL_RGBA8_OES));
|
| + output_surface_.reset(new MockBufferQueue(context_provider, GL_RGBA8_OES));
|
| + output_surface_->Initialize();
|
| }
|
|
|
| unsigned current_surface() { return output_surface_->current_surface_.image; }
|
| const std::vector<BufferQueue::AllocatedSurface>& available_surfaces() {
|
| return output_surface_->available_surfaces_;
|
| }
|
| - const std::queue<BufferQueue::AllocatedSurface>& in_flight_surfaces() {
|
| + const std::deque<BufferQueue::AllocatedSurface>& in_flight_surfaces() {
|
| return output_surface_->in_flight_surfaces_;
|
| }
|
|
|
| + const BufferQueue::AllocatedSurface& last_frame() {
|
| + return output_surface_->in_flight_surfaces_.back();
|
| + }
|
| + const BufferQueue::AllocatedSurface& next_frame() {
|
| + return output_surface_->available_surfaces_.back();
|
| + }
|
| + const gfx::Size size() { return output_surface_->size_; }
|
| +
|
| int CountBuffers() {
|
| int n = available_surfaces().size() + in_flight_surfaces().size();
|
| if (current_surface())
|
| @@ -50,13 +69,29 @@ class BufferQueueTest : public ::testing::Test {
|
| EXPECT_TRUE(InsertUnique(&buffers, current_surface()));
|
| for (size_t i = 0; i < available_surfaces().size(); i++)
|
| EXPECT_TRUE(InsertUnique(&buffers, available_surfaces()[i].image));
|
| - std::queue<BufferQueue::AllocatedSurface> copy = in_flight_surfaces();
|
| - while (!copy.empty()) {
|
| - EXPECT_TRUE(InsertUnique(&buffers, copy.front().image));
|
| - copy.pop();
|
| - }
|
| + for (std::deque<BufferQueue::AllocatedSurface>::const_iterator it =
|
| + in_flight_surfaces().begin();
|
| + it != in_flight_surfaces().end();
|
| + ++it)
|
| + EXPECT_TRUE(InsertUnique(&buffers, it->image));
|
| + }
|
| +
|
| + void SwapBuffers() {
|
| + output_surface_->SwapBuffers(gfx::Rect(output_surface_->size_));
|
| + }
|
| +
|
| + void SendDamagedFrame(const gfx::Rect& damage) {
|
| + // We don't care about the GL-level implementation here, just how it uses
|
| + // damage rects.
|
| + output_surface_->BindFramebuffer();
|
| + output_surface_->SwapBuffers(damage);
|
| + if (doublebuffering_ || !first_frame_)
|
| + output_surface_->PageFlipComplete();
|
| + first_frame_ = false;
|
| }
|
|
|
| + void SendFullFrame() { SendDamagedFrame(gfx::Rect(output_surface_->size_)); }
|
| +
|
| protected:
|
| bool InsertUnique(std::set<unsigned>* set, unsigned value) {
|
| if (!value)
|
| @@ -67,10 +102,17 @@ class BufferQueueTest : public ::testing::Test {
|
| return true;
|
| }
|
|
|
| - scoped_ptr<BufferQueue> output_surface_;
|
| + scoped_ptr<MockBufferQueue> output_surface_;
|
| + bool doublebuffering_;
|
| + bool first_frame_;
|
| };
|
|
|
| namespace {
|
| +const gfx::Size screen_size = gfx::Size(30, 30);
|
| +const gfx::Rect screen_rect = gfx::Rect(screen_size);
|
| +const gfx::Rect small_damage = gfx::Rect(gfx::Size(10, 10));
|
| +const gfx::Rect large_damage = gfx::Rect(gfx::Size(20, 20));
|
| +const gfx::Rect overlapping_damage = gfx::Rect(gfx::Size(5, 20));
|
|
|
| class MockedContext : public cc::TestWebGraphicsContext3D {
|
| public:
|
| @@ -133,6 +175,47 @@ TEST(BufferQueueStandaloneTest, FboBinding) {
|
| output_surface->BindFramebuffer();
|
| }
|
|
|
| +TEST_F(BufferQueueTest, PartialSwapReuse) {
|
| + // Check that
|
| + output_surface_->Reshape(screen_size, 1.0f);
|
| + ASSERT_TRUE(doublebuffering_);
|
| + EXPECT_CALL(*output_surface_,
|
| + CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1);
|
| + SendFullFrame();
|
| + SendDamagedFrame(small_damage);
|
| + SendDamagedFrame(small_damage);
|
| + SendDamagedFrame(large_damage);
|
| + // Verify that the damage has propagated.
|
| + EXPECT_EQ(next_frame().damage, large_damage);
|
| +}
|
| +
|
| +TEST_F(BufferQueueTest, PartialSwapFullFrame) {
|
| + output_surface_->Reshape(screen_size, 1.0f);
|
| + ASSERT_TRUE(doublebuffering_);
|
| + EXPECT_CALL(*output_surface_,
|
| + CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1);
|
| + SendFullFrame();
|
| + SendDamagedFrame(small_damage);
|
| + SendFullFrame();
|
| + SendFullFrame();
|
| + EXPECT_EQ(next_frame().damage, screen_rect);
|
| +}
|
| +
|
| +TEST_F(BufferQueueTest, PartialSwapOverlapping) {
|
| + output_surface_->Reshape(screen_size, 1.0f);
|
| + ASSERT_TRUE(doublebuffering_);
|
| + EXPECT_CALL(*output_surface_,
|
| + CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1);
|
| + EXPECT_CALL(*output_surface_,
|
| + CopyBufferDamage(_, _, overlapping_damage, small_damage))
|
| + .Times(1);
|
| +
|
| + SendFullFrame();
|
| + SendDamagedFrame(small_damage);
|
| + SendDamagedFrame(overlapping_damage);
|
| + EXPECT_EQ(next_frame().damage, overlapping_damage);
|
| +}
|
| +
|
| TEST_F(BufferQueueTest, MultipleBindCalls) {
|
| // Check that multiple bind calls do not create or change surfaces.
|
| output_surface_->BindFramebuffer();
|
| @@ -149,7 +232,7 @@ TEST_F(BufferQueueTest, CheckDoubleBuffering) {
|
| output_surface_->BindFramebuffer();
|
| EXPECT_EQ(1, CountBuffers());
|
| EXPECT_NE(0U, current_surface());
|
| - output_surface_->SwapBuffers();
|
| + SwapBuffers();
|
| EXPECT_EQ(1U, in_flight_surfaces().size());
|
| output_surface_->PageFlipComplete();
|
| EXPECT_EQ(1U, in_flight_surfaces().size());
|
| @@ -158,7 +241,7 @@ TEST_F(BufferQueueTest, CheckDoubleBuffering) {
|
| CheckUnique();
|
| EXPECT_NE(0U, current_surface());
|
| EXPECT_EQ(1U, in_flight_surfaces().size());
|
| - output_surface_->SwapBuffers();
|
| + SwapBuffers();
|
| CheckUnique();
|
| EXPECT_EQ(2U, in_flight_surfaces().size());
|
| output_surface_->PageFlipComplete();
|
| @@ -176,10 +259,10 @@ TEST_F(BufferQueueTest, CheckTripleBuffering) {
|
|
|
| // This bit is the same sequence tested in the doublebuffering case.
|
| output_surface_->BindFramebuffer();
|
| - output_surface_->SwapBuffers();
|
| + SwapBuffers();
|
| output_surface_->PageFlipComplete();
|
| output_surface_->BindFramebuffer();
|
| - output_surface_->SwapBuffers();
|
| + SwapBuffers();
|
|
|
| EXPECT_EQ(2, CountBuffers());
|
| CheckUnique();
|
|
|