| Index: content/browser/compositor/gpu_browser_compositor_output_surface_unittest.cc
|
| diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface_unittest.cc b/content/browser/compositor/gpu_browser_compositor_output_surface_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..140e425728aaf0d571317f4d9d325a90f50e9ce4
|
| --- /dev/null
|
| +++ b/content/browser/compositor/gpu_browser_compositor_output_surface_unittest.cc
|
| @@ -0,0 +1,204 @@
|
| +// Copyright 2014 The Chromium 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 "content/browser/compositor/gpu_browser_compositor_output_surface.h"
|
| +
|
| +#include <set>
|
| +
|
| +#include "cc/test/test_context_provider.h"
|
| +#include "cc/test/test_web_graphics_context_3d.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +//using ::testing::_;
|
| +
|
| +namespace content {
|
| +class BufferedOutputSurfaceTest : public ::testing::Test {
|
| + public:
|
| + virtual void SetUp() OVERRIDE {
|
| + scoped_refptr<cc::TestContextProvider> context_provider =
|
| + cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create());
|
| + context_provider->BindToCurrentThread();
|
| + output_surface_.reset(new BufferedOutputSurface(context_provider, 0));
|
| + }
|
| +
|
| + unsigned current_surface() { return output_surface_->current_surface_; }
|
| + unsigned last_surface() { return output_surface_->last_surface_; }
|
| + unsigned available_surface() { return output_surface_->available_surface_; }
|
| + unsigned in_flight_surface() { return output_surface_->in_flight_surface_; }
|
| +
|
| + int CountBuffers() {
|
| + int n = 0;
|
| + if (in_flight_surface())
|
| + n++;
|
| + if (available_surface())
|
| + n++;
|
| + if (current_surface())
|
| + n++;
|
| + if (last_surface())
|
| + n++;
|
| + return n;
|
| + }
|
| +
|
| + // Check that each buffer is unique if present.
|
| + void CheckUnique() {
|
| + std::set<unsigned> buffers;
|
| + EXPECT_TRUE(InsertUnique(&buffers, current_surface()));
|
| + EXPECT_TRUE(InsertUnique(&buffers, last_surface()));
|
| + EXPECT_TRUE(InsertUnique(&buffers, available_surface()));
|
| + EXPECT_TRUE(InsertUnique(&buffers, in_flight_surface()));
|
| + }
|
| +
|
| + protected:
|
| + bool InsertUnique(std::set<unsigned>* set, unsigned value) {
|
| + if (!value)
|
| + return true;
|
| + if (set->find(value) != set->end())
|
| + return false;
|
| + set->insert(value);
|
| + return true;
|
| + }
|
| +
|
| + scoped_ptr<BufferedOutputSurface> output_surface_;
|
| +};
|
| +
|
| +/*TEST(BufferedOutputSurfaceTest, FboBinding) {
|
| + scoped_ptr<BufferedOutputSurface> output_surface;
|
| + MockedContext *context = new MockedContext();
|
| + output_surface.reset(new
|
| +BufferedOutputSurface(scoped_ptr<TestWebGraphicsContext3D>(context), 0));
|
| + EXPECT_CALL(context, bindFramebuffer(_)).Times(AnyNumber());
|
| + EXPECT_CALL(context, bindRenderbuffer(_)).Times(1);
|
| + output_surface_->BindFramebuffer();
|
| +}*/
|
| +
|
| +TEST_F(BufferedOutputSurfaceTest, MultipleBindCalls) {
|
| + // Check that multiple bind calls do not create or change surfaces.
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(1, CountBuffers());
|
| + unsigned int fb = current_surface();
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(1, CountBuffers());
|
| + EXPECT_EQ(fb, current_surface());
|
| +}
|
| +
|
| +TEST_F(BufferedOutputSurfaceTest, CheckDoubleBuffering) {
|
| + // Check buffer flow through double buffering path.
|
| + EXPECT_EQ(0, CountBuffers());
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(1, CountBuffers());
|
| + EXPECT_NE(0U, current_surface());
|
| + output_surface_->SwapBuffers();
|
| + EXPECT_EQ(1, CountBuffers());
|
| + EXPECT_EQ(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + output_surface_->PageFlipComplete();
|
| + EXPECT_EQ(1, CountBuffers());
|
| + EXPECT_EQ(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(2, CountBuffers());
|
| + CheckUnique();
|
| + EXPECT_NE(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + output_surface_->SwapBuffers();
|
| + EXPECT_EQ(2, CountBuffers());
|
| + CheckUnique();
|
| + EXPECT_EQ(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + EXPECT_NE(0U, in_flight_surface());
|
| + EXPECT_EQ(0U, available_surface());
|
| + output_surface_->PageFlipComplete();
|
| + EXPECT_EQ(2, CountBuffers());
|
| + CheckUnique();
|
| + EXPECT_EQ(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + EXPECT_EQ(0U, in_flight_surface());
|
| + EXPECT_NE(0U, available_surface());
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(2, CountBuffers());
|
| + CheckUnique();
|
| + EXPECT_EQ(0U, available_surface());
|
| +}
|
| +
|
| +TEST_F(BufferedOutputSurfaceTest, CheckTripleBuffering) {
|
| + // Check buffer flow through triple buffering path.
|
| +
|
| + // This bit is the same sequence tested in the doublebuffering case.
|
| + output_surface_->BindFramebuffer();
|
| + output_surface_->SwapBuffers();
|
| + output_surface_->PageFlipComplete();
|
| + output_surface_->BindFramebuffer();
|
| + output_surface_->SwapBuffers();
|
| +
|
| + EXPECT_EQ(2, CountBuffers());
|
| + CheckUnique();
|
| + EXPECT_EQ(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + EXPECT_NE(0U, in_flight_surface());
|
| + EXPECT_EQ(0U, available_surface());
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(3, CountBuffers());
|
| + CheckUnique();
|
| + EXPECT_NE(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + EXPECT_NE(0U, in_flight_surface());
|
| + EXPECT_EQ(0U, available_surface());
|
| + output_surface_->PageFlipComplete();
|
| + EXPECT_EQ(3, CountBuffers());
|
| + CheckUnique();
|
| + EXPECT_NE(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + EXPECT_EQ(0U, in_flight_surface());
|
| + EXPECT_NE(0U, available_surface());
|
| +}
|
| +
|
| +TEST_F(BufferedOutputSurfaceTest, TripleBufferFreeExtra) {
|
| + // Check that if we temporarily triple buffer, the extra one won't stick
|
| + // around for too long once doublebuffering resumes.
|
| + output_surface_->BindFramebuffer();
|
| + output_surface_->SwapBuffers();
|
| + output_surface_->PageFlipComplete();
|
| +
|
| + output_surface_->BindFramebuffer();
|
| + output_surface_->SwapBuffers();
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(3, CountBuffers());
|
| + output_surface_->PageFlipComplete();
|
| +
|
| + output_surface_->SwapBuffers();
|
| + output_surface_->PageFlipComplete();
|
| +
|
| + output_surface_->BindFramebuffer();
|
| + output_surface_->SwapBuffers();
|
| + output_surface_->PageFlipComplete();
|
| +
|
| + EXPECT_EQ(2, CountBuffers());
|
| + EXPECT_EQ(0U, current_surface());
|
| + EXPECT_NE(0U, last_surface());
|
| + EXPECT_EQ(0U, in_flight_surface());
|
| + EXPECT_NE(0U, available_surface());
|
| +}
|
| +
|
| +TEST_F(BufferedOutputSurfaceTest, NoPageFlipCalls) {
|
| + // If PageFlipComplete is never called, it's expected that new buffers
|
| + // will get created and cycle through current & last. This is inefficient,
|
| + // but works.
|
| + output_surface_->BindFramebuffer();
|
| + unsigned int fb1 = current_surface();
|
| + EXPECT_EQ(1, CountBuffers());
|
| + output_surface_->BindFramebuffer();
|
| + EXPECT_EQ(2, CountBuffers());
|
| + output_surface_->SwapBuffers();
|
| + output_surface_->BindFramebuffer();
|
| + unsigned int fb2 = current_surface();
|
| + EXPECT_EQ(3, CountBuffers());
|
| + output_surface_->SwapBuffers();
|
| + EXPECT_EQ(2, CountBuffers());
|
| + EXPECT_EQ(fb1, in_flight_surface());
|
| + EXPECT_EQ(fb2, last_surface());
|
| + EXPECT_EQ(0U, current_surface());
|
| + EXPECT_EQ(0U, available_surface());
|
| +}
|
| +
|
| +} // namespace content
|
|
|