OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "blimp/client/core/compositor/delegated_output_surface.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/memory/ptr_util.h" | |
9 #include "base/run_loop.h" | |
10 #include "base/synchronization/waitable_event.h" | |
11 #include "base/threading/thread_task_runner_handle.h" | |
12 #include "cc/output/compositor_frame.h" | |
13 #include "cc/test/fake_output_surface_client.h" | |
14 #include "cc/test/test_context_provider.h" | |
15 #include "cc/test/test_context_support.h" | |
16 #include "cc/test/test_gles2_interface.h" | |
17 #include "cc/test/test_web_graphics_context_3d.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 | |
20 namespace blimp { | |
21 namespace client { | |
22 namespace { | |
23 | |
24 class FakeBlimpOutputSurfaceClient : public BlimpOutputSurfaceClient { | |
25 public: | |
26 FakeBlimpOutputSurfaceClient( | |
27 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner) | |
28 : compositor_task_runner_(compositor_task_runner), | |
29 output_surface_(nullptr), | |
30 swap_count_(0), | |
31 weak_factory_(this) { | |
32 DCHECK(thread_checker_.CalledOnValidThread()); | |
33 } | |
34 | |
35 ~FakeBlimpOutputSurfaceClient() override { | |
36 DCHECK(thread_checker_.CalledOnValidThread()); | |
37 } | |
38 | |
39 base::WeakPtr<FakeBlimpOutputSurfaceClient> GetWeakPtr() { | |
40 return weak_factory_.GetWeakPtr(); | |
41 } | |
42 | |
43 void BindToOutputSurface( | |
44 base::WeakPtr<BlimpOutputSurface> output_surface) override { | |
45 DCHECK(thread_checker_.CalledOnValidThread()); | |
46 EXPECT_EQ(nullptr, output_surface_); | |
47 output_surface_ = output_surface; | |
48 bound_ = true; | |
49 } | |
50 | |
51 void SwapCompositorFrame(cc::CompositorFrame frame) override { | |
52 DCHECK(thread_checker_.CalledOnValidThread()); | |
53 swap_count_++; | |
54 } | |
55 | |
56 void UnbindOutputSurface() override { | |
57 DCHECK(bound_); | |
58 bound_ = true; | |
59 DCHECK(thread_checker_.CalledOnValidThread()); | |
60 output_surface_ = nullptr; | |
61 } | |
62 | |
63 int swap_count() const { return swap_count_; } | |
64 bool bound() const { return bound_; } | |
65 | |
66 private: | |
67 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; | |
68 bool bound_ = false; | |
69 base::WeakPtr<BlimpOutputSurface> output_surface_; | |
70 int swap_count_; | |
71 base::ThreadChecker thread_checker_; | |
72 base::WeakPtrFactory<FakeBlimpOutputSurfaceClient> weak_factory_; | |
73 }; | |
74 | |
75 class TestContextProvider : public cc::TestContextProvider { | |
76 public: | |
77 static scoped_refptr<TestContextProvider> Create(bool bind_should_fail) { | |
78 return new TestContextProvider(bind_should_fail); | |
79 } | |
80 | |
81 protected: | |
82 explicit TestContextProvider(bool bind_should_fail) | |
83 : cc::TestContextProvider(base::MakeUnique<cc::TestContextSupport>(), | |
84 base::MakeUnique<cc::TestGLES2Interface>(), | |
85 cc::TestWebGraphicsContext3D::Create()), | |
86 bind_should_fail_(bind_should_fail) {} | |
87 | |
88 ~TestContextProvider() override {} | |
89 | |
90 bool BindToCurrentThread() override { | |
91 if (bind_should_fail_) | |
92 return false; | |
93 return cc::TestContextProvider::BindToCurrentThread(); | |
94 } | |
95 | |
96 private: | |
97 const bool bind_should_fail_; | |
98 }; | |
99 | |
100 class DelegatedOutputSurfaceTest : public testing::Test { | |
101 public: | |
102 DelegatedOutputSurfaceTest() {} | |
103 | |
104 void SetUpTest(bool bind_should_fail) { | |
105 main_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
106 compositor_thread_ = base::MakeUnique<base::Thread>("Compositor"); | |
107 ASSERT_TRUE(compositor_thread_->Start()); | |
108 compositor_task_runner_ = compositor_thread_->task_runner(); | |
109 blimp_output_surface_client_ = | |
110 base::MakeUnique<FakeBlimpOutputSurfaceClient>(compositor_task_runner_); | |
111 output_surface_ = base::MakeUnique<DelegatedOutputSurface>( | |
112 TestContextProvider::Create(bind_should_fail), nullptr, | |
113 main_task_runner_, blimp_output_surface_client_->GetWeakPtr()); | |
114 | |
115 base::WaitableEvent init_event( | |
116 base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
117 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
118 compositor_task_runner_->PostTask( | |
119 FROM_HERE, | |
120 base::Bind(&DelegatedOutputSurfaceTest::InitOnCompositorThread, | |
121 base::Unretained(this), &init_event)); | |
122 init_event.Wait(); | |
123 | |
124 // Run all tasks so the registration of the BlimpOutputSurface on the main | |
125 // thread completes. | |
126 base::RunLoop().RunUntilIdle(); | |
127 } | |
128 | |
129 void DoSwapBuffers() { | |
130 base::WaitableEvent swap_event( | |
131 base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
132 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
133 compositor_task_runner_->PostTask( | |
134 FROM_HERE, | |
135 base::Bind(&DelegatedOutputSurfaceTest::DoSwapBuffersOnCompositorThread, | |
136 base::Unretained(this), &swap_event)); | |
137 swap_event.Wait(); | |
138 } | |
139 | |
140 void TearDown() override { | |
141 EXPECT_EQ(blimp_output_surface_client_->swap_count(), | |
142 output_surface_client_.swap_count()); | |
143 } | |
144 | |
145 void EndTest() { | |
146 base::WaitableEvent shutdown_event( | |
147 base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
148 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
149 compositor_task_runner_->PostTask( | |
150 FROM_HERE, | |
151 base::Bind(&DelegatedOutputSurfaceTest::ShutdownOnCompositorThread, | |
152 base::Unretained(this), &shutdown_event)); | |
153 shutdown_event.Wait(); | |
154 compositor_thread_->Stop(); | |
155 | |
156 // Run all tasks so the unregistration of the BlimpOutputSurface on the main | |
157 // thread completes. | |
158 base::RunLoop().RunUntilIdle(); | |
159 } | |
160 | |
161 void InitOnCompositorThread(base::WaitableEvent* event) { | |
162 bound_ = output_surface_->BindToClient(&output_surface_client_); | |
163 event->Signal(); | |
164 } | |
165 | |
166 void DoSwapBuffersOnCompositorThread(base::WaitableEvent* event) { | |
167 output_surface_->SwapBuffers(cc::CompositorFrame()); | |
168 event->Signal(); | |
169 } | |
170 | |
171 void ShutdownOnCompositorThread(base::WaitableEvent* event) { | |
172 base::RunLoop().RunUntilIdle(); | |
173 if (bound_) { | |
174 output_surface_->DetachFromClient(); | |
175 bound_ = false; | |
176 } | |
177 output_surface_.reset(); | |
178 event->Signal(); | |
179 } | |
180 | |
181 base::MessageLoop loop_; | |
182 std::unique_ptr<base::Thread> compositor_thread_; | |
183 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | |
184 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; | |
185 std::unique_ptr<DelegatedOutputSurface> output_surface_; | |
186 std::unique_ptr<FakeBlimpOutputSurfaceClient> blimp_output_surface_client_; | |
187 | |
188 bool bound_ = false; | |
189 cc::FakeOutputSurfaceClient output_surface_client_; | |
190 }; | |
191 | |
192 TEST_F(DelegatedOutputSurfaceTest, BindFails) { | |
193 SetUpTest(true); | |
194 EXPECT_FALSE(blimp_output_surface_client_->bound()); | |
195 EndTest(); | |
196 } | |
197 | |
198 TEST_F(DelegatedOutputSurfaceTest, BindSucceedsSwapBuffers) { | |
199 SetUpTest(false); | |
200 EXPECT_TRUE(blimp_output_surface_client_->bound()); | |
201 | |
202 DoSwapBuffers(); | |
203 DoSwapBuffers(); | |
204 DoSwapBuffers(); | |
205 | |
206 // Run all tasks so the swap buffer calls to the BlimpOutputSurface on the | |
207 // main thread complete. | |
208 base::RunLoop().RunUntilIdle(); | |
209 EXPECT_EQ(3, blimp_output_surface_client_->swap_count()); | |
210 | |
211 EndTest(); | |
212 } | |
213 | |
214 } // namespace | |
215 } // namespace client | |
216 } // namespace blimp | |
OLD | NEW |