OLD | NEW |
| (Empty) |
1 // Copyright 2011 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 "cc/test/layer_tree_test.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "cc/animation/animation.h" | |
9 #include "cc/animation/animation_registrar.h" | |
10 #include "cc/animation/layer_animation_controller.h" | |
11 #include "cc/animation/timing_function.h" | |
12 #include "cc/base/switches.h" | |
13 #include "cc/input/input_handler.h" | |
14 #include "cc/layers/content_layer.h" | |
15 #include "cc/layers/layer.h" | |
16 #include "cc/layers/layer_impl.h" | |
17 #include "cc/test/animation_test_common.h" | |
18 #include "cc/test/begin_frame_args_test.h" | |
19 #include "cc/test/fake_external_begin_frame_source.h" | |
20 #include "cc/test/fake_layer_tree_host_client.h" | |
21 #include "cc/test/fake_output_surface.h" | |
22 #include "cc/test/test_context_provider.h" | |
23 #include "cc/test/test_gpu_memory_buffer_manager.h" | |
24 #include "cc/test/test_shared_bitmap_manager.h" | |
25 #include "cc/test/test_task_graph_runner.h" | |
26 #include "cc/test/tiled_layer_test_common.h" | |
27 #include "cc/trees/layer_tree_host_client.h" | |
28 #include "cc/trees/layer_tree_host_impl.h" | |
29 #include "cc/trees/layer_tree_host_single_thread_client.h" | |
30 #include "cc/trees/layer_tree_impl.h" | |
31 #include "cc/trees/single_thread_proxy.h" | |
32 #include "cc/trees/thread_proxy.h" | |
33 #include "testing/gmock/include/gmock/gmock.h" | |
34 #include "ui/gfx/frame_time.h" | |
35 #include "ui/gfx/geometry/size_conversions.h" | |
36 | |
37 namespace cc { | |
38 | |
39 TestHooks::TestHooks() {} | |
40 | |
41 TestHooks::~TestHooks() {} | |
42 | |
43 DrawResult TestHooks::PrepareToDrawOnThread( | |
44 LayerTreeHostImpl* host_impl, | |
45 LayerTreeHostImpl::FrameData* frame_data, | |
46 DrawResult draw_result) { | |
47 return draw_result; | |
48 } | |
49 | |
50 scoped_ptr<Rasterizer> TestHooks::CreateRasterizer( | |
51 LayerTreeHostImpl* host_impl) { | |
52 return host_impl->LayerTreeHostImpl::CreateRasterizer(); | |
53 } | |
54 | |
55 void TestHooks::CreateResourceAndTileTaskWorkerPool( | |
56 LayerTreeHostImpl* host_impl, | |
57 scoped_ptr<TileTaskWorkerPool>* tile_task_worker_pool, | |
58 scoped_ptr<ResourcePool>* resource_pool, | |
59 scoped_ptr<ResourcePool>* staging_resource_pool) { | |
60 host_impl->LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( | |
61 tile_task_worker_pool, resource_pool, staging_resource_pool); | |
62 } | |
63 | |
64 // Adapts ThreadProxy for test. Injects test hooks for testing. | |
65 class ThreadProxyForTest : public ThreadProxy { | |
66 public: | |
67 static scoped_ptr<Proxy> Create( | |
68 TestHooks* test_hooks, | |
69 LayerTreeHost* host, | |
70 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
71 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, | |
72 scoped_ptr<BeginFrameSource> external_begin_frame_source) { | |
73 return make_scoped_ptr(new ThreadProxyForTest( | |
74 test_hooks, | |
75 host, | |
76 main_task_runner, | |
77 impl_task_runner, | |
78 external_begin_frame_source.Pass())); | |
79 } | |
80 | |
81 ~ThreadProxyForTest() override {} | |
82 | |
83 private: | |
84 TestHooks* test_hooks_; | |
85 | |
86 void WillBeginImplFrame(const BeginFrameArgs& args) override { | |
87 ThreadProxy::WillBeginImplFrame(args); | |
88 test_hooks_->WillBeginImplFrame(args); | |
89 } | |
90 | |
91 void ScheduledActionSendBeginMainFrame() override { | |
92 test_hooks_->ScheduledActionWillSendBeginMainFrame(); | |
93 ThreadProxy::ScheduledActionSendBeginMainFrame(); | |
94 test_hooks_->ScheduledActionSendBeginMainFrame(); | |
95 } | |
96 | |
97 DrawResult ScheduledActionDrawAndSwapIfPossible() override { | |
98 DrawResult result = ThreadProxy::ScheduledActionDrawAndSwapIfPossible(); | |
99 test_hooks_->ScheduledActionDrawAndSwapIfPossible(); | |
100 return result; | |
101 } | |
102 | |
103 void ScheduledActionAnimate() override { | |
104 ThreadProxy::ScheduledActionAnimate(); | |
105 test_hooks_->ScheduledActionAnimate(); | |
106 } | |
107 | |
108 void ScheduledActionCommit() override { | |
109 ThreadProxy::ScheduledActionCommit(); | |
110 test_hooks_->ScheduledActionCommit(); | |
111 } | |
112 | |
113 void ScheduledActionBeginOutputSurfaceCreation() override { | |
114 ThreadProxy::ScheduledActionBeginOutputSurfaceCreation(); | |
115 test_hooks_->ScheduledActionBeginOutputSurfaceCreation(); | |
116 } | |
117 | |
118 void ScheduledActionPrepareTiles() override { | |
119 ThreadProxy::ScheduledActionPrepareTiles(); | |
120 test_hooks_->ScheduledActionPrepareTiles(); | |
121 } | |
122 | |
123 ThreadProxyForTest( | |
124 TestHooks* test_hooks, | |
125 LayerTreeHost* host, | |
126 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
127 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, | |
128 scoped_ptr<BeginFrameSource> external_begin_frame_source) | |
129 : ThreadProxy(host, main_task_runner, | |
130 impl_task_runner, | |
131 external_begin_frame_source.Pass()), | |
132 test_hooks_(test_hooks) {} | |
133 }; | |
134 | |
135 // Adapts ThreadProxy for test. Injects test hooks for testing. | |
136 class SingleThreadProxyForTest : public SingleThreadProxy { | |
137 public: | |
138 static scoped_ptr<Proxy> Create( | |
139 TestHooks* test_hooks, | |
140 LayerTreeHost* host, | |
141 LayerTreeHostSingleThreadClient* client, | |
142 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
143 scoped_ptr<BeginFrameSource> external_begin_frame_source) { | |
144 return make_scoped_ptr(new SingleThreadProxyForTest( | |
145 test_hooks, host, client, main_task_runner, | |
146 external_begin_frame_source.Pass())); | |
147 } | |
148 | |
149 ~SingleThreadProxyForTest() override {} | |
150 | |
151 private: | |
152 TestHooks* test_hooks_; | |
153 | |
154 void WillBeginImplFrame(const BeginFrameArgs& args) override { | |
155 SingleThreadProxy::WillBeginImplFrame(args); | |
156 test_hooks_->WillBeginImplFrame(args); | |
157 } | |
158 | |
159 void ScheduledActionSendBeginMainFrame() override { | |
160 test_hooks_->ScheduledActionWillSendBeginMainFrame(); | |
161 SingleThreadProxy::ScheduledActionSendBeginMainFrame(); | |
162 test_hooks_->ScheduledActionSendBeginMainFrame(); | |
163 } | |
164 | |
165 DrawResult ScheduledActionDrawAndSwapIfPossible() override { | |
166 DrawResult result = | |
167 SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible(); | |
168 test_hooks_->ScheduledActionDrawAndSwapIfPossible(); | |
169 return result; | |
170 } | |
171 | |
172 void ScheduledActionAnimate() override { | |
173 SingleThreadProxy::ScheduledActionAnimate(); | |
174 test_hooks_->ScheduledActionAnimate(); | |
175 } | |
176 | |
177 void ScheduledActionCommit() override { | |
178 SingleThreadProxy::ScheduledActionCommit(); | |
179 test_hooks_->ScheduledActionCommit(); | |
180 } | |
181 | |
182 void ScheduledActionBeginOutputSurfaceCreation() override { | |
183 SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation(); | |
184 test_hooks_->ScheduledActionBeginOutputSurfaceCreation(); | |
185 } | |
186 | |
187 void ScheduledActionPrepareTiles() override { | |
188 SingleThreadProxy::ScheduledActionPrepareTiles(); | |
189 test_hooks_->ScheduledActionPrepareTiles(); | |
190 } | |
191 | |
192 SingleThreadProxyForTest( | |
193 TestHooks* test_hooks, | |
194 LayerTreeHost* host, | |
195 LayerTreeHostSingleThreadClient* client, | |
196 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
197 scoped_ptr<BeginFrameSource> external_begin_frame_source) | |
198 : SingleThreadProxy(host, client, main_task_runner, | |
199 external_begin_frame_source.Pass()), | |
200 test_hooks_(test_hooks) {} | |
201 }; | |
202 | |
203 // Adapts LayerTreeHostImpl for test. Runs real code, then invokes test hooks. | |
204 class LayerTreeHostImplForTesting : public LayerTreeHostImpl { | |
205 public: | |
206 static scoped_ptr<LayerTreeHostImplForTesting> Create( | |
207 TestHooks* test_hooks, | |
208 const LayerTreeSettings& settings, | |
209 LayerTreeHostImplClient* host_impl_client, | |
210 Proxy* proxy, | |
211 SharedBitmapManager* shared_bitmap_manager, | |
212 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | |
213 TaskGraphRunner* task_graph_runner, | |
214 RenderingStatsInstrumentation* stats_instrumentation) { | |
215 return make_scoped_ptr(new LayerTreeHostImplForTesting( | |
216 test_hooks, settings, host_impl_client, proxy, shared_bitmap_manager, | |
217 gpu_memory_buffer_manager, task_graph_runner, stats_instrumentation)); | |
218 } | |
219 | |
220 protected: | |
221 LayerTreeHostImplForTesting( | |
222 TestHooks* test_hooks, | |
223 const LayerTreeSettings& settings, | |
224 LayerTreeHostImplClient* host_impl_client, | |
225 Proxy* proxy, | |
226 SharedBitmapManager* shared_bitmap_manager, | |
227 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | |
228 TaskGraphRunner* task_graph_runner, | |
229 RenderingStatsInstrumentation* stats_instrumentation) | |
230 : LayerTreeHostImpl(settings, | |
231 host_impl_client, | |
232 proxy, | |
233 stats_instrumentation, | |
234 shared_bitmap_manager, | |
235 gpu_memory_buffer_manager, | |
236 task_graph_runner, | |
237 0), | |
238 test_hooks_(test_hooks), | |
239 block_notify_ready_to_activate_for_testing_(false), | |
240 notify_ready_to_activate_was_blocked_(false) {} | |
241 | |
242 scoped_ptr<Rasterizer> CreateRasterizer() override { | |
243 return test_hooks_->CreateRasterizer(this); | |
244 } | |
245 | |
246 void CreateResourceAndTileTaskWorkerPool( | |
247 scoped_ptr<TileTaskWorkerPool>* tile_task_worker_pool, | |
248 scoped_ptr<ResourcePool>* resource_pool, | |
249 scoped_ptr<ResourcePool>* staging_resource_pool) override { | |
250 test_hooks_->CreateResourceAndTileTaskWorkerPool( | |
251 this, tile_task_worker_pool, resource_pool, staging_resource_pool); | |
252 } | |
253 | |
254 void WillBeginImplFrame(const BeginFrameArgs& args) override { | |
255 LayerTreeHostImpl::WillBeginImplFrame(args); | |
256 test_hooks_->WillBeginImplFrameOnThread(this, args); | |
257 } | |
258 | |
259 void BeginMainFrameAborted(CommitEarlyOutReason reason) override { | |
260 LayerTreeHostImpl::BeginMainFrameAborted(reason); | |
261 test_hooks_->BeginMainFrameAbortedOnThread(this, reason); | |
262 } | |
263 | |
264 void BeginCommit() override { | |
265 LayerTreeHostImpl::BeginCommit(); | |
266 test_hooks_->BeginCommitOnThread(this); | |
267 } | |
268 | |
269 void CommitComplete() override { | |
270 LayerTreeHostImpl::CommitComplete(); | |
271 test_hooks_->CommitCompleteOnThread(this); | |
272 } | |
273 | |
274 DrawResult PrepareToDraw(FrameData* frame) override { | |
275 DrawResult draw_result = LayerTreeHostImpl::PrepareToDraw(frame); | |
276 return test_hooks_->PrepareToDrawOnThread(this, frame, draw_result); | |
277 } | |
278 | |
279 void DrawLayers(FrameData* frame, base::TimeTicks frame_begin_time) override { | |
280 LayerTreeHostImpl::DrawLayers(frame, frame_begin_time); | |
281 test_hooks_->DrawLayersOnThread(this); | |
282 } | |
283 | |
284 bool SwapBuffers(const LayerTreeHostImpl::FrameData& frame) override { | |
285 bool result = LayerTreeHostImpl::SwapBuffers(frame); | |
286 test_hooks_->SwapBuffersOnThread(this, result); | |
287 return result; | |
288 } | |
289 | |
290 void DidSwapBuffersComplete() override { | |
291 LayerTreeHostImpl::DidSwapBuffersComplete(); | |
292 test_hooks_->SwapBuffersCompleteOnThread(this); | |
293 } | |
294 | |
295 void ReclaimResources(const CompositorFrameAck* ack) override { | |
296 LayerTreeHostImpl::ReclaimResources(ack); | |
297 } | |
298 | |
299 void NotifyReadyToActivate() override { | |
300 if (block_notify_ready_to_activate_for_testing_) { | |
301 notify_ready_to_activate_was_blocked_ = true; | |
302 } else { | |
303 LayerTreeHostImpl::NotifyReadyToActivate(); | |
304 test_hooks_->NotifyReadyToActivateOnThread(this); | |
305 } | |
306 } | |
307 | |
308 void NotifyReadyToDraw() override { | |
309 LayerTreeHostImpl::NotifyReadyToDraw(); | |
310 test_hooks_->NotifyReadyToDrawOnThread(this); | |
311 } | |
312 | |
313 void BlockNotifyReadyToActivateForTesting(bool block) override { | |
314 CHECK(settings().impl_side_painting); | |
315 CHECK(proxy()->ImplThreadTaskRunner()) | |
316 << "Not supported for single-threaded mode."; | |
317 block_notify_ready_to_activate_for_testing_ = block; | |
318 if (!block && notify_ready_to_activate_was_blocked_) { | |
319 NotifyReadyToActivate(); | |
320 notify_ready_to_activate_was_blocked_ = false; | |
321 } | |
322 } | |
323 | |
324 void ActivateSyncTree() override { | |
325 test_hooks_->WillActivateTreeOnThread(this); | |
326 LayerTreeHostImpl::ActivateSyncTree(); | |
327 DCHECK(!pending_tree()); | |
328 test_hooks_->DidActivateTreeOnThread(this); | |
329 } | |
330 | |
331 bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface) override { | |
332 bool success = LayerTreeHostImpl::InitializeRenderer(output_surface.Pass()); | |
333 test_hooks_->InitializedRendererOnThread(this, success); | |
334 return success; | |
335 } | |
336 | |
337 void SetVisible(bool visible) override { | |
338 LayerTreeHostImpl::SetVisible(visible); | |
339 test_hooks_->DidSetVisibleOnImplTree(this, visible); | |
340 } | |
341 | |
342 void AnimateLayers(base::TimeTicks monotonic_time) override { | |
343 test_hooks_->WillAnimateLayers(this, monotonic_time); | |
344 LayerTreeHostImpl::AnimateLayers(monotonic_time); | |
345 test_hooks_->AnimateLayers(this, monotonic_time); | |
346 } | |
347 | |
348 void UpdateAnimationState(bool start_ready_animations) override { | |
349 LayerTreeHostImpl::UpdateAnimationState(start_ready_animations); | |
350 bool has_unfinished_animation = false; | |
351 for (const auto& it : | |
352 animation_registrar()->active_animation_controllers_for_testing()) { | |
353 if (it.second->HasActiveAnimation()) { | |
354 has_unfinished_animation = true; | |
355 break; | |
356 } | |
357 } | |
358 test_hooks_->UpdateAnimationState(this, has_unfinished_animation); | |
359 } | |
360 | |
361 void NotifyTileStateChanged(const Tile* tile) override { | |
362 LayerTreeHostImpl::NotifyTileStateChanged(tile); | |
363 test_hooks_->NotifyTileStateChangedOnThread(this, tile); | |
364 } | |
365 | |
366 private: | |
367 TestHooks* test_hooks_; | |
368 bool block_notify_ready_to_activate_for_testing_; | |
369 bool notify_ready_to_activate_was_blocked_; | |
370 }; | |
371 | |
372 // Implementation of LayerTreeHost callback interface. | |
373 class LayerTreeHostClientForTesting : public LayerTreeHostClient, | |
374 public LayerTreeHostSingleThreadClient { | |
375 public: | |
376 static scoped_ptr<LayerTreeHostClientForTesting> Create( | |
377 TestHooks* test_hooks) { | |
378 return make_scoped_ptr(new LayerTreeHostClientForTesting(test_hooks)); | |
379 } | |
380 ~LayerTreeHostClientForTesting() override {} | |
381 | |
382 void WillBeginMainFrame() override { test_hooks_->WillBeginMainFrame(); } | |
383 | |
384 void DidBeginMainFrame() override { test_hooks_->DidBeginMainFrame(); } | |
385 | |
386 void BeginMainFrame(const BeginFrameArgs& args) override { | |
387 test_hooks_->BeginMainFrame(args); | |
388 } | |
389 | |
390 void Layout() override { test_hooks_->Layout(); } | |
391 | |
392 void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, | |
393 const gfx::Vector2dF& outer_delta, | |
394 const gfx::Vector2dF& elastic_overscroll_delta, | |
395 float page_scale, | |
396 float top_controls_delta) override { | |
397 test_hooks_->ApplyViewportDeltas(inner_delta, outer_delta, | |
398 elastic_overscroll_delta, page_scale, | |
399 top_controls_delta); | |
400 } | |
401 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
402 float scale, | |
403 float top_controls_delta) override { | |
404 test_hooks_->ApplyViewportDeltas(scroll_delta, | |
405 scale, | |
406 top_controls_delta); | |
407 } | |
408 | |
409 void RequestNewOutputSurface() override { | |
410 test_hooks_->RequestNewOutputSurface(); | |
411 } | |
412 | |
413 void DidInitializeOutputSurface() override { | |
414 test_hooks_->DidInitializeOutputSurface(); | |
415 } | |
416 | |
417 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | |
418 test_hooks_->SendBeginFramesToChildren(args); | |
419 } | |
420 | |
421 void DidFailToInitializeOutputSurface() override { | |
422 test_hooks_->DidFailToInitializeOutputSurface(); | |
423 RequestNewOutputSurface(); | |
424 } | |
425 | |
426 void WillCommit() override { test_hooks_->WillCommit(); } | |
427 | |
428 void DidCommit() override { test_hooks_->DidCommit(); } | |
429 | |
430 void DidCommitAndDrawFrame() override { | |
431 test_hooks_->DidCommitAndDrawFrame(); | |
432 } | |
433 | |
434 void DidCompleteSwapBuffers() override { | |
435 test_hooks_->DidCompleteSwapBuffers(); | |
436 } | |
437 | |
438 void DidPostSwapBuffers() override {} | |
439 void DidAbortSwapBuffers() override {} | |
440 void ScheduleComposite() override { test_hooks_->ScheduleComposite(); } | |
441 void DidCompletePageScaleAnimation() override {} | |
442 void BeginMainFrameNotExpectedSoon() override {} | |
443 | |
444 private: | |
445 explicit LayerTreeHostClientForTesting(TestHooks* test_hooks) | |
446 : test_hooks_(test_hooks) {} | |
447 | |
448 TestHooks* test_hooks_; | |
449 }; | |
450 | |
451 // Adapts LayerTreeHost for test. Injects LayerTreeHostImplForTesting. | |
452 class LayerTreeHostForTesting : public LayerTreeHost { | |
453 public: | |
454 static scoped_ptr<LayerTreeHostForTesting> Create( | |
455 TestHooks* test_hooks, | |
456 LayerTreeHostClientForTesting* client, | |
457 SharedBitmapManager* shared_bitmap_manager, | |
458 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | |
459 TaskGraphRunner* task_graph_runner, | |
460 const LayerTreeSettings& settings, | |
461 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
462 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, | |
463 scoped_ptr<BeginFrameSource> external_begin_frame_source) { | |
464 scoped_ptr<LayerTreeHostForTesting> layer_tree_host( | |
465 new LayerTreeHostForTesting(test_hooks, client, shared_bitmap_manager, | |
466 gpu_memory_buffer_manager, | |
467 task_graph_runner, settings)); | |
468 if (impl_task_runner.get()) { | |
469 layer_tree_host->InitializeForTesting( | |
470 ThreadProxyForTest::Create(test_hooks, | |
471 layer_tree_host.get(), | |
472 main_task_runner, | |
473 impl_task_runner, | |
474 external_begin_frame_source.Pass())); | |
475 } else { | |
476 layer_tree_host->InitializeForTesting( | |
477 SingleThreadProxyForTest::Create( | |
478 test_hooks, | |
479 layer_tree_host.get(), | |
480 client, | |
481 main_task_runner, | |
482 external_begin_frame_source.Pass())); | |
483 } | |
484 return layer_tree_host.Pass(); | |
485 } | |
486 | |
487 scoped_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( | |
488 LayerTreeHostImplClient* host_impl_client) override { | |
489 return LayerTreeHostImplForTesting::Create( | |
490 test_hooks_, settings(), host_impl_client, proxy(), | |
491 shared_bitmap_manager_, gpu_memory_buffer_manager_, task_graph_runner_, | |
492 rendering_stats_instrumentation()); | |
493 } | |
494 | |
495 void SetNeedsCommit() override { | |
496 if (!test_started_) | |
497 return; | |
498 LayerTreeHost::SetNeedsCommit(); | |
499 } | |
500 | |
501 void set_test_started(bool started) { test_started_ = started; } | |
502 | |
503 private: | |
504 LayerTreeHostForTesting( | |
505 TestHooks* test_hooks, | |
506 LayerTreeHostClient* client, | |
507 SharedBitmapManager* shared_bitmap_manager, | |
508 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | |
509 TaskGraphRunner* task_graph_runner, | |
510 const LayerTreeSettings& settings) | |
511 : LayerTreeHost(client, NULL, NULL, NULL, settings), | |
512 shared_bitmap_manager_(shared_bitmap_manager), | |
513 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), | |
514 task_graph_runner_(task_graph_runner), | |
515 test_hooks_(test_hooks), | |
516 test_started_(false) {} | |
517 | |
518 SharedBitmapManager* shared_bitmap_manager_; | |
519 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; | |
520 TaskGraphRunner* task_graph_runner_; | |
521 TestHooks* test_hooks_; | |
522 bool test_started_; | |
523 }; | |
524 | |
525 LayerTreeTest::LayerTreeTest() | |
526 : output_surface_(nullptr), | |
527 external_begin_frame_source_(nullptr), | |
528 beginning_(false), | |
529 end_when_begin_returns_(false), | |
530 timed_out_(false), | |
531 scheduled_(false), | |
532 started_(false), | |
533 ended_(false), | |
534 delegating_renderer_(false), | |
535 verify_property_trees_(true), | |
536 timeout_seconds_(0), | |
537 weak_factory_(this) { | |
538 main_thread_weak_ptr_ = weak_factory_.GetWeakPtr(); | |
539 | |
540 // Tests should timeout quickly unless --cc-layer-tree-test-no-timeout was | |
541 // specified (for running in a debugger). | |
542 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
543 if (!command_line->HasSwitch(switches::kCCLayerTreeTestNoTimeout)) | |
544 timeout_seconds_ = 5; | |
545 } | |
546 | |
547 LayerTreeTest::~LayerTreeTest() {} | |
548 | |
549 void LayerTreeTest::EndTest() { | |
550 if (ended_) | |
551 return; | |
552 ended_ = true; | |
553 | |
554 // For the case where we EndTest during BeginTest(), set a flag to indicate | |
555 // that the test should end the second BeginTest regains control. | |
556 if (beginning_) { | |
557 end_when_begin_returns_ = true; | |
558 } else { | |
559 main_task_runner_->PostTask( | |
560 FROM_HERE, | |
561 base::Bind(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_)); | |
562 } | |
563 } | |
564 | |
565 void LayerTreeTest::EndTestAfterDelayMs(int delay_milliseconds) { | |
566 main_task_runner_->PostDelayedTask( | |
567 FROM_HERE, | |
568 base::Bind(&LayerTreeTest::EndTest, main_thread_weak_ptr_), | |
569 base::TimeDelta::FromMilliseconds(delay_milliseconds)); | |
570 } | |
571 | |
572 void LayerTreeTest::PostAddAnimationToMainThread( | |
573 Layer* layer_to_receive_animation) { | |
574 main_task_runner_->PostTask( | |
575 FROM_HERE, | |
576 base::Bind(&LayerTreeTest::DispatchAddAnimation, main_thread_weak_ptr_, | |
577 base::Unretained(layer_to_receive_animation), 0.000004)); | |
578 } | |
579 | |
580 void LayerTreeTest::PostAddInstantAnimationToMainThread( | |
581 Layer* layer_to_receive_animation) { | |
582 main_task_runner_->PostTask( | |
583 FROM_HERE, | |
584 base::Bind(&LayerTreeTest::DispatchAddAnimation, | |
585 main_thread_weak_ptr_, | |
586 base::Unretained(layer_to_receive_animation), | |
587 0.0)); | |
588 } | |
589 | |
590 void LayerTreeTest::PostAddLongAnimationToMainThread( | |
591 Layer* layer_to_receive_animation) { | |
592 main_task_runner_->PostTask( | |
593 FROM_HERE, | |
594 base::Bind(&LayerTreeTest::DispatchAddAnimation, | |
595 main_thread_weak_ptr_, | |
596 base::Unretained(layer_to_receive_animation), | |
597 1.0)); | |
598 } | |
599 | |
600 void LayerTreeTest::PostSetDeferCommitsToMainThread(bool defer_commits) { | |
601 main_task_runner_->PostTask( | |
602 FROM_HERE, | |
603 base::Bind(&LayerTreeTest::DispatchSetDeferCommits, | |
604 main_thread_weak_ptr_, defer_commits)); | |
605 } | |
606 | |
607 void LayerTreeTest::PostSetNeedsCommitToMainThread() { | |
608 main_task_runner_->PostTask(FROM_HERE, | |
609 base::Bind(&LayerTreeTest::DispatchSetNeedsCommit, | |
610 main_thread_weak_ptr_)); | |
611 } | |
612 | |
613 void LayerTreeTest::PostSetNeedsUpdateLayersToMainThread() { | |
614 main_task_runner_->PostTask( | |
615 FROM_HERE, | |
616 base::Bind(&LayerTreeTest::DispatchSetNeedsUpdateLayers, | |
617 main_thread_weak_ptr_)); | |
618 } | |
619 | |
620 void LayerTreeTest::PostSetNeedsRedrawToMainThread() { | |
621 main_task_runner_->PostTask(FROM_HERE, | |
622 base::Bind(&LayerTreeTest::DispatchSetNeedsRedraw, | |
623 main_thread_weak_ptr_)); | |
624 } | |
625 | |
626 void LayerTreeTest::PostSetNeedsRedrawRectToMainThread( | |
627 const gfx::Rect& damage_rect) { | |
628 main_task_runner_->PostTask( | |
629 FROM_HERE, | |
630 base::Bind(&LayerTreeTest::DispatchSetNeedsRedrawRect, | |
631 main_thread_weak_ptr_, | |
632 damage_rect)); | |
633 } | |
634 | |
635 void LayerTreeTest::PostSetVisibleToMainThread(bool visible) { | |
636 main_task_runner_->PostTask( | |
637 FROM_HERE, | |
638 base::Bind( | |
639 &LayerTreeTest::DispatchSetVisible, main_thread_weak_ptr_, visible)); | |
640 } | |
641 | |
642 void LayerTreeTest::PostSetNextCommitForcesRedrawToMainThread() { | |
643 main_task_runner_->PostTask( | |
644 FROM_HERE, | |
645 base::Bind(&LayerTreeTest::DispatchSetNextCommitForcesRedraw, | |
646 main_thread_weak_ptr_)); | |
647 } | |
648 | |
649 void LayerTreeTest::PostCompositeImmediatelyToMainThread() { | |
650 main_task_runner_->PostTask( | |
651 FROM_HERE, | |
652 base::Bind(&LayerTreeTest::DispatchCompositeImmediately, | |
653 main_thread_weak_ptr_)); | |
654 } | |
655 | |
656 void LayerTreeTest::WillBeginTest() { | |
657 layer_tree_host_->SetLayerTreeHostClientReady(); | |
658 } | |
659 | |
660 void LayerTreeTest::DoBeginTest() { | |
661 client_ = LayerTreeHostClientForTesting::Create(this); | |
662 | |
663 scoped_ptr<FakeExternalBeginFrameSource> external_begin_frame_source; | |
664 if (settings_.use_external_begin_frame_source) { | |
665 external_begin_frame_source.reset(new FakeExternalBeginFrameSource( | |
666 settings_.renderer_settings.refresh_rate)); | |
667 external_begin_frame_source_ = external_begin_frame_source.get(); | |
668 } | |
669 | |
670 DCHECK(!impl_thread_ || impl_thread_->message_loop_proxy().get()); | |
671 layer_tree_host_ = LayerTreeHostForTesting::Create( | |
672 this, client_.get(), shared_bitmap_manager_.get(), | |
673 gpu_memory_buffer_manager_.get(), task_graph_runner_.get(), settings_, | |
674 base::MessageLoopProxy::current(), | |
675 impl_thread_ ? impl_thread_->message_loop_proxy() : NULL, | |
676 external_begin_frame_source.Pass()); | |
677 ASSERT_TRUE(layer_tree_host_); | |
678 | |
679 started_ = true; | |
680 beginning_ = true; | |
681 SetupTree(); | |
682 WillBeginTest(); | |
683 BeginTest(); | |
684 beginning_ = false; | |
685 if (end_when_begin_returns_) | |
686 RealEndTest(); | |
687 | |
688 // Allow commits to happen once BeginTest() has had a chance to post tasks | |
689 // so that those tasks will happen before the first commit. | |
690 if (layer_tree_host_) { | |
691 static_cast<LayerTreeHostForTesting*>(layer_tree_host_.get()) | |
692 ->set_test_started(true); | |
693 } | |
694 } | |
695 | |
696 void LayerTreeTest::SetupTree() { | |
697 if (!layer_tree_host_->root_layer()) { | |
698 scoped_refptr<Layer> root_layer = Layer::Create(); | |
699 root_layer->SetBounds(gfx::Size(1, 1)); | |
700 root_layer->SetIsDrawable(true); | |
701 layer_tree_host_->SetRootLayer(root_layer); | |
702 } | |
703 | |
704 gfx::Size root_bounds = layer_tree_host_->root_layer()->bounds(); | |
705 gfx::Size device_root_bounds = gfx::ToCeiledSize( | |
706 gfx::ScaleSize(root_bounds, layer_tree_host_->device_scale_factor())); | |
707 layer_tree_host_->SetViewportSize(device_root_bounds); | |
708 } | |
709 | |
710 void LayerTreeTest::Timeout() { | |
711 timed_out_ = true; | |
712 EndTest(); | |
713 } | |
714 | |
715 void LayerTreeTest::RealEndTest() { | |
716 if (layer_tree_host_ && !timed_out_ && | |
717 proxy()->MainFrameWillHappenForTesting()) { | |
718 main_task_runner_->PostTask( | |
719 FROM_HERE, | |
720 base::Bind(&LayerTreeTest::RealEndTest, main_thread_weak_ptr_)); | |
721 return; | |
722 } | |
723 | |
724 base::MessageLoop::current()->Quit(); | |
725 } | |
726 | |
727 void LayerTreeTest::DispatchAddAnimation(Layer* layer_to_receive_animation, | |
728 double animation_duration) { | |
729 DCHECK(!proxy() || proxy()->IsMainThread()); | |
730 | |
731 if (layer_to_receive_animation) { | |
732 AddOpacityTransitionToLayer( | |
733 layer_to_receive_animation, animation_duration, 0, 0.5, true); | |
734 } | |
735 } | |
736 | |
737 void LayerTreeTest::DispatchSetDeferCommits(bool defer_commits) { | |
738 DCHECK(!proxy() || proxy()->IsMainThread()); | |
739 | |
740 if (layer_tree_host_) | |
741 layer_tree_host_->SetDeferCommits(defer_commits); | |
742 } | |
743 | |
744 void LayerTreeTest::DispatchSetNeedsCommit() { | |
745 DCHECK(!proxy() || proxy()->IsMainThread()); | |
746 | |
747 if (layer_tree_host_) | |
748 layer_tree_host_->SetNeedsCommit(); | |
749 } | |
750 | |
751 void LayerTreeTest::DispatchSetNeedsUpdateLayers() { | |
752 DCHECK(!proxy() || proxy()->IsMainThread()); | |
753 | |
754 if (layer_tree_host_) | |
755 layer_tree_host_->SetNeedsUpdateLayers(); | |
756 } | |
757 | |
758 void LayerTreeTest::DispatchSetNeedsRedraw() { | |
759 DCHECK(!proxy() || proxy()->IsMainThread()); | |
760 | |
761 if (layer_tree_host_) | |
762 layer_tree_host_->SetNeedsRedraw(); | |
763 } | |
764 | |
765 void LayerTreeTest::DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect) { | |
766 DCHECK(!proxy() || proxy()->IsMainThread()); | |
767 | |
768 if (layer_tree_host_) | |
769 layer_tree_host_->SetNeedsRedrawRect(damage_rect); | |
770 } | |
771 | |
772 void LayerTreeTest::DispatchSetVisible(bool visible) { | |
773 DCHECK(!proxy() || proxy()->IsMainThread()); | |
774 if (layer_tree_host_) | |
775 layer_tree_host_->SetVisible(visible); | |
776 } | |
777 | |
778 void LayerTreeTest::DispatchSetNextCommitForcesRedraw() { | |
779 DCHECK(!proxy() || proxy()->IsMainThread()); | |
780 | |
781 if (layer_tree_host_) | |
782 layer_tree_host_->SetNextCommitForcesRedraw(); | |
783 } | |
784 | |
785 void LayerTreeTest::DispatchCompositeImmediately() { | |
786 DCHECK(!proxy() || proxy()->IsMainThread()); | |
787 if (layer_tree_host_) | |
788 layer_tree_host_->Composite(gfx::FrameTime::Now()); | |
789 } | |
790 | |
791 void LayerTreeTest::RunTest(bool threaded, | |
792 bool delegating_renderer, | |
793 bool impl_side_painting) { | |
794 if (threaded) { | |
795 impl_thread_.reset(new base::Thread("Compositor")); | |
796 ASSERT_TRUE(impl_thread_->Start()); | |
797 } | |
798 | |
799 main_task_runner_ = base::MessageLoopProxy::current(); | |
800 | |
801 shared_bitmap_manager_.reset(new TestSharedBitmapManager); | |
802 gpu_memory_buffer_manager_.reset(new TestGpuMemoryBufferManager); | |
803 task_graph_runner_.reset(new TestTaskGraphRunner); | |
804 | |
805 delegating_renderer_ = delegating_renderer; | |
806 | |
807 // Spend less time waiting for BeginFrame because the output is | |
808 // mocked out. | |
809 settings_.renderer_settings.refresh_rate = 200.0; | |
810 settings_.background_animation_rate = 200.0; | |
811 settings_.impl_side_painting = impl_side_painting; | |
812 settings_.verify_property_trees = verify_property_trees_; | |
813 InitializeSettings(&settings_); | |
814 | |
815 main_task_runner_->PostTask( | |
816 FROM_HERE, | |
817 base::Bind(&LayerTreeTest::DoBeginTest, base::Unretained(this))); | |
818 | |
819 if (timeout_seconds_) { | |
820 timeout_.Reset(base::Bind(&LayerTreeTest::Timeout, base::Unretained(this))); | |
821 main_task_runner_->PostDelayedTask( | |
822 FROM_HERE, | |
823 timeout_.callback(), | |
824 base::TimeDelta::FromSeconds(timeout_seconds_)); | |
825 } | |
826 | |
827 base::MessageLoop::current()->Run(); | |
828 DestroyLayerTreeHost(); | |
829 | |
830 timeout_.Cancel(); | |
831 | |
832 ASSERT_FALSE(layer_tree_host_.get()); | |
833 client_ = nullptr; | |
834 if (timed_out_) { | |
835 FAIL() << "Test timed out"; | |
836 return; | |
837 } | |
838 AfterTest(); | |
839 } | |
840 | |
841 void LayerTreeTest::RunTestWithImplSidePainting() { | |
842 RunTest(true, false, true); | |
843 } | |
844 | |
845 void LayerTreeTest::RequestNewOutputSurface() { | |
846 layer_tree_host_->SetOutputSurface(CreateOutputSurface()); | |
847 } | |
848 | |
849 scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface() { | |
850 scoped_ptr<FakeOutputSurface> output_surface = CreateFakeOutputSurface(); | |
851 DCHECK_EQ(delegating_renderer_, | |
852 output_surface->capabilities().delegated_rendering); | |
853 output_surface_ = output_surface.get(); | |
854 | |
855 if (settings_.use_external_begin_frame_source) { | |
856 DCHECK(external_begin_frame_source_); | |
857 DCHECK(external_begin_frame_source_->is_ready()); | |
858 } | |
859 return output_surface.Pass(); | |
860 } | |
861 | |
862 scoped_ptr<FakeOutputSurface> LayerTreeTest::CreateFakeOutputSurface() { | |
863 if (delegating_renderer_) | |
864 return FakeOutputSurface::CreateDelegating3d(); | |
865 else | |
866 return FakeOutputSurface::Create3d(); | |
867 } | |
868 | |
869 TestWebGraphicsContext3D* LayerTreeTest::TestContext() { | |
870 return static_cast<TestContextProvider*>(output_surface_->context_provider()) | |
871 ->TestContext3d(); | |
872 } | |
873 | |
874 int LayerTreeTest::LastCommittedSourceFrameNumber(LayerTreeHostImpl* impl) | |
875 const { | |
876 if (impl->pending_tree()) | |
877 return impl->pending_tree()->source_frame_number(); | |
878 if (impl->active_tree()) | |
879 return impl->active_tree()->source_frame_number(); | |
880 // Source frames start at 0, so this is invalid. | |
881 return -1; | |
882 } | |
883 | |
884 void LayerTreeTest::DestroyLayerTreeHost() { | |
885 if (layer_tree_host_ && layer_tree_host_->root_layer()) | |
886 layer_tree_host_->root_layer()->SetLayerTreeHost(NULL); | |
887 layer_tree_host_ = nullptr; | |
888 } | |
889 | |
890 LayerTreeHost* LayerTreeTest::layer_tree_host() { | |
891 // We check for a null proxy here as we sometimes ask for the layer tree host | |
892 // when the proxy does not exist, often for checking settings after a test has | |
893 // completed. For example, LTHPixelResourceTest::RunPixelResourceTest. See | |
894 // elsewhere in this file for other examples. | |
895 DCHECK(!proxy() || proxy()->IsMainThread() || proxy()->IsMainThreadBlocked()); | |
896 return layer_tree_host_.get(); | |
897 } | |
898 | |
899 } // namespace cc | |
OLD | NEW |