Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: ui/compositor/compositor_unittest.cc

Issue 2773433003: Fix CompositorResizeLock to do something. (Closed)
Patch Set: resizelock: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdint.h> 5 #include <stdint.h>
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/test/test_mock_time_task_runner.h"
9 #include "base/threading/thread_task_runner_handle.h" 10 #include "base/threading/thread_task_runner_handle.h"
10 #include "cc/output/begin_frame_args.h" 11 #include "cc/output/begin_frame_args.h"
11 #include "cc/surfaces/local_surface_id_allocator.h" 12 #include "cc/surfaces/local_surface_id_allocator.h"
12 #include "cc/surfaces/surface_factory.h" 13 #include "cc/surfaces/surface_factory.h"
13 #include "cc/surfaces/surface_factory_client.h" 14 #include "cc/surfaces/surface_factory_client.h"
14 #include "cc/surfaces/surface_manager.h" 15 #include "cc/surfaces/surface_manager.h"
15 #include "cc/test/begin_frame_args_test.h" 16 #include "cc/test/begin_frame_args_test.h"
16 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/compositor/compositor.h" 19 #include "ui/compositor/compositor.h"
19 #include "ui/compositor/layer.h" 20 #include "ui/compositor/layer.h"
20 #include "ui/compositor/test/context_factories_for_test.h" 21 #include "ui/compositor/test/context_factories_for_test.h"
21 #include "ui/compositor/test/draw_waiter_for_test.h" 22 #include "ui/compositor/test/draw_waiter_for_test.h"
22 23
23 using testing::Mock; 24 using testing::Mock;
24 using testing::_; 25 using testing::_;
25 26
26 namespace ui { 27 namespace ui {
27 namespace { 28 namespace {
28 29
29 // Test fixture for tests that require a ui::Compositor with a real task
30 // runner.
31 class CompositorTest : public testing::Test { 30 class CompositorTest : public testing::Test {
32 public: 31 public:
33 CompositorTest() {} 32 CompositorTest() {}
34 ~CompositorTest() override {} 33 ~CompositorTest() override {}
35 34
36 void SetUp() override { 35 void SetUp() override {
37 task_runner_ = base::ThreadTaskRunnerHandle::Get();
38
39 ui::ContextFactory* context_factory = nullptr; 36 ui::ContextFactory* context_factory = nullptr;
40 ui::ContextFactoryPrivate* context_factory_private = nullptr; 37 ui::ContextFactoryPrivate* context_factory_private = nullptr;
41 ui::InitializeContextFactoryForTests(false, &context_factory, 38 ui::InitializeContextFactoryForTests(false, &context_factory,
42 &context_factory_private); 39 &context_factory_private);
43 40
44 compositor_.reset(new ui::Compositor( 41 compositor_.reset(new ui::Compositor(
45 context_factory_private->AllocateFrameSinkId(), context_factory, 42 context_factory_private->AllocateFrameSinkId(), context_factory,
46 context_factory_private, task_runner_)); 43 context_factory_private, CreateTaskRunner()));
47 compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); 44 compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
48 } 45 }
46
49 void TearDown() override { 47 void TearDown() override {
50 compositor_.reset(); 48 compositor_.reset();
51 ui::TerminateContextFactoryForTests(); 49 ui::TerminateContextFactoryForTests();
52 } 50 }
53 51
54 protected: 52 void DestroyCompositor() { compositor_.reset(); }
55 base::SingleThreadTaskRunner* task_runner() { return task_runner_.get(); } 53
54 protected:
55 virtual scoped_refptr<base::SingleThreadTaskRunner> CreateTaskRunner() = 0;
56
56 ui::Compositor* compositor() { return compositor_.get(); } 57 ui::Compositor* compositor() { return compositor_.get(); }
57 58
58 private: 59 private:
60 std::unique_ptr<ui::Compositor> compositor_;
61
62 DISALLOW_COPY_AND_ASSIGN(CompositorTest);
63 };
64
65 // For tests that control time.
66 class CompositorTestWithMockedTime : public CompositorTest {
67 protected:
68 scoped_refptr<base::SingleThreadTaskRunner> CreateTaskRunner() override {
69 task_runner_ = new base::TestMockTimeTaskRunner;
70 return task_runner_;
71 }
72
73 base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
74
75 protected:
76 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
77 };
78
79 // For tests that run on a real MessageLoop with real time.
80 class CompositorTestWithMessageLoop : public CompositorTest {
81 protected:
82 scoped_refptr<base::SingleThreadTaskRunner> CreateTaskRunner() override {
83 task_runner_ = base::ThreadTaskRunnerHandle::Get();
84 return task_runner_;
85 }
86
87 base::SequencedTaskRunner* task_runner() { return task_runner_.get(); }
88
89 private:
59 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 90 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
60 std::unique_ptr<ui::Compositor> compositor_; 91 };
61 92
62 DISALLOW_COPY_AND_ASSIGN(CompositorTest); 93 class MockCompositorLockClient
94 : NON_EXPORTED_BASE(public ui::CompositorLockClient) {
95 public:
96 MOCK_METHOD0(CompositorLockTimedOut, void());
63 }; 97 };
64 98
65 } // namespace 99 } // namespace
66 100
67 TEST_F(CompositorTest, LocksTimeOut) { 101 TEST_F(CompositorTestWithMockedTime, LocksTimeOut) {
68 scoped_refptr<ui::CompositorLock> lock; 102 std::unique_ptr<CompositorLock> lock;
69 { 103
70 base::RunLoop run_loop; 104 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(100);
71 // Ensure that the lock times out by default. 105
72 lock = compositor()->GetCompositorLock(); 106 {
107 testing::StrictMock<MockCompositorLockClient> lock_client;
108 // This lock has a timeout.
109 lock = compositor()->GetCompositorLock(&lock_client, timeout);
73 EXPECT_TRUE(compositor()->IsLocked()); 110 EXPECT_TRUE(compositor()->IsLocked());
74 task_runner()->PostDelayedTask( 111 EXPECT_CALL(lock_client, CompositorLockTimedOut()).Times(1);
75 FROM_HERE, run_loop.QuitClosure(), 112 task_runner()->FastForwardBy(timeout);
76 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); 113 task_runner()->RunUntilIdle();
77 run_loop.Run();
78 EXPECT_FALSE(compositor()->IsLocked()); 114 EXPECT_FALSE(compositor()->IsLocked());
79 } 115 }
80 116
81 { 117 {
82 base::RunLoop run_loop; 118 testing::StrictMock<MockCompositorLockClient> lock_client;
83 // Ensure that the lock does not time out when set. 119 // This lock has no timeout.
84 compositor()->SetLocksWillTimeOut(false); 120 lock = compositor()->GetCompositorLock(&lock_client, base::TimeDelta());
85 lock = compositor()->GetCompositorLock();
86 EXPECT_TRUE(compositor()->IsLocked()); 121 EXPECT_TRUE(compositor()->IsLocked());
87 task_runner()->PostDelayedTask( 122 EXPECT_CALL(lock_client, CompositorLockTimedOut()).Times(0);
88 FROM_HERE, run_loop.QuitClosure(), 123 task_runner()->FastForwardBy(timeout);
89 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); 124 task_runner()->RunUntilIdle();
90 run_loop.Run();
91 EXPECT_TRUE(compositor()->IsLocked()); 125 EXPECT_TRUE(compositor()->IsLocked());
92 } 126 }
93 } 127 }
94 128
95 TEST_F(CompositorTest, ReleaseWidgetWithOutputSurfaceNeverCreated) { 129 TEST_F(CompositorTestWithMockedTime, MultipleLockClients) {
130 testing::StrictMock<MockCompositorLockClient> lock_client1;
131 std::unique_ptr<CompositorLock> lock1;
132 testing::StrictMock<MockCompositorLockClient> lock_client2;
133 std::unique_ptr<CompositorLock> lock2;
134
135 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1);
136 // Both locks are grabbed from the Compositor with a separate client.
137 lock1 = compositor()->GetCompositorLock(&lock_client1, timeout);
138 lock2 = compositor()->GetCompositorLock(&lock_client2, timeout);
139 EXPECT_TRUE(compositor()->IsLocked());
140 // Both clients get notified of timeout.
141 EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(1);
142 EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(1);
143 task_runner()->FastForwardBy(timeout);
144 task_runner()->RunUntilIdle();
145 EXPECT_FALSE(compositor()->IsLocked());
146 }
147
148 TEST_F(CompositorTestWithMockedTime, ExtendingLifeOfLockDoesntUseDeadClient) {
149 testing::StrictMock<MockCompositorLockClient> lock_client1;
150 std::unique_ptr<CompositorLock> lock1;
151 testing::StrictMock<MockCompositorLockClient> lock_client2;
152 std::unique_ptr<CompositorLock> lock2;
153
154 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1);
155
156 // One lock is grabbed from the compositor with a client. The other
157 // extends its lifetime past that of the first.
158 lock1 = compositor()->GetCompositorLock(&lock_client1, timeout);
159 EXPECT_TRUE(compositor()->IsLocked());
160
161 // This also locks the compositor and will do so past |lock1| ending.
162 lock2 = compositor()->GetCompositorLock(&lock_client2, timeout);
163 // |lock1| is destroyed, so it won't timeout but |lock2| will.
164 lock1 = nullptr;
165
166 EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(0);
167 EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(1);
168 task_runner()->FastForwardBy(timeout);
169 task_runner()->RunUntilIdle();
170
171 EXPECT_FALSE(compositor()->IsLocked());
172 }
173
174 TEST_F(CompositorTestWithMockedTime, AddingLocksDoesNotExtendTimeout) {
175 testing::StrictMock<MockCompositorLockClient> lock_client1;
176 std::unique_ptr<CompositorLock> lock1;
177 testing::StrictMock<MockCompositorLockClient> lock_client2;
178 std::unique_ptr<CompositorLock> lock2;
179
180 base::TimeDelta timeout1 = base::TimeDelta::FromMilliseconds(1);
181 base::TimeDelta timeout2 = base::TimeDelta::FromMilliseconds(10);
182
183 // The first lock has a short timeout.
184 lock1 = compositor()->GetCompositorLock(&lock_client1, timeout1);
185 EXPECT_TRUE(compositor()->IsLocked());
186
187 // The second lock has a longer timeout, but since a lock is active,
188 // the first one is used for both.
189 lock2 = compositor()->GetCompositorLock(&lock_client2, timeout2);
190
191 EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(1);
192 EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(1);
193 task_runner()->FastForwardBy(timeout1);
194 task_runner()->RunUntilIdle();
195 EXPECT_FALSE(compositor()->IsLocked());
196 }
197
198 TEST_F(CompositorTestWithMockedTime, LockIsDestroyedDoesntTimeout) {
199 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1);
200
201 testing::StrictMock<MockCompositorLockClient> lock_client1;
202 std::unique_ptr<CompositorLock> lock1;
203 lock1 = compositor()->GetCompositorLock(&lock_client1, timeout);
204 EXPECT_TRUE(compositor()->IsLocked());
205 // The CompositorLockClient is destroyed when |lock1| is released.
206 lock1 = nullptr;
207 // The client isn't called as a result.
208 EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(0);
209 task_runner()->FastForwardBy(timeout);
210 task_runner()->RunUntilIdle();
211 EXPECT_FALSE(compositor()->IsLocked());
212 }
213
214 TEST_F(CompositorTestWithMockedTime, TimeoutEndsWhenLockEnds) {
215 testing::StrictMock<MockCompositorLockClient> lock_client1;
216 std::unique_ptr<CompositorLock> lock1;
217 testing::StrictMock<MockCompositorLockClient> lock_client2;
218 std::unique_ptr<CompositorLock> lock2;
219
220 base::TimeDelta timeout1 = base::TimeDelta::FromMilliseconds(1);
221 base::TimeDelta timeout2 = base::TimeDelta::FromMilliseconds(10);
222
223 // The first lock has a short timeout.
224 lock1 = compositor()->GetCompositorLock(&lock_client1, timeout1);
225 EXPECT_TRUE(compositor()->IsLocked());
226 // But the first lock is ended before timeout.
227 lock1 = nullptr;
228 EXPECT_FALSE(compositor()->IsLocked());
229
230 // The second lock has a longer timeout, and it should use that timeout,
231 // since the first lock is done.
232 lock2 = compositor()->GetCompositorLock(&lock_client2, timeout2);
233 EXPECT_TRUE(compositor()->IsLocked());
234
235 {
236 // The second lock doesn't timeout from the first lock which has ended.
237 EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(0);
238 task_runner()->FastForwardBy(timeout1);
239 task_runner()->RunUntilIdle();
240 }
241
242 {
243 // The second lock can still timeout on its own though.
244 EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(1);
245 task_runner()->FastForwardBy(timeout2 - timeout1);
246 task_runner()->RunUntilIdle();
247 }
248
249 EXPECT_FALSE(compositor()->IsLocked());
250 }
251
252 TEST_F(CompositorTestWithMockedTime, CompositorLockOutlivesCompositor) {
253 testing::StrictMock<MockCompositorLockClient> lock_client1;
254 std::unique_ptr<CompositorLock> lock1;
255
256 lock1 = compositor()->GetCompositorLock(&lock_client1, base::TimeDelta());
257 // The compositor is destroyed before the lock.
258 DestroyCompositor();
259 // This doesn't crash.
260 lock1 = nullptr;
261 }
262
263 TEST_F(CompositorTestWithMockedTime,
264 ReleaseWidgetWithOutputSurfaceNeverCreated) {
96 compositor()->SetVisible(false); 265 compositor()->SetVisible(false);
97 EXPECT_EQ(gfx::kNullAcceleratedWidget, 266 EXPECT_EQ(gfx::kNullAcceleratedWidget,
98 compositor()->ReleaseAcceleratedWidget()); 267 compositor()->ReleaseAcceleratedWidget());
99 compositor()->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); 268 compositor()->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
100 compositor()->SetVisible(true); 269 compositor()->SetVisible(true);
101 } 270 }
102 271
103 #if defined(OS_WIN) 272 #if defined(OS_WIN)
104 // TODO(crbug.com/608436): Flaky on windows trybots 273 // TODO(crbug.com/608436): Flaky on windows trybots
105 #define MAYBE_CreateAndReleaseOutputSurface \ 274 #define MAYBE_CreateAndReleaseOutputSurface \
106 DISABLED_CreateAndReleaseOutputSurface 275 DISABLED_CreateAndReleaseOutputSurface
107 #else 276 #else
108 #define MAYBE_CreateAndReleaseOutputSurface CreateAndReleaseOutputSurface 277 #define MAYBE_CreateAndReleaseOutputSurface CreateAndReleaseOutputSurface
109 #endif 278 #endif
110 TEST_F(CompositorTest, MAYBE_CreateAndReleaseOutputSurface) { 279 TEST_F(CompositorTestWithMessageLoop, MAYBE_CreateAndReleaseOutputSurface) {
111 std::unique_ptr<Layer> root_layer(new Layer(ui::LAYER_SOLID_COLOR)); 280 std::unique_ptr<Layer> root_layer(new Layer(ui::LAYER_SOLID_COLOR));
112 root_layer->SetBounds(gfx::Rect(10, 10)); 281 root_layer->SetBounds(gfx::Rect(10, 10));
113 compositor()->SetRootLayer(root_layer.get()); 282 compositor()->SetRootLayer(root_layer.get());
114 compositor()->SetScaleAndSize(1.0f, gfx::Size(10, 10)); 283 compositor()->SetScaleAndSize(1.0f, gfx::Size(10, 10));
115 DCHECK(compositor()->IsVisible()); 284 DCHECK(compositor()->IsVisible());
116 compositor()->ScheduleDraw(); 285 compositor()->ScheduleDraw();
117 DrawWaiterForTest::WaitForCompositingEnded(compositor()); 286 DrawWaiterForTest::WaitForCompositingEnded(compositor());
118 compositor()->SetVisible(false); 287 compositor()->SetVisible(false);
119 EXPECT_EQ(gfx::kNullAcceleratedWidget, 288 EXPECT_EQ(gfx::kNullAcceleratedWidget,
120 compositor()->ReleaseAcceleratedWidget()); 289 compositor()->ReleaseAcceleratedWidget());
121 compositor()->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); 290 compositor()->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
122 compositor()->SetVisible(true); 291 compositor()->SetVisible(true);
123 compositor()->ScheduleDraw(); 292 compositor()->ScheduleDraw();
124 DrawWaiterForTest::WaitForCompositingEnded(compositor()); 293 DrawWaiterForTest::WaitForCompositingEnded(compositor());
125 compositor()->SetRootLayer(nullptr); 294 compositor()->SetRootLayer(nullptr);
126 } 295 }
127 296
128 } // namespace ui 297 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698