| 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 |