Index: blimp/client/core/compositor/delegated_output_surface_unittest.cc |
diff --git a/blimp/client/core/compositor/delegated_output_surface_unittest.cc b/blimp/client/core/compositor/delegated_output_surface_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..59fbc8e2023920143598268e919e5ecdf3333014 |
--- /dev/null |
+++ b/blimp/client/core/compositor/delegated_output_surface_unittest.cc |
@@ -0,0 +1,244 @@ |
+// Copyright 2016 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 "blimp/client/core/compositor/delegated_output_surface.h" |
+ |
+#include "base/memory/ptr_util.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "base/threading/thread_task_runner_handle.h" |
+#include "cc/output/compositor_frame.h" |
+#include "cc/test/fake_output_surface_client.h" |
+#include "cc/test/test_context_provider.h" |
+#include "cc/test/test_context_support.h" |
+#include "cc/test/test_gles2_interface.h" |
+#include "cc/test/test_web_graphics_context_3d.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace blimp { |
+namespace client { |
+namespace { |
+ |
+class FakeBlimpOutputSurfaceClient : public BlimpOutputSurfaceClient { |
+ public: |
+ FakeBlimpOutputSurfaceClient() |
+ : output_surface_(nullptr), surfaces_bound_(0), swap_count_(0) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ } |
+ |
+ ~FakeBlimpOutputSurfaceClient() override { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ EXPECT_EQ(nullptr, output_surface_); |
+ } |
+ |
+ void BindToOutputSurface(BlimpOutputSurface* output_surface) override { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ EXPECT_EQ(nullptr, output_surface_); |
+ output_surface_ = output_surface; |
+ surfaces_bound_++; |
+ } |
+ |
+ void SwapCompositorFrame(cc::CompositorFrame frame) override { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ swap_count_++; |
+ output_surface_->ReclaimCompositorResources(cc::ReturnedResourceArray()); |
+ } |
+ |
+ void UnbindOutputSurface(BlimpOutputSurface* output_surface) override { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ EXPECT_EQ(output_surface, output_surface_); |
+ output_surface_ = nullptr; |
+ } |
+ |
+ int surfaces_bound() const { return surfaces_bound_; } |
+ int swap_count() const { return swap_count_; } |
+ |
+ private: |
+ BlimpOutputSurface* output_surface_; |
+ int surfaces_bound_; |
+ int swap_count_; |
+ base::ThreadChecker thread_checker_; |
+}; |
+ |
+class TestContextProvider : public cc::TestContextProvider { |
+ public: |
+ static scoped_refptr<TestContextProvider> Create(bool bind_should_fail) { |
+ return new TestContextProvider(bind_should_fail); |
+ } |
+ |
+ protected: |
+ explicit TestContextProvider(bool bind_should_fail) |
+ : cc::TestContextProvider(base::MakeUnique<cc::TestContextSupport>(), |
+ base::MakeUnique<cc::TestGLES2Interface>(), |
+ cc::TestWebGraphicsContext3D::Create()), |
+ bind_should_fail_(bind_should_fail) {} |
+ |
+ ~TestContextProvider() override {} |
+ |
+ bool BindToCurrentThread() override { |
+ if (bind_should_fail_) |
+ return false; |
+ return cc::TestContextProvider::BindToCurrentThread(); |
+ } |
+ |
+ private: |
+ const bool bind_should_fail_; |
+}; |
+ |
+class TestDelegatedOutputSurface : public DelegatedOutputSurface { |
+ public: |
+ TestDelegatedOutputSurface( |
+ scoped_refptr<cc::ContextProvider> compositor_context_provider, |
+ scoped_refptr<cc::ContextProvider> worker_context_provider, |
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, |
+ BlimpOutputSurfaceClient* client) |
+ : DelegatedOutputSurface(compositor_context_provider, |
+ worker_context_provider, |
+ main_task_runner, |
+ compositor_task_runner, |
+ client), |
+ pending_swap_ack_count_(0), |
+ unclaimed_resources_count_(0) {} |
+ |
+ void DoSwapBuffers() { |
+ DelegatedOutputSurface::SwapBuffers(cc::CompositorFrame()); |
+ unclaimed_resources_count_++; |
+ pending_swap_ack_count_++; |
+ } |
+ |
+ void OnSwapBuffersComplete() override { pending_swap_ack_count_--; } |
+ |
+ void ReclaimResourcesOnCompositorThread( |
+ const cc::ReturnedResourceArray& resources) override { |
+ unclaimed_resources_count_--; |
+ } |
+ |
+ int pending_swap_ack_count() const { return pending_swap_ack_count_; } |
+ int unclaimed_resources_count() const { return unclaimed_resources_count_; } |
+ |
+ private: |
+ int pending_swap_ack_count_; |
+ int unclaimed_resources_count_; |
+}; |
+ |
+class DelegatedOutputSurfaceTest : public testing::Test { |
+ public: |
+ DelegatedOutputSurfaceTest() {} |
+ |
+ void SetUpTest(bool bind_should_fail) { |
+ main_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
+ compositor_thread_ = base::MakeUnique<base::Thread>("Compositor"); |
+ ASSERT_TRUE(compositor_thread_->Start()); |
+ compositor_task_runner_ = compositor_thread_->task_runner(); |
+ output_surface_ = base::MakeUnique<TestDelegatedOutputSurface>( |
+ TestContextProvider::Create(bind_should_fail), nullptr, |
+ main_task_runner_, compositor_task_runner_, |
+ &blimp_output_surface_client_); |
+ |
+ base::WaitableEvent init_event( |
+ base::WaitableEvent::ResetPolicy::AUTOMATIC, |
+ base::WaitableEvent::InitialState::NOT_SIGNALED); |
+ compositor_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&DelegatedOutputSurfaceTest::InitOnCompositorThread, |
+ base::Unretained(this), &init_event)); |
+ init_event.Wait(); |
+ BeginTest(); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ } |
+ |
+ virtual void BeginTest() = 0; |
+ |
+ void DoSwapBuffers() { |
+ compositor_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&DelegatedOutputSurfaceTest::DoSwapBuffersOnCompositorThread, |
+ base::Unretained(this))); |
+ } |
+ |
+ void TearDown() override { |
+ EXPECT_EQ(blimp_output_surface_client_.swap_count(), |
+ output_surface_client_.swap_count()); |
+ } |
+ |
+ void EndTest() { |
+ base::WaitableEvent shutdown_event( |
+ base::WaitableEvent::ResetPolicy::AUTOMATIC, |
+ base::WaitableEvent::InitialState::NOT_SIGNALED); |
+ compositor_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&DelegatedOutputSurfaceTest::ShutdownOnCompositorThread, |
+ base::Unretained(this), &shutdown_event)); |
+ shutdown_event.Wait(); |
+ compositor_thread_->Stop(); |
+ } |
+ |
+ void InitOnCompositorThread(base::WaitableEvent* event) { |
+ bound_ = output_surface_->BindToClient(&output_surface_client_); |
+ event->Signal(); |
+ } |
+ |
+ void DoSwapBuffersOnCompositorThread() { |
+ output_surface_->SwapBuffers(cc::CompositorFrame()); |
+ } |
+ |
+ void ShutdownOnCompositorThread(base::WaitableEvent* event) { |
+ EXPECT_EQ(0, output_surface_->unclaimed_resources_count()); |
+ EXPECT_EQ(0, output_surface_->pending_swap_ack_count()); |
+ if (bound_) { |
+ output_surface_->DetachFromClient(); |
+ bound_ = false; |
+ } |
+ event->Signal(); |
+ } |
+ |
+ base::MessageLoop loop_; |
+ std::unique_ptr<base::Thread> compositor_thread_; |
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; |
+ std::unique_ptr<TestDelegatedOutputSurface> output_surface_; |
+ FakeBlimpOutputSurfaceClient blimp_output_surface_client_; |
+ |
+ bool bound_ = false; |
+ cc::FakeOutputSurfaceClient output_surface_client_; |
+}; |
+ |
+class DelegatedOutputSurfaceTestBindFails : public DelegatedOutputSurfaceTest { |
+ void SetUp() override { SetUpTest(true); } |
+ |
+ void BeginTest() override { |
+ // Do nothing. We'll just check the surfaces count on tear down to make sure |
+ // there were no registrations. |
+ EndTest(); |
+ } |
+ |
+ void TearDown() override { |
+ DelegatedOutputSurfaceTest::TearDown(); |
+ EXPECT_EQ(0, blimp_output_surface_client_.surfaces_bound()); |
+ } |
+}; |
+ |
+TEST_F(DelegatedOutputSurfaceTestBindFails, NoRegistrations) {} |
David Trainor- moved to gerrit
2016/08/24 23:09:34
Can we put the test flow in here?
SetupTest(true/
Khushal
2016/08/25 02:35:39
Done.
|
+ |
+class DelegatedOutputSurfaceTestBindSucceeds |
+ : public DelegatedOutputSurfaceTest { |
+ void SetUp() override { SetUpTest(false); } |
+ |
+ void BeginTest() override { |
+ DoSwapBuffers(); |
+ DoSwapBuffers(); |
+ DoSwapBuffers(); |
+ } |
+ |
+ void TearDown() override { |
+ DelegatedOutputSurfaceTest::TearDown(); |
+ EXPECT_EQ(3, blimp_output_surface_client_.swap_count()); |
+ } |
+}; |
+ |
+TEST_F(DelegatedOutputSurfaceTestBindSucceeds, SwapBuffers) {} |
David Trainor- moved to gerrit
2016/08/24 23:09:34
Who calls EndTest? Could we just put most of this
Khushal
2016/08/25 02:35:39
Done.
|
+ |
+} // namespace |
+} // namespace client |
+} // namespace blimp |