Index: cc/trees/layer_tree_host_unittest.cc |
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc |
deleted file mode 100644 |
index 201af9a45fc63cbabb5158445a7a1fbf564458f7..0000000000000000000000000000000000000000 |
--- a/cc/trees/layer_tree_host_unittest.cc |
+++ /dev/null |
@@ -1,6609 +0,0 @@ |
-// Copyright 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "cc/trees/layer_tree_host.h" |
- |
-#include <algorithm> |
- |
-#include "base/auto_reset.h" |
-#include "base/synchronization/lock.h" |
-#include "cc/animation/timing_function.h" |
-#include "cc/debug/frame_rate_counter.h" |
-#include "cc/layers/content_layer.h" |
-#include "cc/layers/content_layer_client.h" |
-#include "cc/layers/io_surface_layer.h" |
-#include "cc/layers/layer_impl.h" |
-#include "cc/layers/painted_scrollbar_layer.h" |
-#include "cc/layers/picture_layer.h" |
-#include "cc/layers/solid_color_layer.h" |
-#include "cc/output/begin_frame_args.h" |
-#include "cc/output/compositor_frame_ack.h" |
-#include "cc/output/copy_output_request.h" |
-#include "cc/output/copy_output_result.h" |
-#include "cc/output/output_surface.h" |
-#include "cc/output/swap_promise.h" |
-#include "cc/quads/draw_quad.h" |
-#include "cc/quads/io_surface_draw_quad.h" |
-#include "cc/quads/tile_draw_quad.h" |
-#include "cc/resources/prioritized_resource.h" |
-#include "cc/resources/prioritized_resource_manager.h" |
-#include "cc/resources/resource_update_queue.h" |
-#include "cc/test/fake_content_layer.h" |
-#include "cc/test/fake_content_layer_client.h" |
-#include "cc/test/fake_content_layer_impl.h" |
-#include "cc/test/fake_layer_tree_host_client.h" |
-#include "cc/test/fake_output_surface.h" |
-#include "cc/test/fake_painted_scrollbar_layer.h" |
-#include "cc/test/fake_picture_layer.h" |
-#include "cc/test/fake_picture_layer_impl.h" |
-#include "cc/test/fake_picture_pile.h" |
-#include "cc/test/fake_proxy.h" |
-#include "cc/test/fake_scoped_ui_resource.h" |
-#include "cc/test/geometry_test_utils.h" |
-#include "cc/test/impl_side_painting_settings.h" |
-#include "cc/test/layer_tree_test.h" |
-#include "cc/test/test_shared_bitmap_manager.h" |
-#include "cc/test/test_web_graphics_context_3d.h" |
-#include "cc/trees/layer_tree_host_impl.h" |
-#include "cc/trees/layer_tree_impl.h" |
-#include "cc/trees/single_thread_proxy.h" |
-#include "cc/trees/thread_proxy.h" |
-#include "gpu/GLES2/gl2extchromium.h" |
-#include "skia/ext/refptr.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "third_party/khronos/GLES2/gl2.h" |
-#include "third_party/khronos/GLES2/gl2ext.h" |
-#include "third_party/skia/include/core/SkPicture.h" |
-#include "ui/gfx/frame_time.h" |
-#include "ui/gfx/geometry/point_conversions.h" |
-#include "ui/gfx/geometry/size_conversions.h" |
-#include "ui/gfx/geometry/vector2d_conversions.h" |
- |
-using testing::_; |
-using testing::AnyNumber; |
-using testing::AtLeast; |
-using testing::Mock; |
- |
-namespace cc { |
-namespace { |
- |
-class LayerTreeHostTest : public LayerTreeTest { |
- public: |
- LayerTreeHostTest() : contents_texture_manager_(nullptr) {} |
- |
- void DidInitializeOutputSurface() override { |
- contents_texture_manager_ = layer_tree_host()->contents_texture_manager(); |
- } |
- |
- protected: |
- PrioritizedResourceManager* contents_texture_manager_; |
-}; |
- |
-// Test if the LTHI receives ReadyToActivate notifications from the TileManager |
-// when no raster tasks get scheduled. |
-class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestReadyToActivateEmpty() |
- : did_notify_ready_to_activate_(false), |
- all_tiles_required_for_activation_are_ready_to_draw_(false), |
- required_for_activation_count_(0) {} |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- const std::vector<PictureLayerImpl*>& layers = |
- impl->sync_tree()->picture_layers(); |
- required_for_activation_count_ = 0; |
- for (const auto& layer : layers) { |
- FakePictureLayerImpl* fake_layer = |
- static_cast<FakePictureLayerImpl*>(layer); |
- required_for_activation_count_ += |
- fake_layer->CountTilesRequiredForActivation(); |
- } |
- } |
- |
- void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { |
- did_notify_ready_to_activate_ = true; |
- all_tiles_required_for_activation_are_ready_to_draw_ = |
- impl->tile_manager()->IsReadyToActivate(); |
- EndTest(); |
- } |
- |
- void AfterTest() override { |
- EXPECT_TRUE(did_notify_ready_to_activate_); |
- EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_); |
- EXPECT_EQ(size_t(0), required_for_activation_count_); |
- } |
- |
- protected: |
- bool did_notify_ready_to_activate_; |
- bool all_tiles_required_for_activation_are_ready_to_draw_; |
- size_t required_for_activation_count_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty); |
- |
-// Test if the LTHI receives ReadyToActivate notifications from the TileManager |
-// when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled. |
-class LayerTreeHostTestReadyToActivateNonEmpty |
- : public LayerTreeHostTestReadyToActivateEmpty { |
- public: |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- scoped_refptr<FakePictureLayer> root_layer = |
- FakePictureLayer::Create(&client_); |
- root_layer->SetBounds(gfx::Size(1024, 1024)); |
- root_layer->SetIsDrawable(true); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void AfterTest() override { |
- EXPECT_TRUE(did_notify_ready_to_activate_); |
- EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_); |
- EXPECT_LE(size_t(1), required_for_activation_count_); |
- } |
- |
- private: |
- FakeContentLayerClient client_; |
-}; |
- |
-// Multi-thread only because in single thread the commit goes directly to the |
-// active tree, so notify ready to activate is skipped. |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty); |
- |
-// Test if the LTHI receives ReadyToDraw notifications from the TileManager when |
-// no raster tasks get scheduled. |
-class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestReadyToDrawEmpty() |
- : did_notify_ready_to_draw_(false), |
- all_tiles_required_for_draw_are_ready_to_draw_(false), |
- required_for_draw_count_(0) {} |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override { |
- did_notify_ready_to_draw_ = true; |
- const std::vector<PictureLayerImpl*>& layers = |
- impl->active_tree()->picture_layers(); |
- all_tiles_required_for_draw_are_ready_to_draw_ = |
- impl->tile_manager()->IsReadyToDraw(); |
- for (const auto& layer : layers) { |
- FakePictureLayerImpl* fake_layer = |
- static_cast<FakePictureLayerImpl*>(layer); |
- required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw(); |
- } |
- |
- EndTest(); |
- } |
- |
- void AfterTest() override { |
- EXPECT_TRUE(did_notify_ready_to_draw_); |
- EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_); |
- EXPECT_EQ(size_t(0), required_for_draw_count_); |
- } |
- |
- protected: |
- bool did_notify_ready_to_draw_; |
- bool all_tiles_required_for_draw_are_ready_to_draw_; |
- size_t required_for_draw_count_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty); |
- |
-// Test if the LTHI receives ReadyToDraw notifications from the TileManager when |
-// some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled. |
-class LayerTreeHostTestReadyToDrawNonEmpty |
- : public LayerTreeHostTestReadyToDrawEmpty { |
- public: |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- scoped_refptr<FakePictureLayer> root_layer = |
- FakePictureLayer::Create(&client_); |
- root_layer->SetBounds(gfx::Size(1024, 1024)); |
- root_layer->SetIsDrawable(true); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void AfterTest() override { |
- EXPECT_TRUE(did_notify_ready_to_draw_); |
- EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_); |
- EXPECT_LE(size_t(1), required_for_draw_count_); |
- } |
- |
- private: |
- FakeContentLayerClient client_; |
-}; |
- |
-// Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in |
-// single threaded mode. |
-SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty); |
- |
-// Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 |
-// draw with frame 0. |
-class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {} |
- |
- void BeginTest() override { |
- PostSetNeedsCommitToMainThread(); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- num_draws_++; |
- if (!impl->active_tree()->source_frame_number()) |
- EndTest(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- num_commits_++; |
- } |
- |
- void AfterTest() override { |
- EXPECT_LE(1, num_commits_); |
- EXPECT_LE(1, num_draws_); |
- } |
- |
- private: |
- int num_commits_; |
- int num_draws_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1); |
- |
-// A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that |
-// first committed frame draws should lead to another commit. |
-class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {} |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- ++num_commits_; |
- switch (num_commits_) { |
- case 1: |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 2: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- } |
- |
- void AfterTest() override { |
- EXPECT_EQ(2, num_commits_); |
- EXPECT_LE(1, num_draws_); |
- } |
- |
- private: |
- int num_commits_; |
- int num_draws_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); |
- |
-// Verify that we pass property values in PushPropertiesTo. |
-class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { |
- protected: |
- void SetupTree() override { |
- scoped_refptr<Layer> root = Layer::Create(); |
- root->CreateRenderSurface(); |
- root->SetBounds(gfx::Size(10, 10)); |
- layer_tree_host()->SetRootLayer(root); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- enum Properties { |
- STARTUP, |
- BOUNDS, |
- HIDE_LAYER_AND_SUBTREE, |
- DRAWS_CONTENT, |
- DONE, |
- }; |
- |
- void BeginTest() override { |
- index_ = STARTUP; |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- VerifyAfterValues(impl->active_tree()->root_layer()); |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- SetBeforeValues(layer_tree_host()->root_layer()); |
- VerifyBeforeValues(layer_tree_host()->root_layer()); |
- |
- ++index_; |
- if (index_ == DONE) { |
- EndTest(); |
- return; |
- } |
- |
- SetAfterValues(layer_tree_host()->root_layer()); |
- } |
- |
- void AfterTest() override {} |
- |
- void VerifyBeforeValues(Layer* layer) { |
- EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString()); |
- EXPECT_FALSE(layer->hide_layer_and_subtree()); |
- EXPECT_FALSE(layer->DrawsContent()); |
- } |
- |
- void SetBeforeValues(Layer* layer) { |
- layer->SetBounds(gfx::Size(10, 10)); |
- layer->SetHideLayerAndSubtree(false); |
- layer->SetIsDrawable(false); |
- } |
- |
- void VerifyAfterValues(LayerImpl* layer) { |
- switch (static_cast<Properties>(index_)) { |
- case STARTUP: |
- case DONE: |
- break; |
- case BOUNDS: |
- EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString()); |
- break; |
- case HIDE_LAYER_AND_SUBTREE: |
- EXPECT_TRUE(layer->hide_layer_and_subtree()); |
- break; |
- case DRAWS_CONTENT: |
- EXPECT_TRUE(layer->DrawsContent()); |
- break; |
- } |
- } |
- |
- void SetAfterValues(Layer* layer) { |
- switch (static_cast<Properties>(index_)) { |
- case STARTUP: |
- case DONE: |
- break; |
- case BOUNDS: |
- layer->SetBounds(gfx::Size(20, 20)); |
- break; |
- case HIDE_LAYER_AND_SUBTREE: |
- layer->SetHideLayerAndSubtree(true); |
- break; |
- case DRAWS_CONTENT: |
- layer->SetIsDrawable(true); |
- break; |
- } |
- } |
- |
- int index_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo); |
- |
-// 1 setNeedsRedraw after the first commit has completed should lead to 1 |
-// additional draw. |
-class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {} |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- EXPECT_EQ(0, impl->active_tree()->source_frame_number()); |
- if (!num_draws_) { |
- // Redraw again to verify that the second redraw doesn't commit. |
- PostSetNeedsRedrawToMainThread(); |
- } else { |
- EndTest(); |
- } |
- num_draws_++; |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- EXPECT_EQ(0, num_draws_); |
- num_commits_++; |
- } |
- |
- void AfterTest() override { |
- EXPECT_GE(2, num_draws_); |
- EXPECT_EQ(1, num_commits_); |
- } |
- |
- private: |
- int num_commits_; |
- int num_draws_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw); |
- |
-// After setNeedsRedrawRect(invalid_rect) the final damage_rect |
-// must contain invalid_rect. |
-class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSetNeedsRedrawRect() |
- : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {} |
- |
- void BeginTest() override { |
- if (layer_tree_host()->settings().impl_side_painting) |
- root_layer_ = FakePictureLayer::Create(&client_); |
- else |
- root_layer_ = ContentLayer::Create(&client_); |
- root_layer_->SetIsDrawable(true); |
- root_layer_->SetBounds(bounds_); |
- layer_tree_host()->SetRootLayer(root_layer_); |
- layer_tree_host()->SetViewportSize(bounds_); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- EXPECT_EQ(DRAW_SUCCESS, draw_result); |
- |
- gfx::RectF root_damage_rect; |
- if (!frame_data->render_passes.empty()) |
- root_damage_rect = frame_data->render_passes.back()->damage_rect; |
- |
- if (!num_draws_) { |
- // If this is the first frame, expect full frame damage. |
- EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_)); |
- } else { |
- // Check that invalid_rect_ is indeed repainted. |
- EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_)); |
- } |
- |
- return draw_result; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- if (!num_draws_) { |
- PostSetNeedsRedrawRectToMainThread(invalid_rect_); |
- } else { |
- EndTest(); |
- } |
- num_draws_++; |
- } |
- |
- void AfterTest() override { EXPECT_EQ(2, num_draws_); } |
- |
- private: |
- int num_draws_; |
- const gfx::Size bounds_; |
- const gfx::Rect invalid_rect_; |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_layer_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect); |
- |
-// Ensure the texture size of the pending and active trees are identical when a |
-// layer is not in the viewport and a resize happens on the viewport |
-class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestGpuRasterDeviceSizeChanged() |
- : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {} |
- |
- void BeginTest() override { |
- client_.set_fill_with_nonsolid_color(true); |
- root_layer_ = FakePictureLayer::Create(&client_); |
- root_layer_->SetIsDrawable(true); |
- gfx::Transform transform; |
- // Translate the layer out of the viewport to force it to not update its |
- // tile size via PushProperties. |
- transform.Translate(10000.0, 10000.0); |
- root_layer_->SetTransform(transform); |
- root_layer_->SetBounds(bounds_); |
- layer_tree_host()->SetRootLayer(root_layer_); |
- layer_tree_host()->SetViewportSize(bounds_); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->gpu_rasterization_enabled = true; |
- settings->gpu_rasterization_forced = true; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- // Perform 2 commits. |
- if (!num_draws_) { |
- PostSetNeedsRedrawRectToMainThread(invalid_rect_); |
- } else { |
- EndTest(); |
- } |
- num_draws_++; |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- if (num_draws_ == 2) { |
- auto pending_tree = host_impl->pending_tree(); |
- auto pending_layer_impl = |
- static_cast<FakePictureLayerImpl*>(pending_tree->root_layer()); |
- EXPECT_NE(pending_layer_impl, nullptr); |
- |
- auto active_tree = host_impl->pending_tree(); |
- auto active_layer_impl = |
- static_cast<FakePictureLayerImpl*>(active_tree->root_layer()); |
- EXPECT_NE(pending_layer_impl, nullptr); |
- |
- auto active_tiling_set = active_layer_impl->picture_layer_tiling_set(); |
- auto active_tiling = active_tiling_set->tiling_at(0); |
- auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set(); |
- auto pending_tiling = pending_tiling_set->tiling_at(0); |
- EXPECT_EQ( |
- pending_tiling->TilingDataForTesting().max_texture_size().width(), |
- active_tiling->TilingDataForTesting().max_texture_size().width()); |
- } |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- // On the second commit, resize the viewport. |
- if (num_draws_ == 1) { |
- layer_tree_host()->SetViewportSize(gfx::Size(400, 64)); |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- int num_draws_; |
- const gfx::Size bounds_; |
- const gfx::Rect invalid_rect_; |
- FakeContentLayerClient client_; |
- scoped_refptr<FakePictureLayer> root_layer_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F( |
- LayerTreeHostTestGpuRasterDeviceSizeChanged); |
- |
-class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { |
- public: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->layer_transforms_should_scale_layer_contents = true; |
- } |
- |
- void SetupTree() override { |
- root_layer_ = Layer::Create(); |
- root_layer_->SetBounds(gfx::Size(10, 20)); |
- root_layer_->CreateRenderSurface(); |
- |
- if (layer_tree_host()->settings().impl_side_painting) |
- scaled_layer_ = FakePictureLayer::Create(&client_); |
- else |
- scaled_layer_ = FakeContentLayer::Create(&client_); |
- scaled_layer_->SetBounds(gfx::Size(1, 1)); |
- root_layer_->AddChild(scaled_layer_); |
- |
- layer_tree_host()->SetRootLayer(root_layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- if (host_impl->active_tree()->source_frame_number() == 1) |
- EndTest(); |
- } |
- |
- void DidCommit() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- // SetBounds grows the layer and exposes new content. |
- if (layer_tree_host()->settings().impl_side_painting) { |
- scaled_layer_->SetBounds(gfx::Size(4, 4)); |
- } else { |
- // Changing the device scale factor causes a commit. It also changes |
- // the content bounds of |scaled_layer_|, which should not generate |
- // a second commit as a result. |
- layer_tree_host()->SetDeviceScaleFactor(4.f); |
- } |
- break; |
- default: |
- // No extra commits. |
- EXPECT_EQ(2, layer_tree_host()->source_frame_number()); |
- } |
- } |
- |
- void AfterTest() override { |
- EXPECT_EQ(gfx::Size(4, 4).ToString(), |
- scaled_layer_->content_bounds().ToString()); |
- } |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_layer_; |
- scoped_refptr<Layer> scaled_layer_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate); |
- |
-class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate |
- : public LayerTreeHostTest { |
- public: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->layer_transforms_should_scale_layer_contents = true; |
- } |
- |
- void SetupTree() override { |
- root_layer_ = Layer::Create(); |
- root_layer_->SetBounds(gfx::Size(10, 20)); |
- root_layer_->CreateRenderSurface(); |
- |
- bool paint_scrollbar = true; |
- bool has_thumb = false; |
- scrollbar_ = FakePaintedScrollbarLayer::Create( |
- paint_scrollbar, has_thumb, root_layer_->id()); |
- scrollbar_->SetPosition(gfx::Point(0, 10)); |
- scrollbar_->SetBounds(gfx::Size(10, 10)); |
- |
- root_layer_->AddChild(scrollbar_); |
- |
- layer_tree_host()->SetRootLayer(root_layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- if (host_impl->active_tree()->source_frame_number() == 1) |
- EndTest(); |
- } |
- |
- void DidCommit() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- // Changing the device scale factor causes a commit. It also changes |
- // the content bounds of |scrollbar_|, which should not generate |
- // a second commit as a result. |
- layer_tree_host()->SetDeviceScaleFactor(4.f); |
- break; |
- default: |
- // No extra commits. |
- EXPECT_EQ(2, layer_tree_host()->source_frame_number()); |
- } |
- } |
- |
- void AfterTest() override { |
- EXPECT_EQ(gfx::Size(40, 40).ToString(), |
- scrollbar_->internal_content_bounds().ToString()); |
- } |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_layer_; |
- scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F( |
- LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate); |
- |
-class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSetNextCommitForcesRedraw() |
- : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {} |
- |
- void BeginTest() override { |
- if (layer_tree_host()->settings().impl_side_painting) |
- root_layer_ = FakePictureLayer::Create(&client_); |
- else |
- root_layer_ = ContentLayer::Create(&client_); |
- root_layer_->SetIsDrawable(true); |
- root_layer_->SetBounds(bounds_); |
- layer_tree_host()->SetRootLayer(root_layer_); |
- layer_tree_host()->SetViewportSize(bounds_); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- if (num_draws_ == 3 && host_impl->settings().impl_side_painting) |
- host_impl->SetNeedsRedrawRect(invalid_rect_); |
- } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- EXPECT_EQ(DRAW_SUCCESS, draw_result); |
- |
- gfx::RectF root_damage_rect; |
- if (!frame_data->render_passes.empty()) |
- root_damage_rect = frame_data->render_passes.back()->damage_rect; |
- |
- switch (num_draws_) { |
- case 0: |
- EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect); |
- break; |
- case 1: |
- case 2: |
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect); |
- break; |
- case 3: |
- EXPECT_EQ(invalid_rect_, root_damage_rect); |
- break; |
- case 4: |
- EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- |
- return draw_result; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- switch (num_draws_) { |
- case 0: |
- case 1: |
- // Cycle through a couple of empty commits to ensure we're observing the |
- // right behavior |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 2: |
- // Should force full frame damage on the next commit |
- PostSetNextCommitForcesRedrawToMainThread(); |
- PostSetNeedsCommitToMainThread(); |
- if (host_impl->settings().impl_side_painting) |
- host_impl->BlockNotifyReadyToActivateForTesting(true); |
- else |
- num_draws_++; |
- break; |
- case 3: |
- host_impl->BlockNotifyReadyToActivateForTesting(false); |
- break; |
- default: |
- EndTest(); |
- break; |
- } |
- num_draws_++; |
- } |
- |
- void AfterTest() override { EXPECT_EQ(5, num_draws_); } |
- |
- private: |
- int num_draws_; |
- const gfx::Size bounds_; |
- const gfx::Rect invalid_rect_; |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_layer_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( |
- LayerTreeHostTestSetNextCommitForcesRedraw); |
- |
-// Tests that if a layer is not drawn because of some reason in the parent then |
-// its damage is preserved until the next time it is drawn. |
-class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestUndrawnLayersDamageLater() {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- // If we don't set the minimum contents scale, it's harder to verify whether |
- // the damage we get is correct. For other scale amounts, please see |
- // LayerTreeHostTestDamageWithScale. |
- settings->minimum_contents_scale = 1.f; |
- } |
- |
- void SetupTree() override { |
- if (layer_tree_host()->settings().impl_side_painting) |
- root_layer_ = FakePictureLayer::Create(&client_); |
- else |
- root_layer_ = ContentLayer::Create(&client_); |
- root_layer_->SetIsDrawable(true); |
- root_layer_->SetBounds(gfx::Size(50, 50)); |
- layer_tree_host()->SetRootLayer(root_layer_); |
- |
- // The initially transparent layer has a larger child layer, which is |
- // not initially drawn because of the this (parent) layer. |
- if (layer_tree_host()->settings().impl_side_painting) |
- parent_layer_ = FakePictureLayer::Create(&client_); |
- else |
- parent_layer_ = FakeContentLayer::Create(&client_); |
- parent_layer_->SetBounds(gfx::Size(15, 15)); |
- parent_layer_->SetOpacity(0.0f); |
- root_layer_->AddChild(parent_layer_); |
- |
- if (layer_tree_host()->settings().impl_side_painting) |
- child_layer_ = FakePictureLayer::Create(&client_); |
- else |
- child_layer_ = FakeContentLayer::Create(&client_); |
- child_layer_->SetBounds(gfx::Size(25, 25)); |
- parent_layer_->AddChild(child_layer_); |
- |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- EXPECT_EQ(DRAW_SUCCESS, draw_result); |
- |
- gfx::RectF root_damage_rect; |
- if (!frame_data->render_passes.empty()) |
- root_damage_rect = frame_data->render_passes.back()->damage_rect; |
- |
- // The first time, the whole view needs be drawn. |
- // Afterwards, just the opacity of surface_layer1 is changed a few times, |
- // and each damage should be the bounding box of it and its child. If this |
- // was working improperly, the damage might not include its childs bounding |
- // box. |
- switch (host_impl->active_tree()->source_frame_number()) { |
- case 0: |
- EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect); |
- break; |
- case 1: |
- case 2: |
- case 3: |
- EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- |
- return draw_result; |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- // Test not owning the surface. |
- parent_layer_->SetOpacity(1.0f); |
- break; |
- case 2: |
- parent_layer_->SetOpacity(0.0f); |
- break; |
- case 3: |
- // Test owning the surface. |
- parent_layer_->SetOpacity(0.5f); |
- parent_layer_->SetForceRenderSurface(true); |
- break; |
- case 4: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_layer_; |
- scoped_refptr<Layer> parent_layer_; |
- scoped_refptr<Layer> child_layer_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater); |
- |
-// Tests that if a layer is not drawn because of some reason in the parent then |
-// its damage is preserved until the next time it is drawn. |
-class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestDamageWithScale() {} |
- |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- |
- scoped_ptr<FakePicturePile> pile( |
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, |
- ImplSidePaintingSettings().default_tile_grid_size)); |
- root_layer_ = |
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); |
- root_layer_->SetBounds(gfx::Size(50, 50)); |
- |
- pile.reset( |
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, |
- ImplSidePaintingSettings().default_tile_grid_size)); |
- child_layer_ = |
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); |
- child_layer_->SetBounds(gfx::Size(25, 25)); |
- child_layer_->SetIsDrawable(true); |
- child_layer_->SetContentsOpaque(true); |
- root_layer_->AddChild(child_layer_); |
- |
- layer_tree_host()->SetRootLayer(root_layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- // Force the layer to have a tiling at 1.3f scale. Note that if we simply |
- // add tiling, it will be gone by the time we draw because of aggressive |
- // cleanup. AddTilingUntilNextDraw ensures that it remains there during |
- // damage calculation. |
- FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( |
- host_impl->active_tree()->LayerById(child_layer_->id())); |
- child_layer_impl->AddTilingUntilNextDraw(1.3f); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- EXPECT_EQ(DRAW_SUCCESS, draw_result); |
- |
- gfx::RectF root_damage_rect; |
- if (!frame_data->render_passes.empty()) |
- root_damage_rect = frame_data->render_passes.back()->damage_rect; |
- |
- // The first time, the whole view needs be drawn. |
- // Afterwards, just the opacity of surface_layer1 is changed a few times, |
- // and each damage should be the bounding box of it and its child. If this |
- // was working improperly, the damage might not include its childs bounding |
- // box. |
- switch (host_impl->active_tree()->source_frame_number()) { |
- case 0: |
- EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect); |
- break; |
- case 1: { |
- FakePictureLayerImpl* child_layer_impl = |
- static_cast<FakePictureLayerImpl*>( |
- host_impl->active_tree()->LayerById(child_layer_->id())); |
- // We remove tilings pretty aggressively if they are not ideal. Add this |
- // back in so that we can compare |
- // child_layer_impl->GetEnclosingRectInTargetSpace to the damage. |
- child_layer_impl->AddTilingUntilNextDraw(1.3f); |
- |
- EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect); |
- EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(), |
- root_damage_rect); |
- EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains( |
- gfx::Rect(child_layer_->bounds()))); |
- break; |
- } |
- default: |
- NOTREACHED(); |
- } |
- |
- return draw_result; |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: { |
- // Test not owning the surface. |
- child_layer_->SetOpacity(0.5f); |
- break; |
- } |
- case 2: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_layer_; |
- scoped_refptr<Layer> child_layer_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale); |
- |
-// Tests that if a layer is not drawn because of some reason in the parent, |
-// causing its content bounds to not be computed, then when it is later drawn, |
-// its content bounds get pushed. |
-class LayerTreeHostTestUndrawnLayersPushContentBoundsLater |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestUndrawnLayersPushContentBoundsLater() |
- : root_layer_(Layer::Create()) {} |
- |
- void SetupTree() override { |
- root_layer_->CreateRenderSurface(); |
- root_layer_->SetIsDrawable(true); |
- root_layer_->SetBounds(gfx::Size(20, 20)); |
- layer_tree_host()->SetRootLayer(root_layer_); |
- |
- parent_layer_ = Layer::Create(); |
- parent_layer_->SetBounds(gfx::Size(20, 20)); |
- parent_layer_->SetOpacity(0.0f); |
- root_layer_->AddChild(parent_layer_); |
- |
- child_layer_ = Layer::Create(); |
- child_layer_->SetBounds(gfx::Size(15, 15)); |
- parent_layer_->AddChild(child_layer_); |
- |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- LayerImpl* root = host_impl->active_tree()->root_layer(); |
- LayerImpl* parent = root->children()[0]; |
- LayerImpl* child = parent->children()[0]; |
- |
- switch (host_impl->active_tree()->source_frame_number()) { |
- case 0: |
- EXPECT_EQ(0.f, parent->opacity()); |
- EXPECT_EQ(gfx::SizeF(), child->content_bounds()); |
- break; |
- case 1: |
- EXPECT_EQ(1.f, parent->opacity()); |
- EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds()); |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- } |
- |
- void DidCommit() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- parent_layer_->SetOpacity(1.0f); |
- break; |
- case 2: |
- break; |
- default: |
- NOTREACHED(); |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- scoped_refptr<Layer> root_layer_; |
- scoped_refptr<Layer> parent_layer_; |
- scoped_refptr<Layer> child_layer_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F( |
- LayerTreeHostTestUndrawnLayersPushContentBoundsLater); |
- |
-// This test verifies that properties on the layer tree host are commited |
-// to the impl side. |
-class LayerTreeHostTestCommit : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestCommit() {} |
- |
- void BeginTest() override { |
- layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); |
- layer_tree_host()->set_background_color(SK_ColorGRAY); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize()); |
- EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color()); |
- |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); |
- |
-// This test verifies that LayerTreeHostImpl's current frame time gets |
-// updated in consecutive frames when it doesn't draw due to tree |
-// activation failure. |
-class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() |
- : frame_count_with_pending_tree_(0) {} |
- |
- void BeginTest() override { |
- layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); |
- layer_tree_host()->set_background_color(SK_ColorGRAY); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void BeginCommitOnThread(LayerTreeHostImpl* impl) override { |
- EXPECT_EQ(frame_count_with_pending_tree_, 0); |
- if (impl->settings().impl_side_painting) |
- impl->BlockNotifyReadyToActivateForTesting(true); |
- } |
- |
- void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl, |
- const BeginFrameArgs& args) override { |
- if (impl->pending_tree()) |
- frame_count_with_pending_tree_++; |
- |
- if (frame_count_with_pending_tree_ == 1) { |
- EXPECT_EQ(first_frame_time_.ToInternalValue(), 0); |
- first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; |
- } else if (frame_count_with_pending_tree_ == 2 && |
- impl->settings().impl_side_painting) { |
- impl->BlockNotifyReadyToActivateForTesting(false); |
- } |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- if (frame_count_with_pending_tree_ > 1) { |
- EXPECT_NE(first_frame_time_.ToInternalValue(), 0); |
- EXPECT_NE(first_frame_time_.ToInternalValue(), |
- impl->CurrentBeginFrameArgs().frame_time.ToInternalValue()); |
- EndTest(); |
- return; |
- } |
- |
- EXPECT_FALSE(impl->settings().impl_side_painting); |
- EndTest(); |
- } |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- if (impl->settings().impl_side_painting) |
- EXPECT_NE(frame_count_with_pending_tree_, 1); |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- int frame_count_with_pending_tree_; |
- base::TimeTicks first_frame_time_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( |
- LayerTreeHostTestFrameTimeUpdatesAfterActivationFails); |
- |
-// This test verifies that LayerTreeHostImpl's current frame time gets |
-// updated in consecutive frames when it draws in each frame. |
-class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {} |
- |
- void BeginTest() override { |
- layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); |
- layer_tree_host()->set_background_color(SK_ColorGRAY); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- frame_++; |
- if (frame_ == 1) { |
- first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; |
- impl->SetNeedsRedraw(); |
- |
- // Since we might use a low-resolution clock on Windows, we need to |
- // make sure that the clock has incremented past first_frame_time_. |
- while (first_frame_time_ == gfx::FrameTime::Now()) { |
- } |
- |
- return; |
- } |
- |
- EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time); |
- EndTest(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- // Ensure there isn't a commit between the two draws, to ensure that a |
- // commit isn't required for updating the current frame time. We can |
- // only check for this in the multi-threaded case, since in the single- |
- // threaded case there will always be a commit between consecutive draws. |
- if (HasImplThread()) |
- EXPECT_EQ(0, frame_); |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- int frame_; |
- base::TimeTicks first_frame_time_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); |
- |
-// Verifies that StartPageScaleAnimation events propagate correctly |
-// from LayerTreeHost to LayerTreeHostImpl in the MT compositor. |
-class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestStartPageScaleAnimation() {} |
- |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- |
- if (layer_tree_host()->settings().impl_side_painting) { |
- scoped_refptr<FakePictureLayer> layer = |
- FakePictureLayer::Create(&client_); |
- layer->set_always_update_resources(true); |
- scroll_layer_ = layer; |
- } else { |
- scroll_layer_ = FakeContentLayer::Create(&client_); |
- } |
- |
- Layer* root_layer = layer_tree_host()->root_layer(); |
- scroll_layer_->SetScrollClipLayerId(root_layer->id()); |
- scroll_layer_->SetIsContainerForFixedPositionLayers(true); |
- scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(), |
- 2 * root_layer->bounds().height())); |
- scroll_layer_->SetScrollOffset(gfx::ScrollOffset()); |
- layer_tree_host()->root_layer()->AddChild(scroll_layer_); |
- // This test requires the page_scale and inner viewport layers to be |
- // identified. |
- layer_tree_host()->RegisterViewportLayers(NULL, root_layer, |
- scroll_layer_.get(), NULL); |
- layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, |
- float scale, |
- float) override { |
- gfx::ScrollOffset offset = scroll_layer_->scroll_offset(); |
- scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset, |
- scroll_delta)); |
- layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- // We get one commit before the first draw, and the animation doesn't happen |
- // until the second draw. |
- switch (impl->active_tree()->source_frame_number()) { |
- case 0: |
- EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); |
- // We'll start an animation when we get back to the main thread. |
- break; |
- case 1: |
- EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); |
- break; |
- case 2: |
- EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor()); |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- layer_tree_host()->StartPageScaleAnimation( |
- gfx::Vector2d(), false, 1.25f, base::TimeDelta()); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> scroll_layer_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); |
- |
-class LayerTreeHostTestSetVisible : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSetVisible() : num_draws_(0) {} |
- |
- void BeginTest() override { |
- PostSetNeedsCommitToMainThread(); |
- PostSetVisibleToMainThread(false); |
- // This is suppressed while we're invisible. |
- PostSetNeedsRedrawToMainThread(); |
- // Triggers the redraw. |
- PostSetVisibleToMainThread(true); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- EXPECT_TRUE(impl->visible()); |
- ++num_draws_; |
- EndTest(); |
- } |
- |
- void AfterTest() override { EXPECT_EQ(1, num_draws_); } |
- |
- private: |
- int num_draws_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible); |
- |
-class TestOpacityChangeLayerDelegate : public ContentLayerClient { |
- public: |
- TestOpacityChangeLayerDelegate() : test_layer_(0) {} |
- |
- void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; } |
- |
- void PaintContents(SkCanvas* canvas, |
- const gfx::Rect& clip, |
- PaintingControlSetting picture_control) override { |
- // Set layer opacity to 0. |
- if (test_layer_) |
- test_layer_->SetOpacity(0.f); |
- } |
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList( |
- const gfx::Rect& clip, |
- PaintingControlSetting picture_control) override { |
- NOTIMPLEMENTED(); |
- return DisplayItemList::Create(); |
- } |
- bool FillsBoundsCompletely() const override { return false; } |
- |
- private: |
- Layer* test_layer_; |
-}; |
- |
-class ContentLayerWithUpdateTracking : public ContentLayer { |
- public: |
- static scoped_refptr<ContentLayerWithUpdateTracking> Create( |
- ContentLayerClient* client) { |
- return make_scoped_refptr(new ContentLayerWithUpdateTracking(client)); |
- } |
- |
- int PaintContentsCount() { return paint_contents_count_; } |
- void ResetPaintContentsCount() { paint_contents_count_ = 0; } |
- |
- bool Update(ResourceUpdateQueue* queue, |
- const OcclusionTracker<Layer>* occlusion) override { |
- bool updated = ContentLayer::Update(queue, occlusion); |
- paint_contents_count_++; |
- return updated; |
- } |
- |
- private: |
- explicit ContentLayerWithUpdateTracking(ContentLayerClient* client) |
- : ContentLayer(client), paint_contents_count_(0) { |
- SetBounds(gfx::Size(10, 10)); |
- SetIsDrawable(true); |
- } |
- ~ContentLayerWithUpdateTracking() override {} |
- |
- int paint_contents_count_; |
-}; |
- |
-// Layer opacity change during paint should not prevent compositor resources |
-// from being updated during commit. |
-class LayerTreeHostTestOpacityChange : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {} |
- |
- void BeginTest() override { |
- if (layer_tree_host()->settings().impl_side_painting) { |
- update_check_picture_layer_ = |
- FakePictureLayer::Create(&test_opacity_change_delegate_); |
- test_opacity_change_delegate_.SetTestLayer( |
- update_check_picture_layer_.get()); |
- is_impl_paint_ = true; |
- } else { |
- update_check_content_layer_ = ContentLayerWithUpdateTracking::Create( |
- &test_opacity_change_delegate_); |
- test_opacity_change_delegate_.SetTestLayer( |
- update_check_content_layer_.get()); |
- is_impl_paint_ = false; |
- } |
- layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); |
- if (layer_tree_host()->settings().impl_side_painting) |
- layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_); |
- else |
- layer_tree_host()->root_layer()->AddChild(update_check_content_layer_); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); } |
- |
- void AfterTest() override { |
- // Update() should have been called once. |
- if (is_impl_paint_) |
- EXPECT_EQ(1u, update_check_picture_layer_->update_count()); |
- else |
- EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount()); |
- } |
- |
- private: |
- TestOpacityChangeLayerDelegate test_opacity_change_delegate_; |
- scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_; |
- scoped_refptr<FakePictureLayer> update_check_picture_layer_; |
- bool is_impl_paint_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange); |
- |
-class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- // PictureLayer can only be used with impl side painting enabled. |
- settings->impl_side_painting = true; |
- } |
- |
- void BeginTest() override { |
- client_.set_fill_with_nonsolid_color(true); |
- root_layer_ = FakePictureLayer::Create(&client_); |
- child_layer_ = FakePictureLayer::Create(&client_); |
- |
- layer_tree_host()->SetViewportSize(gfx::Size(60, 60)); |
- layer_tree_host()->SetDeviceScaleFactor(1.5); |
- EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size()); |
- |
- root_layer_->AddChild(child_layer_); |
- |
- root_layer_->SetIsDrawable(true); |
- root_layer_->SetBounds(gfx::Size(30, 30)); |
- |
- child_layer_->SetIsDrawable(true); |
- child_layer_->SetPosition(gfx::Point(2, 2)); |
- child_layer_->SetBounds(gfx::Size(10, 10)); |
- |
- layer_tree_host()->SetRootLayer(root_layer_); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- // Should only do one commit. |
- EXPECT_EQ(0, impl->active_tree()->source_frame_number()); |
- // Device scale factor should come over to impl. |
- EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f); |
- |
- // Both layers are on impl. |
- ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size()); |
- |
- // Device viewport is scaled. |
- EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize()); |
- |
- FakePictureLayerImpl* root = |
- static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); |
- FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>( |
- impl->active_tree()->root_layer()->children()[0]); |
- |
- // Positions remain in layout pixels. |
- EXPECT_EQ(gfx::Point(0, 0), root->position()); |
- EXPECT_EQ(gfx::Point(2, 2), child->position()); |
- |
- // Compute all the layer transforms for the frame. |
- LayerTreeHostImpl::FrameData frame_data; |
- impl->PrepareToDraw(&frame_data); |
- impl->DidDrawAllLayers(frame_data); |
- |
- const LayerImplList& render_surface_layer_list = |
- *frame_data.render_surface_layer_list; |
- |
- // Both layers should be drawing into the root render surface. |
- ASSERT_EQ(1u, render_surface_layer_list.size()); |
- ASSERT_EQ(root->render_surface(), |
- render_surface_layer_list[0]->render_surface()); |
- ASSERT_EQ(2u, root->render_surface()->layer_list().size()); |
- |
- // The root render surface is the size of the viewport. |
- EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect()); |
- |
- // The max tiling scale of the child should be scaled. |
- EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale()); |
- |
- gfx::Transform scale_transform; |
- scale_transform.Scale(impl->device_scale_factor(), |
- impl->device_scale_factor()); |
- |
- // The root layer is scaled by 2x. |
- gfx::Transform root_screen_space_transform = scale_transform; |
- gfx::Transform root_draw_transform = scale_transform; |
- |
- EXPECT_EQ(root_draw_transform, root->draw_transform()); |
- EXPECT_EQ(root_screen_space_transform, root->screen_space_transform()); |
- |
- // The child is at position 2,2, which is transformed to 3,3 after the scale |
- gfx::Transform child_transform; |
- child_transform.Translate(3.f, 3.f); |
- child_transform.Scale(child->MaximumTilingContentsScale(), |
- child->MaximumTilingContentsScale()); |
- |
- EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform()); |
- EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, |
- child->screen_space_transform()); |
- |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<FakePictureLayer> root_layer_; |
- scoped_refptr<FakePictureLayer> child_layer_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); |
- |
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere. |
-// Verify atomicity of commits and reuse of textures. |
-class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { |
- public: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->renderer_settings.texture_id_allocation_chunk_size = 1; |
- // Make sure partial texture updates are turned off. |
- settings->max_partial_texture_updates = 0; |
- // Linear fade animator prevents scrollbars from drawing immediately. |
- settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR; |
- } |
- |
- void SetupTree() override { |
- layer_ = FakeContentLayer::Create(&client_); |
- layer_->SetBounds(gfx::Size(10, 20)); |
- |
- bool paint_scrollbar = true; |
- bool has_thumb = false; |
- scrollbar_ = FakePaintedScrollbarLayer::Create( |
- paint_scrollbar, has_thumb, layer_->id()); |
- scrollbar_->SetPosition(gfx::Point(0, 10)); |
- scrollbar_->SetBounds(gfx::Size(10, 10)); |
- |
- layer_->AddChild(scrollbar_); |
- |
- layer_tree_host()->SetRootLayer(layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { |
- drew_frame_ = -1; |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- ASSERT_EQ(0u, impl->settings().max_partial_texture_updates); |
- |
- TestWebGraphicsContext3D* context = TestContext(); |
- |
- switch (impl->active_tree()->source_frame_number()) { |
- case 0: |
- // Number of textures should be one for each layer |
- ASSERT_EQ(2u, context->NumTextures()); |
- // Number of textures used for commit should be one for each layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- // Verify that used texture is correct. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); |
- |
- context->ResetUsedTextures(); |
- break; |
- case 1: |
- // Number of textures should be one for scrollbar layer since it was |
- // requested and deleted on the impl-thread, and double for the content |
- // layer since its first texture is used by impl thread and cannot by |
- // used for update. |
- ASSERT_EQ(3u, context->NumTextures()); |
- // Number of textures used for commit should be one for each layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- // First textures should not have been used. |
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); |
- // New textures should have been used. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); |
- context->ResetUsedTextures(); |
- break; |
- case 2: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- TestWebGraphicsContext3D* context = TestContext(); |
- |
- if (drew_frame_ == impl->active_tree()->source_frame_number()) { |
- EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_; |
- return; |
- } |
- drew_frame_ = impl->active_tree()->source_frame_number(); |
- |
- // We draw/ship one texture each frame for each layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- context->ResetUsedTextures(); |
- |
- if (!TestEnded()) |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void Layout() override { |
- layer_->SetNeedsDisplay(); |
- scrollbar_->SetNeedsDisplay(); |
- } |
- |
- void AfterTest() override {} |
- |
- protected: |
- FakeContentLayerClient client_; |
- scoped_refptr<FakeContentLayer> layer_; |
- scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; |
- int drew_frame_; |
-}; |
- |
-MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( |
- LayerTreeHostTestDirectRendererAtomicCommit); |
- |
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere. |
-class LayerTreeHostTestDelegatingRendererAtomicCommit |
- : public LayerTreeHostTestDirectRendererAtomicCommit { |
- public: |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- ASSERT_EQ(0u, impl->settings().max_partial_texture_updates); |
- |
- TestWebGraphicsContext3D* context = TestContext(); |
- |
- switch (impl->active_tree()->source_frame_number()) { |
- case 0: |
- // Number of textures should be one for each layer |
- ASSERT_EQ(2u, context->NumTextures()); |
- // Number of textures used for commit should be one for each layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- // Verify that used texture is correct. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); |
- break; |
- case 1: |
- // Number of textures should be doubled as the first context layer |
- // texture is being used by the impl-thread and cannot be used for |
- // update. The scrollbar behavior is different direct renderer because |
- // UI resource deletion with delegating renderer occurs after tree |
- // activation. |
- ASSERT_EQ(4u, context->NumTextures()); |
- // Number of textures used for commit should still be |
- // one for each layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- // First textures should not have been used. |
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); |
- // New textures should have been used. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); |
- break; |
- case 2: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
-}; |
- |
-MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F( |
- LayerTreeHostTestDelegatingRendererAtomicCommit); |
- |
-static void SetLayerPropertiesForTesting(Layer* layer, |
- Layer* parent, |
- const gfx::Transform& transform, |
- const gfx::Point3F& transform_origin, |
- const gfx::PointF& position, |
- const gfx::Size& bounds, |
- bool opaque) { |
- layer->RemoveAllChildren(); |
- if (parent) |
- parent->AddChild(layer); |
- layer->SetTransform(transform); |
- layer->SetTransformOrigin(transform_origin); |
- layer->SetPosition(position); |
- layer->SetBounds(bounds); |
- layer->SetContentsOpaque(opaque); |
-} |
- |
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere. |
-class LayerTreeHostTestAtomicCommitWithPartialUpdate |
- : public LayerTreeHostTest { |
- public: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->renderer_settings.texture_id_allocation_chunk_size = 1; |
- // Allow one partial texture update. |
- settings->max_partial_texture_updates = 1; |
- // No partial updates when impl side painting is enabled. |
- settings->impl_side_painting = false; |
- } |
- |
- void SetupTree() override { |
- parent_ = FakeContentLayer::Create(&client_); |
- parent_->SetBounds(gfx::Size(10, 20)); |
- |
- child_ = FakeContentLayer::Create(&client_); |
- child_->SetPosition(gfx::Point(0, 10)); |
- child_->SetBounds(gfx::Size(3, 10)); |
- |
- parent_->AddChild(child_); |
- |
- layer_tree_host()->SetRootLayer(parent_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- parent_->SetNeedsDisplay(); |
- child_->SetNeedsDisplay(); |
- break; |
- case 2: |
- // Damage part of layers. |
- parent_->SetNeedsDisplayRect(gfx::Rect(5, 5)); |
- child_->SetNeedsDisplayRect(gfx::Rect(5, 5)); |
- break; |
- case 3: |
- child_->SetNeedsDisplay(); |
- layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); |
- break; |
- case 4: |
- layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); |
- break; |
- case 5: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED() << layer_tree_host()->source_frame_number(); |
- break; |
- } |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- ASSERT_EQ(1u, impl->settings().max_partial_texture_updates); |
- |
- TestWebGraphicsContext3D* context = TestContext(); |
- |
- switch (impl->active_tree()->source_frame_number()) { |
- case 0: |
- // Number of textures should be one for each layer. |
- ASSERT_EQ(2u, context->NumTextures()); |
- // Number of textures used for commit should be one for each layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- // Verify that used textures are correct. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); |
- context->ResetUsedTextures(); |
- break; |
- case 1: |
- if (HasImplThread()) { |
- // Number of textures should be two for each content layer. |
- ASSERT_EQ(4u, context->NumTextures()); |
- } else { |
- // In single thread we can always do partial updates, so the limit has |
- // no effect. |
- ASSERT_EQ(2u, context->NumTextures()); |
- } |
- // Number of textures used for commit should be one for each content |
- // layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- |
- if (HasImplThread()) { |
- // First content textures should not have been used. |
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); |
- // New textures should have been used. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); |
- } else { |
- // In single thread we can always do partial updates, so the limit has |
- // no effect. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); |
- } |
- |
- context->ResetUsedTextures(); |
- break; |
- case 2: |
- if (HasImplThread()) { |
- // Number of textures should be two for each content layer. |
- ASSERT_EQ(4u, context->NumTextures()); |
- } else { |
- // In single thread we can always do partial updates, so the limit has |
- // no effect. |
- ASSERT_EQ(2u, context->NumTextures()); |
- } |
- // Number of textures used for commit should be one for each content |
- // layer. |
- EXPECT_EQ(2u, context->NumUsedTextures()); |
- |
- if (HasImplThread()) { |
- // One content layer does a partial update also. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); |
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(3))); |
- } else { |
- // In single thread we can always do partial updates, so the limit has |
- // no effect. |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); |
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); |
- } |
- |
- context->ResetUsedTextures(); |
- break; |
- case 3: |
- // No textures should be used for commit. |
- EXPECT_EQ(0u, context->NumUsedTextures()); |
- |
- context->ResetUsedTextures(); |
- break; |
- case 4: |
- // Number of textures used for commit should be one, for the |
- // content layer. |
- EXPECT_EQ(1u, context->NumUsedTextures()); |
- |
- context->ResetUsedTextures(); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- EXPECT_LT(impl->active_tree()->source_frame_number(), 5); |
- |
- TestWebGraphicsContext3D* context = TestContext(); |
- |
- // Number of textures used for drawing should one per layer except for |
- // frame 3 where the viewport only contains one layer. |
- if (impl->active_tree()->source_frame_number() == 3) { |
- EXPECT_EQ(1u, context->NumUsedTextures()); |
- } else { |
- EXPECT_EQ(2u, context->NumUsedTextures()) |
- << "For frame " << impl->active_tree()->source_frame_number(); |
- } |
- |
- context->ResetUsedTextures(); |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<FakeContentLayer> parent_; |
- scoped_refptr<FakeContentLayer> child_; |
-}; |
- |
-// Partial updates are not possible with a delegating renderer. |
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( |
- LayerTreeHostTestAtomicCommitWithPartialUpdate); |
- |
-// TODO(sohanjg) : Make it work with impl-side painting. |
-class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit |
- : public LayerTreeHostTest { |
- protected: |
- void SetupTree() override { |
- root_layer_ = FakeContentLayer::Create(&client_); |
- root_layer_->SetBounds(gfx::Size(100, 100)); |
- |
- surface_layer1_ = FakeContentLayer::Create(&client_); |
- surface_layer1_->SetBounds(gfx::Size(100, 100)); |
- surface_layer1_->SetForceRenderSurface(true); |
- surface_layer1_->SetOpacity(0.5f); |
- root_layer_->AddChild(surface_layer1_); |
- |
- surface_layer2_ = FakeContentLayer::Create(&client_); |
- surface_layer2_->SetBounds(gfx::Size(100, 100)); |
- surface_layer2_->SetForceRenderSurface(true); |
- surface_layer2_->SetOpacity(0.5f); |
- surface_layer1_->AddChild(surface_layer2_); |
- |
- replica_layer1_ = FakeContentLayer::Create(&client_); |
- surface_layer1_->SetReplicaLayer(replica_layer1_.get()); |
- |
- replica_layer2_ = FakeContentLayer::Create(&client_); |
- surface_layer2_->SetReplicaLayer(replica_layer2_.get()); |
- |
- layer_tree_host()->SetRootLayer(root_layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- Renderer* renderer = host_impl->renderer(); |
- RenderPassId surface1_render_pass_id = host_impl->active_tree() |
- ->root_layer() |
- ->children()[0] |
- ->render_surface() |
- ->GetRenderPassId(); |
- RenderPassId surface2_render_pass_id = host_impl->active_tree() |
- ->root_layer() |
- ->children()[0] |
- ->children()[0] |
- ->render_surface() |
- ->GetRenderPassId(); |
- |
- switch (host_impl->active_tree()->source_frame_number()) { |
- case 0: |
- EXPECT_TRUE( |
- renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); |
- EXPECT_TRUE( |
- renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); |
- |
- // Reduce the memory limit to only fit the root layer and one render |
- // surface. This prevents any contents drawing into surfaces |
- // from being allocated. |
- host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2)); |
- break; |
- case 1: |
- EXPECT_FALSE( |
- renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); |
- EXPECT_FALSE( |
- renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); |
- |
- EndTest(); |
- break; |
- } |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- if (layer_tree_host()->source_frame_number() < 2) |
- root_layer_->SetNeedsDisplay(); |
- } |
- |
- void AfterTest() override { |
- EXPECT_LE(2u, root_layer_->update_count()); |
- EXPECT_LE(2u, surface_layer1_->update_count()); |
- EXPECT_LE(2u, surface_layer2_->update_count()); |
- } |
- |
- FakeContentLayerClient client_; |
- scoped_refptr<FakeContentLayer> root_layer_; |
- scoped_refptr<FakeContentLayer> surface_layer1_; |
- scoped_refptr<FakeContentLayer> replica_layer1_; |
- scoped_refptr<FakeContentLayer> surface_layer2_; |
- scoped_refptr<FakeContentLayer> replica_layer2_; |
-}; |
- |
-// Surfaces don't exist with a delegated renderer. |
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( |
- LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit); |
- |
-class EvictionTestLayer : public Layer { |
- public: |
- static scoped_refptr<EvictionTestLayer> Create() { |
- return make_scoped_refptr(new EvictionTestLayer()); |
- } |
- |
- bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override; |
- bool DrawsContent() const override { return true; } |
- |
- scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; |
- void PushPropertiesTo(LayerImpl* impl) override; |
- void SetTexturePriorities(const PriorityCalculator&) override; |
- |
- bool HaveBackingTexture() const { |
- return texture_.get() ? texture_->have_backing_texture() : false; |
- } |
- |
- private: |
- EvictionTestLayer() : Layer() {} |
- ~EvictionTestLayer() override {} |
- |
- void CreateTextureIfNeeded() { |
- if (texture_) |
- return; |
- texture_ = PrioritizedResource::Create( |
- layer_tree_host()->contents_texture_manager()); |
- texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888); |
- bitmap_.allocN32Pixels(10, 10); |
- } |
- |
- scoped_ptr<PrioritizedResource> texture_; |
- SkBitmap bitmap_; |
-}; |
- |
-class EvictionTestLayerImpl : public LayerImpl { |
- public: |
- static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl, |
- int id) { |
- return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id)); |
- } |
- ~EvictionTestLayerImpl() override {} |
- |
- void AppendQuads(RenderPass* render_pass, |
- AppendQuadsData* append_quads_data) override { |
- ASSERT_TRUE(has_texture_); |
- ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources()); |
- } |
- |
- void SetHasTexture(bool has_texture) { has_texture_ = has_texture; } |
- |
- private: |
- EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id) |
- : LayerImpl(tree_impl, id), has_texture_(false) {} |
- |
- bool has_texture_; |
-}; |
- |
-void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) { |
- CreateTextureIfNeeded(); |
- if (!texture_) |
- return; |
- texture_->set_request_priority(PriorityCalculator::UIPriority(true)); |
-} |
- |
-bool EvictionTestLayer::Update(ResourceUpdateQueue* queue, |
- const OcclusionTracker<Layer>* occlusion) { |
- CreateTextureIfNeeded(); |
- if (!texture_) |
- return false; |
- |
- gfx::Rect full_rect(0, 0, 10, 10); |
- ResourceUpdate upload = ResourceUpdate::Create( |
- texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d()); |
- queue->AppendFullUpload(upload); |
- return true; |
-} |
- |
-scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl( |
- LayerTreeImpl* tree_impl) { |
- return EvictionTestLayerImpl::Create(tree_impl, layer_id_); |
-} |
- |
-void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) { |
- Layer::PushPropertiesTo(layer_impl); |
- |
- EvictionTestLayerImpl* test_layer_impl = |
- static_cast<EvictionTestLayerImpl*>(layer_impl); |
- test_layer_impl->SetHasTexture(texture_->have_backing_texture()); |
-} |
- |
-class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestEvictTextures() |
- : layer_(EvictionTestLayer::Create()), |
- impl_for_evict_textures_(0), |
- num_commits_(0) {} |
- |
- void BeginTest() override { |
- layer_tree_host()->SetRootLayer(layer_); |
- layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); |
- |
- gfx::Transform identity_matrix; |
- SetLayerPropertiesForTesting(layer_.get(), |
- 0, |
- identity_matrix, |
- gfx::Point3F(0.f, 0.f, 0.f), |
- gfx::PointF(0.f, 0.f), |
- gfx::Size(10, 20), |
- true); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void PostEvictTextures() { |
- ImplThreadTaskRunner()->PostTask( |
- FROM_HERE, |
- base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread, |
- base::Unretained(this))); |
- } |
- |
- void EvictTexturesOnImplThread() { |
- DCHECK(impl_for_evict_textures_); |
- impl_for_evict_textures_->EvictTexturesForTesting(); |
- } |
- |
- // Commit 1: Just commit and draw normally, then post an eviction at the end |
- // that will trigger a commit. |
- // Commit 2: Triggered by the eviction, let it go through and then set |
- // needsCommit. |
- // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction |
- // task, which will be handled before the commit. Don't set needsCommit, it |
- // should have been posted. A frame should not be drawn (note, |
- // didCommitAndDrawFrame may be called anyway). |
- // Commit 4: Triggered by the eviction, let it go through and then set |
- // needsCommit. |
- // Commit 5: Triggered by the setNeedsCommit, post an eviction task in |
- // Layout(), a frame should not be drawn but a commit will be posted. |
- // Commit 6: Triggered by the eviction, post an eviction task in |
- // Layout(), which will be a noop, letting the commit (which recreates the |
- // textures) go through and draw a frame, then end the test. |
- // |
- // Commits 1+2 test the eviction recovery path where eviction happens outside |
- // of the beginFrame/commit pair. |
- // Commits 3+4 test the eviction recovery path where eviction happens inside |
- // the beginFrame/commit pair. |
- // Commits 5+6 test the path where an eviction happens during the eviction |
- // recovery path. |
- void DidCommit() override { |
- switch (num_commits_) { |
- case 1: |
- EXPECT_TRUE(layer_->HaveBackingTexture()); |
- PostEvictTextures(); |
- break; |
- case 2: |
- EXPECT_TRUE(layer_->HaveBackingTexture()); |
- layer_tree_host()->SetNeedsCommit(); |
- break; |
- case 3: |
- break; |
- case 4: |
- EXPECT_TRUE(layer_->HaveBackingTexture()); |
- layer_tree_host()->SetNeedsCommit(); |
- break; |
- case 5: |
- break; |
- case 6: |
- EXPECT_TRUE(layer_->HaveBackingTexture()); |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- impl_for_evict_textures_ = impl; |
- } |
- |
- void Layout() override { |
- ++num_commits_; |
- switch (num_commits_) { |
- case 1: |
- case 2: |
- break; |
- case 3: |
- PostEvictTextures(); |
- break; |
- case 4: |
- // We couldn't check in didCommitAndDrawFrame on commit 3, |
- // so check here. |
- EXPECT_FALSE(layer_->HaveBackingTexture()); |
- break; |
- case 5: |
- PostEvictTextures(); |
- break; |
- case 6: |
- // We couldn't check in didCommitAndDrawFrame on commit 5, |
- // so check here. |
- EXPECT_FALSE(layer_->HaveBackingTexture()); |
- PostEvictTextures(); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<EvictionTestLayer> layer_; |
- LayerTreeHostImpl* impl_for_evict_textures_; |
- int num_commits_; |
-}; |
- |
-MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures); |
- |
-class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestContinuousInvalidate() |
- : num_commit_complete_(0), num_draw_layers_(0) {} |
- |
- void BeginTest() override { |
- layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); |
- layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); |
- |
- if (layer_tree_host()->settings().impl_side_painting) |
- layer_ = FakePictureLayer::Create(&client_); |
- else |
- layer_ = FakeContentLayer::Create(&client_); |
- |
- layer_->SetBounds(gfx::Size(10, 10)); |
- layer_->SetPosition(gfx::PointF(0.f, 0.f)); |
- layer_->SetIsDrawable(true); |
- layer_tree_host()->root_layer()->AddChild(layer_); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- if (num_draw_layers_ == 2) |
- return; |
- layer_->SetNeedsDisplay(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- if (num_draw_layers_ == 1) |
- num_commit_complete_++; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- num_draw_layers_++; |
- if (num_draw_layers_ == 2) |
- EndTest(); |
- } |
- |
- void AfterTest() override { |
- // Check that we didn't commit twice between first and second draw. |
- EXPECT_EQ(1, num_commit_complete_); |
- } |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> layer_; |
- int num_commit_complete_; |
- int num_draw_layers_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate); |
- |
-class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestDeferCommits() |
- : num_will_begin_impl_frame_(0), |
- num_send_begin_main_frame_(0) {} |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void WillBeginImplFrame(const BeginFrameArgs& args) override { |
- num_will_begin_impl_frame_++; |
- switch (num_will_begin_impl_frame_) { |
- case 1: |
- break; |
- case 2: |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 3: |
- PostSetDeferCommitsToMainThread(false); |
- break; |
- default: |
- // Sometimes |num_will_begin_impl_frame_| will be greater than 3 if the |
- // main thread is slow to respond. |
- break; |
- } |
- } |
- |
- void ScheduledActionSendBeginMainFrame() override { |
- num_send_begin_main_frame_++; |
- switch (num_send_begin_main_frame_) { |
- case 1: |
- PostSetDeferCommitsToMainThread(true); |
- break; |
- case 2: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void AfterTest() override { |
- EXPECT_GE(num_will_begin_impl_frame_, 3); |
- EXPECT_EQ(2, num_send_begin_main_frame_); |
- } |
- |
- private: |
- int num_will_begin_impl_frame_; |
- int num_send_begin_main_frame_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); |
- |
-class LayerTreeHostWithProxy : public LayerTreeHost { |
- public: |
- LayerTreeHostWithProxy(FakeLayerTreeHostClient* client, |
- const LayerTreeSettings& settings, |
- scoped_ptr<FakeProxy> proxy) |
- : LayerTreeHost(client, NULL, NULL, NULL, settings) { |
- proxy->SetLayerTreeHost(this); |
- client->SetLayerTreeHost(this); |
- InitializeForTesting(proxy.Pass()); |
- } |
-}; |
- |
-TEST(LayerTreeHostTest, LimitPartialUpdates) { |
- // When partial updates are not allowed, max updates should be 0. |
- { |
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); |
- |
- scoped_ptr<FakeProxy> proxy(new FakeProxy); |
- proxy->GetRendererCapabilities().allow_partial_texture_updates = false; |
- proxy->SetMaxPartialTextureUpdates(5); |
- |
- LayerTreeSettings settings; |
- settings.impl_side_painting = false; |
- settings.max_partial_texture_updates = 10; |
- |
- LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); |
- |
- EXPECT_EQ(0u, host.MaxPartialTextureUpdates()); |
- } |
- |
- // When partial updates are allowed, |
- // max updates should be limited by the proxy. |
- { |
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); |
- |
- scoped_ptr<FakeProxy> proxy(new FakeProxy); |
- proxy->GetRendererCapabilities().allow_partial_texture_updates = true; |
- proxy->SetMaxPartialTextureUpdates(5); |
- |
- LayerTreeSettings settings; |
- settings.impl_side_painting = false; |
- settings.max_partial_texture_updates = 10; |
- |
- LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); |
- |
- EXPECT_EQ(5u, host.MaxPartialTextureUpdates()); |
- } |
- |
- // When partial updates are allowed, |
- // max updates should also be limited by the settings. |
- { |
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); |
- |
- scoped_ptr<FakeProxy> proxy(new FakeProxy); |
- proxy->GetRendererCapabilities().allow_partial_texture_updates = true; |
- proxy->SetMaxPartialTextureUpdates(20); |
- |
- LayerTreeSettings settings; |
- settings.impl_side_painting = false; |
- settings.max_partial_texture_updates = 10; |
- |
- LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); |
- |
- EXPECT_EQ(10u, host.MaxPartialTextureUpdates()); |
- } |
-} |
- |
-TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { |
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); |
- |
- LayerTreeSettings settings; |
- settings.max_partial_texture_updates = 4; |
- settings.single_thread_proxy_scheduler = false; |
- settings.impl_side_painting = false; |
- |
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager( |
- new TestSharedBitmapManager()); |
- scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( |
- &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, |
- base::MessageLoopProxy::current(), nullptr); |
- client.SetLayerTreeHost(host.get()); |
- host->Composite(base::TimeTicks::Now()); |
- |
- EXPECT_EQ(4u, host->settings().max_partial_texture_updates); |
-} |
- |
-TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { |
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE); |
- |
- LayerTreeSettings settings; |
- settings.max_partial_texture_updates = 4; |
- settings.single_thread_proxy_scheduler = false; |
- settings.impl_side_painting = false; |
- |
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager( |
- new TestSharedBitmapManager()); |
- scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( |
- &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, |
- base::MessageLoopProxy::current(), nullptr); |
- client.SetLayerTreeHost(host.get()); |
- host->Composite(base::TimeTicks::Now()); |
- |
- EXPECT_EQ(4u, host->settings().max_partial_texture_updates); |
-} |
- |
-TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { |
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D); |
- |
- LayerTreeSettings settings; |
- settings.max_partial_texture_updates = 4; |
- settings.single_thread_proxy_scheduler = false; |
- settings.impl_side_painting = false; |
- |
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager( |
- new TestSharedBitmapManager()); |
- scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( |
- &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, |
- base::MessageLoopProxy::current(), nullptr); |
- client.SetLayerTreeHost(host.get()); |
- host->Composite(base::TimeTicks::Now()); |
- |
- EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); |
-} |
- |
-TEST(LayerTreeHostTest, |
- PartialUpdatesWithDelegatingRendererAndSoftwareContent) { |
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE); |
- |
- LayerTreeSettings settings; |
- settings.max_partial_texture_updates = 4; |
- settings.single_thread_proxy_scheduler = false; |
- settings.impl_side_painting = false; |
- |
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager( |
- new TestSharedBitmapManager()); |
- scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( |
- &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, |
- base::MessageLoopProxy::current(), nullptr); |
- client.SetLayerTreeHost(host.get()); |
- host->Composite(base::TimeTicks::Now()); |
- |
- EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); |
-} |
- |
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere. |
-class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted() |
- : root_layer_(FakeContentLayer::Create(&client_)), |
- child_layer1_(FakeContentLayer::Create(&client_)), |
- child_layer2_(FakeContentLayer::Create(&client_)), |
- num_commits_(0) {} |
- |
- void BeginTest() override { |
- layer_tree_host()->SetViewportSize(gfx::Size(100, 100)); |
- root_layer_->SetBounds(gfx::Size(100, 100)); |
- child_layer1_->SetBounds(gfx::Size(100, 100)); |
- child_layer2_->SetBounds(gfx::Size(100, 100)); |
- root_layer_->AddChild(child_layer1_); |
- root_layer_->AddChild(child_layer2_); |
- layer_tree_host()->SetRootLayer(root_layer_); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, |
- bool visible) override { |
- if (visible) { |
- // One backing should remain unevicted. |
- EXPECT_EQ(100u * 100u * 4u * 1u, |
- contents_texture_manager_->MemoryUseBytes()); |
- } else { |
- EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes()); |
- } |
- |
- // Make sure that contents textures are marked as having been |
- // purged. |
- EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged()); |
- // End the test in this state. |
- EndTest(); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- ++num_commits_; |
- switch (num_commits_) { |
- case 1: |
- // All three backings should have memory. |
- EXPECT_EQ(100u * 100u * 4u * 3u, |
- contents_texture_manager_->MemoryUseBytes()); |
- |
- // Set a new policy that will kick out 1 of the 3 resources. |
- // Because a resource was evicted, a commit will be kicked off. |
- host_impl->SetMemoryPolicy( |
- ManagedMemoryPolicy(100 * 100 * 4 * 2, |
- gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, |
- 1000)); |
- break; |
- case 2: |
- // Only two backings should have memory. |
- EXPECT_EQ(100u * 100u * 4u * 2u, |
- contents_texture_manager_->MemoryUseBytes()); |
- // Become backgrounded, which will cause 1 more resource to be |
- // evicted. |
- PostSetVisibleToMainThread(false); |
- break; |
- default: |
- // No further commits should happen because this is not visible |
- // anymore. |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<FakeContentLayer> root_layer_; |
- scoped_refptr<FakeContentLayer> child_layer1_; |
- scoped_refptr<FakeContentLayer> child_layer2_; |
- int num_commits_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F( |
- LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted); |
- |
-class LayerTreeHostTestLCDChange : public LayerTreeHostTest { |
- public: |
- void SetupTree() override { |
- num_tiles_rastered_ = 0; |
- |
- scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_); |
- client_.set_fill_with_nonsolid_color(true); |
- root_layer->SetIsDrawable(true); |
- root_layer->SetBounds(gfx::Size(10, 10)); |
- root_layer->SetContentsOpaque(true); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- |
- // The expectations are based on the assumption that the default |
- // LCD settings are: |
- EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text); |
- |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 2: |
- // Change layer opacity that should trigger lcd change. |
- layer_tree_host()->root_layer()->SetOpacity(.5f); |
- break; |
- case 3: |
- // Change layer opacity that should not trigger lcd change. |
- layer_tree_host()->root_layer()->SetOpacity(1.f); |
- break; |
- case 4: |
- EndTest(); |
- break; |
- } |
- } |
- |
- void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, |
- const Tile* tile) override { |
- ++num_tiles_rastered_; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- PictureLayerImpl* root_layer = |
- static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer()); |
- bool can_use_lcd_text = |
- host_impl->active_tree()->root_layer()->can_use_lcd_text(); |
- switch (host_impl->active_tree()->source_frame_number()) { |
- case 0: |
- // The first draw. |
- EXPECT_EQ(1, num_tiles_rastered_); |
- EXPECT_TRUE(can_use_lcd_text); |
- EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); |
- break; |
- case 1: |
- // Nothing changed on the layer. |
- EXPECT_EQ(1, num_tiles_rastered_); |
- EXPECT_TRUE(can_use_lcd_text); |
- EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); |
- break; |
- case 2: |
- // LCD text was disabled; it should be re-rastered with LCD text off. |
- EXPECT_EQ(2, num_tiles_rastered_); |
- EXPECT_FALSE(can_use_lcd_text); |
- EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); |
- break; |
- case 3: |
- // LCD text was enabled, but it's sticky and stays off. |
- EXPECT_EQ(2, num_tiles_rastered_); |
- EXPECT_TRUE(can_use_lcd_text); |
- EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- int num_tiles_rastered_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange); |
- |
-// Verify that the BeginFrame notification is used to initiate rendering. |
-class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { |
- public: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->use_external_begin_frame_source = true; |
- } |
- |
- void BeginTest() override { |
- // This will trigger a SetNeedsBeginFrame which will trigger a |
- // BeginFrame. |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame, |
- DrawResult draw_result) override { |
- EndTest(); |
- return DRAW_SUCCESS; |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- base::TimeTicks frame_time_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification); |
- |
-class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled |
- : public LayerTreeHostTest { |
- public: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->use_external_begin_frame_source = true; |
- settings->using_synchronous_renderer_compositor = true; |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- // The BeginFrame notification is turned off now but will get enabled |
- // once we return. End test while it's enabled. |
- ImplThreadTaskRunner()->PostTask( |
- FROM_HERE, |
- base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest, |
- base::Unretained(this))); |
- } |
- |
- void AfterTest() override {} |
-}; |
- |
-MULTI_THREAD_TEST_F( |
- LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled); |
- |
-class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { |
- protected: |
- LayerTreeHostTestAbortedCommitDoesntStall() |
- : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->use_external_begin_frame_source = true; |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidCommit() override { |
- commit_count_++; |
- if (commit_count_ == 4) { |
- // After two aborted commits, request a real commit now to make sure a |
- // real commit following an aborted commit will still complete and |
- // end the test even when the Impl thread is idle. |
- layer_tree_host()->SetNeedsCommit(); |
- } |
- } |
- |
- void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, |
- CommitEarlyOutReason reason) override { |
- commit_abort_count_++; |
- // Initiate another abortable commit. |
- host_impl->SetNeedsCommit(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- commit_complete_count_++; |
- if (commit_complete_count_ == 1) { |
- // Initiate an abortable commit after the first commit. |
- host_impl->SetNeedsCommit(); |
- } else { |
- EndTest(); |
- } |
- } |
- |
- void AfterTest() override { |
- EXPECT_EQ(commit_count_, 5); |
- EXPECT_EQ(commit_abort_count_, 3); |
- EXPECT_EQ(commit_complete_count_, 2); |
- } |
- |
- int commit_count_; |
- int commit_abort_count_; |
- int commit_complete_count_; |
-}; |
- |
-class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor |
- : public LayerTreeHostTestAbortedCommitDoesntStall { |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); |
- settings->using_synchronous_renderer_compositor = true; |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F( |
- LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor); |
- |
-class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync |
- : public LayerTreeHostTestAbortedCommitDoesntStall { |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); |
- settings->throttle_frame_production = false; |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync); |
- |
-class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation |
- : public LayerTreeHostTest { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- } |
- |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- |
- scoped_refptr<Layer> layer = PictureLayer::Create(&client_); |
- layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); |
- layer->SetBounds(gfx::Size(10, 10)); |
- layer_tree_host()->root_layer()->AddChild(layer); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient client_; |
-}; |
- |
-MULTI_THREAD_TEST_F( |
- LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation); |
- |
-class LayerTreeHostTestChangeLayerPropertiesInPaintContents |
- : public LayerTreeHostTest { |
- public: |
- class SetBoundsClient : public ContentLayerClient { |
- public: |
- SetBoundsClient() : layer_(0) {} |
- |
- void set_layer(Layer* layer) { layer_ = layer; } |
- |
- void PaintContents(SkCanvas* canvas, |
- const gfx::Rect& clip, |
- PaintingControlSetting picture_control) override { |
- layer_->SetBounds(gfx::Size(2, 2)); |
- } |
- |
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList( |
- const gfx::Rect& clip, |
- PaintingControlSetting picture_control) override { |
- NOTIMPLEMENTED(); |
- return DisplayItemList::Create(); |
- } |
- |
- bool FillsBoundsCompletely() const override { return false; } |
- |
- private: |
- Layer* layer_; |
- }; |
- |
- LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {} |
- |
- void SetupTree() override { |
- if (layer_tree_host()->settings().impl_side_painting) { |
- scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_); |
- layer_tree_host()->SetRootLayer(root_layer); |
- } else { |
- scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_); |
- layer_tree_host()->SetRootLayer(root_layer); |
- } |
- Layer* root_layer = layer_tree_host()->root_layer(); |
- root_layer->SetIsDrawable(true); |
- root_layer->SetBounds(gfx::Size(1, 1)); |
- |
- client_.set_layer(root_layer); |
- |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- void AfterTest() override {} |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- num_commits_++; |
- if (num_commits_ == 1) { |
- LayerImpl* root_layer = host_impl->active_tree()->root_layer(); |
- EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds()); |
- } else { |
- LayerImpl* root_layer = host_impl->active_tree()->root_layer(); |
- EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds()); |
- EndTest(); |
- } |
- } |
- |
- private: |
- SetBoundsClient client_; |
- int num_commits_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F( |
- LayerTreeHostTestChangeLayerPropertiesInPaintContents); |
- |
-class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { |
- public: |
- MockIOSurfaceWebGraphicsContext3D() { |
- test_capabilities_.gpu.iosurface = true; |
- test_capabilities_.gpu.texture_rectangle = true; |
- } |
- |
- GLuint createTexture() override { return 1; } |
- MOCK_METHOD1(activeTexture, void(GLenum texture)); |
- MOCK_METHOD2(bindTexture, void(GLenum target, |
- GLuint texture_id)); |
- MOCK_METHOD3(texParameteri, void(GLenum target, |
- GLenum pname, |
- GLint param)); |
- MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target, |
- GLint width, |
- GLint height, |
- GLuint ioSurfaceId, |
- GLuint plane)); |
- MOCK_METHOD4(drawElements, void(GLenum mode, |
- GLsizei count, |
- GLenum type, |
- GLintptr offset)); |
- MOCK_METHOD1(deleteTexture, void(GLenum texture)); |
- MOCK_METHOD3(produceTextureDirectCHROMIUM, |
- void(GLuint texture, GLenum target, const GLbyte* mailbox)); |
-}; |
- |
-class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { |
- protected: |
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { |
- scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned( |
- new MockIOSurfaceWebGraphicsContext3D); |
- mock_context_ = mock_context_owned.get(); |
- |
- if (delegating_renderer()) |
- return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass()); |
- else |
- return FakeOutputSurface::Create3d(mock_context_owned.Pass()); |
- } |
- |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- |
- layer_tree_host()->root_layer()->SetIsDrawable(false); |
- |
- io_surface_id_ = 9; |
- io_surface_size_ = gfx::Size(6, 7); |
- |
- scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create(); |
- io_surface_layer->SetBounds(gfx::Size(10, 10)); |
- io_surface_layer->SetIsDrawable(true); |
- io_surface_layer->SetContentsOpaque(true); |
- io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); |
- layer_tree_host()->root_layer()->AddChild(io_surface_layer); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- EXPECT_EQ(0u, host_impl->resource_provider()->num_resources()); |
- // In WillDraw, the IOSurfaceLayer sets up the io surface texture. |
- |
- EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0); |
- EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1)) |
- .Times(AtLeast(1)); |
- EXPECT_CALL(*mock_context_, |
- texParameteri( |
- GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)) |
- .Times(1); |
- EXPECT_CALL(*mock_context_, |
- texParameteri( |
- GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)) |
- .Times(1); |
- EXPECT_CALL(*mock_context_, |
- texParameteri(GL_TEXTURE_RECTANGLE_ARB, |
- GL_TEXTURE_POOL_CHROMIUM, |
- GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1); |
- EXPECT_CALL(*mock_context_, |
- texParameteri(GL_TEXTURE_RECTANGLE_ARB, |
- GL_TEXTURE_WRAP_S, |
- GL_CLAMP_TO_EDGE)).Times(1); |
- EXPECT_CALL(*mock_context_, |
- texParameteri(GL_TEXTURE_RECTANGLE_ARB, |
- GL_TEXTURE_WRAP_T, |
- GL_CLAMP_TO_EDGE)).Times(1); |
- |
- EXPECT_CALL(*mock_context_, |
- texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, |
- io_surface_size_.width(), |
- io_surface_size_.height(), |
- io_surface_id_, |
- 0)).Times(1); |
- |
- EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber()); |
- } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame, |
- DrawResult draw_result) override { |
- Mock::VerifyAndClearExpectations(&mock_context_); |
- ResourceProvider* resource_provider = host_impl->resource_provider(); |
- EXPECT_EQ(1u, resource_provider->num_resources()); |
- CHECK_EQ(1u, frame->render_passes.size()); |
- CHECK_LE(1u, frame->render_passes[0]->quad_list.size()); |
- const DrawQuad* quad = frame->render_passes[0]->quad_list.front(); |
- CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material); |
- const IOSurfaceDrawQuad* io_surface_draw_quad = |
- IOSurfaceDrawQuad::MaterialCast(quad); |
- EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size); |
- EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id); |
- EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), |
- resource_provider->TargetForTesting( |
- io_surface_draw_quad->io_surface_resource_id)); |
- |
- if (delegating_renderer()) { |
- // The io surface layer's resource should be sent to the parent. |
- EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM( |
- _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1); |
- } else { |
- // The io surface layer's texture is drawn. |
- EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1)); |
- EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _)) |
- .Times(AtLeast(1)); |
- } |
- |
- return draw_result; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- Mock::VerifyAndClearExpectations(&mock_context_); |
- |
- EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1)); |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- int io_surface_id_; |
- MockIOSurfaceWebGraphicsContext3D* mock_context_; |
- gfx::Size io_surface_size_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing); |
- |
-class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { |
- public: |
- void BeginTest() override { |
- frame_ = 0; |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- // Round 1: commit + draw |
- // Round 2: commit only (no draw/swap) |
- // Round 3: draw only (no commit) |
- |
- void DidCommit() override { |
- int commit = layer_tree_host()->source_frame_number(); |
- switch (commit) { |
- case 2: |
- // Round 2 done. |
- EXPECT_EQ(1, frame_); |
- layer_tree_host()->SetNeedsRedraw(); |
- break; |
- } |
- } |
- |
- void DidCompleteSwapBuffers() override { |
- int commit = layer_tree_host()->source_frame_number(); |
- ++frame_; |
- switch (frame_) { |
- case 1: |
- // Round 1 done. |
- EXPECT_EQ(1, commit); |
- layer_tree_host()->SetNeedsCommit(); |
- break; |
- case 2: |
- // Round 3 done. |
- EXPECT_EQ(2, commit); |
- EndTest(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- protected: |
- int frame_; |
-}; |
- |
-// Flaky on all platforms: http://crbug.com/327498 |
-TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) { |
- RunTest(true, true, true); |
-} |
- |
-TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) { |
- RunTest(true, false, true); |
-} |
- |
-class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { |
- public: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- // PictureLayer can only be used with impl side painting enabled. |
- settings->impl_side_painting = true; |
- } |
- |
- void SetupTree() override { |
- layer_ = FakePictureLayer::Create(&client_); |
- // Force commits to not be aborted so new frames get drawn, otherwise |
- // the renderer gets deferred initialized but nothing new needs drawing. |
- layer_->set_always_update_resources(true); |
- layer_tree_host()->SetRootLayer(layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { |
- did_initialize_gl_ = false; |
- did_release_gl_ = false; |
- last_source_frame_number_drawn_ = -1; // Never drawn. |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { |
- scoped_ptr<TestWebGraphicsContext3D> context3d( |
- TestWebGraphicsContext3D::Create()); |
- |
- return FakeOutputSurface::CreateDeferredGL( |
- scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice), |
- delegating_renderer()); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- ASSERT_TRUE(host_impl->RootLayer()); |
- FakePictureLayerImpl* layer_impl = |
- static_cast<FakePictureLayerImpl*>(host_impl->RootLayer()); |
- |
- // The same frame can be draw multiple times if new visible tiles are |
- // rasterized. But we want to make sure we only post DeferredInitialize |
- // and ReleaseGL once, so early out if the same frame is drawn again. |
- if (last_source_frame_number_drawn_ == |
- host_impl->active_tree()->source_frame_number()) |
- return; |
- |
- last_source_frame_number_drawn_ = |
- host_impl->active_tree()->source_frame_number(); |
- |
- if (!did_initialize_gl_) { |
- EXPECT_LE(1u, layer_impl->append_quads_count()); |
- ImplThreadTaskRunner()->PostTask( |
- FROM_HERE, |
- base::Bind( |
- &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw, |
- base::Unretained(this), |
- base::Unretained(host_impl))); |
- } else if (did_initialize_gl_ && !did_release_gl_) { |
- EXPECT_LE(2u, layer_impl->append_quads_count()); |
- ImplThreadTaskRunner()->PostTask( |
- FROM_HERE, |
- base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw, |
- base::Unretained(this), |
- base::Unretained(host_impl))); |
- } else if (did_initialize_gl_ && did_release_gl_) { |
- EXPECT_LE(3u, layer_impl->append_quads_count()); |
- EndTest(); |
- } |
- } |
- |
- void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) { |
- EXPECT_FALSE(did_initialize_gl_); |
- // SetAndInitializeContext3D calls SetNeedsCommit. |
- FakeOutputSurface* fake_output_surface = |
- static_cast<FakeOutputSurface*>(host_impl->output_surface()); |
- scoped_refptr<TestContextProvider> context_provider = |
- TestContextProvider::Create(); // Not bound to thread. |
- scoped_refptr<TestContextProvider> worker_context_provider = |
- TestContextProvider::Create(); // Not bound to thread. |
- EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d( |
- context_provider, worker_context_provider)); |
- did_initialize_gl_ = true; |
- } |
- |
- void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) { |
- EXPECT_TRUE(did_initialize_gl_); |
- EXPECT_FALSE(did_release_gl_); |
- // ReleaseGL calls SetNeedsCommit. |
- static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL(); |
- did_release_gl_ = true; |
- } |
- |
- void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { |
- ASSERT_TRUE(result); |
- DelegatedFrameData* delegated_frame_data = |
- output_surface()->last_sent_frame().delegated_frame_data.get(); |
- if (!delegated_frame_data) |
- return; |
- |
- // Return all resources immediately. |
- TransferableResourceArray resources_to_return = |
- output_surface()->resources_held_by_parent(); |
- |
- CompositorFrameAck ack; |
- for (size_t i = 0; i < resources_to_return.size(); ++i) |
- output_surface()->ReturnResource(resources_to_return[i].id, &ack); |
- host_impl->ReclaimResources(&ack); |
- } |
- |
- void AfterTest() override { |
- EXPECT_TRUE(did_initialize_gl_); |
- EXPECT_TRUE(did_release_gl_); |
- } |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<FakePictureLayer> layer_; |
- bool did_initialize_gl_; |
- bool did_release_gl_; |
- int last_source_frame_number_drawn_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize); |
- |
-class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { |
- public: |
- void SetupTree() override { |
- root_layer_ = FakePictureLayer::Create(&client_); |
- root_layer_->SetIsDrawable(true); |
- root_layer_->SetBounds(gfx::Size(50, 50)); |
- |
- parent_layer_ = FakePictureLayer::Create(&client_); |
- parent_layer_->SetIsDrawable(true); |
- parent_layer_->SetBounds(gfx::Size(50, 50)); |
- parent_layer_->SetForceRenderSurface(true); |
- |
- child_layer_ = FakePictureLayer::Create(&client_); |
- child_layer_->SetIsDrawable(true); |
- child_layer_->SetBounds(gfx::Size(50, 50)); |
- |
- root_layer_->AddChild(parent_layer_); |
- parent_layer_->AddChild(child_layer_); |
- layer_tree_host()->SetRootLayer(root_layer_); |
- |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { |
- return FakeOutputSurface::CreateDeferredGL( |
- make_scoped_ptr(new SoftwareOutputDevice), delegating_renderer()); |
- } |
- |
- void BeginTest() override { |
- PostSetNeedsCommitToMainThread(); |
- swap_count_ = 0; |
- } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) { |
- EXPECT_EQ(1u, frame_data->render_passes.size()); |
- // Has at least 3 quads for each layer. |
- RenderPass* render_pass = frame_data->render_passes[0]; |
- EXPECT_GE(render_pass->quad_list.size(), 3u); |
- } else { |
- EXPECT_EQ(2u, frame_data->render_passes.size()); |
- |
- // At least root layer quad in root render pass. |
- EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u); |
- // At least parent and child layer quads in parent render pass. |
- EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u); |
- } |
- return draw_result; |
- } |
- |
- void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- swap_count_++; |
- switch (swap_count_) { |
- case 1: { |
- gfx::Transform identity; |
- gfx::Rect empty_rect; |
- bool resourceless_software_draw = true; |
- host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect, |
- empty_rect, identity, |
- resourceless_software_draw); |
- host_impl->SetFullRootLayerDamage(); |
- host_impl->SetNeedsRedraw(); |
- break; |
- } |
- case 2: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_layer_; |
- scoped_refptr<Layer> parent_layer_; |
- scoped_refptr<Layer> child_layer_; |
- int swap_count_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw); |
- |
-class LayerTreeHostTestDeferredInitializeWithGpuRasterization |
- : public LayerTreeHostTestDeferredInitialize { |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- // PictureLayer can only be used with impl side painting enabled. |
- settings->impl_side_painting = true; |
- settings->gpu_rasterization_enabled = true; |
- settings->gpu_rasterization_forced = true; |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization); |
- |
-// Test for UI Resource management. |
-class LayerTreeHostTestUIResource : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestUIResource() : num_ui_resources_(0) {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->renderer_settings.texture_id_allocation_chunk_size = 1; |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidCommit() override { |
- int frame = layer_tree_host()->source_frame_number(); |
- switch (frame) { |
- case 1: |
- CreateResource(); |
- CreateResource(); |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 2: |
- // Usually ScopedUIResource are deleted from the manager in their |
- // destructor. Here we just want to test that a direct call to |
- // DeleteUIResource works. |
- layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 3: |
- // DeleteUIResource can be called with an invalid id. |
- layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 4: |
- CreateResource(); |
- CreateResource(); |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 5: |
- ClearResources(); |
- EndTest(); |
- break; |
- } |
- } |
- |
- void PerformTest(LayerTreeHostImpl* impl) { |
- TestWebGraphicsContext3D* context = TestContext(); |
- |
- int frame = impl->active_tree()->source_frame_number(); |
- switch (frame) { |
- case 0: |
- ASSERT_EQ(0u, context->NumTextures()); |
- break; |
- case 1: |
- // Created two textures. |
- ASSERT_EQ(2u, context->NumTextures()); |
- break; |
- case 2: |
- // One texture left after one deletion. |
- ASSERT_EQ(1u, context->NumTextures()); |
- break; |
- case 3: |
- // Resource manager state should not change when delete is called on an |
- // invalid id. |
- ASSERT_EQ(1u, context->NumTextures()); |
- break; |
- case 4: |
- // Creation after deletion: two more creates should total up to |
- // three textures. |
- ASSERT_EQ(3u, context->NumTextures()); |
- break; |
- } |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- if (!impl->settings().impl_side_painting) |
- PerformTest(impl); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- if (impl->settings().impl_side_painting) |
- PerformTest(impl); |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- // Must clear all resources before exiting. |
- void ClearResources() { |
- for (int i = 0; i < num_ui_resources_; i++) |
- ui_resources_[i] = nullptr; |
- } |
- |
- void CreateResource() { |
- ui_resources_[num_ui_resources_++] = |
- FakeScopedUIResource::Create(layer_tree_host()); |
- } |
- |
- scoped_ptr<FakeScopedUIResource> ui_resources_[5]; |
- int num_ui_resources_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource); |
- |
-class PushPropertiesCountingLayerImpl : public LayerImpl { |
- public: |
- static scoped_ptr<PushPropertiesCountingLayerImpl> Create( |
- LayerTreeImpl* tree_impl, int id) { |
- return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id)); |
- } |
- |
- ~PushPropertiesCountingLayerImpl() override {} |
- |
- void PushPropertiesTo(LayerImpl* layer) override { |
- LayerImpl::PushPropertiesTo(layer); |
- push_properties_count_++; |
- // Push state to the active tree because we can only access it from there. |
- static_cast<PushPropertiesCountingLayerImpl*>( |
- layer)->push_properties_count_ = push_properties_count_; |
- } |
- |
- scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { |
- return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); |
- } |
- |
- size_t push_properties_count() const { return push_properties_count_; } |
- void reset_push_properties_count() { push_properties_count_ = 0; } |
- |
- private: |
- size_t push_properties_count_; |
- |
- PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id) |
- : LayerImpl(tree_impl, id), |
- push_properties_count_(0) { |
- SetBounds(gfx::Size(1, 1)); |
- } |
-}; |
- |
-class PushPropertiesCountingLayer : public Layer { |
- public: |
- static scoped_refptr<PushPropertiesCountingLayer> Create() { |
- return new PushPropertiesCountingLayer(); |
- } |
- |
- void PushPropertiesTo(LayerImpl* layer) override { |
- Layer::PushPropertiesTo(layer); |
- push_properties_count_++; |
- if (persist_needs_push_properties_) |
- needs_push_properties_ = true; |
- } |
- |
- scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { |
- return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); |
- } |
- |
- void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); } |
- |
- size_t push_properties_count() const { return push_properties_count_; } |
- void reset_push_properties_count() { push_properties_count_ = 0; } |
- |
- void set_persist_needs_push_properties(bool persist) { |
- persist_needs_push_properties_ = persist; |
- } |
- |
- private: |
- PushPropertiesCountingLayer() |
- : push_properties_count_(0), persist_needs_push_properties_(false) { |
- SetBounds(gfx::Size(1, 1)); |
- } |
- ~PushPropertiesCountingLayer() override {} |
- |
- size_t push_properties_count_; |
- bool persist_needs_push_properties_; |
-}; |
- |
-class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { |
- protected: |
- void BeginTest() override { |
- num_commits_ = 0; |
- expected_push_properties_root_ = 0; |
- expected_push_properties_child_ = 0; |
- expected_push_properties_grandchild_ = 0; |
- expected_push_properties_child2_ = 0; |
- expected_push_properties_other_root_ = 0; |
- expected_push_properties_leaf_layer_ = 0; |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void SetupTree() override { |
- root_ = PushPropertiesCountingLayer::Create(); |
- root_->CreateRenderSurface(); |
- child_ = PushPropertiesCountingLayer::Create(); |
- child2_ = PushPropertiesCountingLayer::Create(); |
- grandchild_ = PushPropertiesCountingLayer::Create(); |
- leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create(); |
- leaf_always_pushing_layer_->set_persist_needs_push_properties(true); |
- |
- root_->AddChild(child_); |
- root_->AddChild(child2_); |
- child_->AddChild(grandchild_); |
- child2_->AddChild(leaf_always_pushing_layer_); |
- |
- other_root_ = PushPropertiesCountingLayer::Create(); |
- other_root_->CreateRenderSurface(); |
- |
- // Don't set the root layer here. |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- ++num_commits_; |
- |
- EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count()); |
- EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count()); |
- EXPECT_EQ(expected_push_properties_grandchild_, |
- grandchild_->push_properties_count()); |
- EXPECT_EQ(expected_push_properties_child2_, |
- child2_->push_properties_count()); |
- EXPECT_EQ(expected_push_properties_other_root_, |
- other_root_->push_properties_count()); |
- EXPECT_EQ(expected_push_properties_leaf_layer_, |
- leaf_always_pushing_layer_->push_properties_count()); |
- |
- // The scrollbar layer always needs to be pushed. |
- if (root_->layer_tree_host()) { |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(root_->needs_push_properties()); |
- } |
- if (child2_->layer_tree_host()) { |
- EXPECT_TRUE(child2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child2_->needs_push_properties()); |
- } |
- if (leaf_always_pushing_layer_->layer_tree_host()) { |
- EXPECT_FALSE( |
- leaf_always_pushing_layer_->descendant_needs_push_properties()); |
- EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties()); |
- } |
- |
- // child_ and grandchild_ don't persist their need to push properties. |
- if (child_->layer_tree_host()) { |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- } |
- if (grandchild_->layer_tree_host()) { |
- EXPECT_FALSE(grandchild_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild_->needs_push_properties()); |
- } |
- |
- if (other_root_->layer_tree_host()) { |
- EXPECT_FALSE(other_root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(other_root_->needs_push_properties()); |
- } |
- |
- switch (num_commits_) { |
- case 1: |
- layer_tree_host()->SetRootLayer(root_); |
- // Layers added to the tree get committed. |
- ++expected_push_properties_root_; |
- ++expected_push_properties_child_; |
- ++expected_push_properties_grandchild_; |
- ++expected_push_properties_child2_; |
- break; |
- case 2: |
- layer_tree_host()->SetNeedsCommit(); |
- // No layers need commit. |
- break; |
- case 3: |
- layer_tree_host()->SetRootLayer(other_root_); |
- // Layers added to the tree get committed. |
- ++expected_push_properties_other_root_; |
- break; |
- case 4: |
- layer_tree_host()->SetRootLayer(root_); |
- // Layers added to the tree get committed. |
- ++expected_push_properties_root_; |
- ++expected_push_properties_child_; |
- ++expected_push_properties_grandchild_; |
- ++expected_push_properties_child2_; |
- break; |
- case 5: |
- layer_tree_host()->SetNeedsCommit(); |
- // No layers need commit. |
- break; |
- case 6: |
- child_->RemoveFromParent(); |
- // No layers need commit. |
- break; |
- case 7: |
- root_->AddChild(child_); |
- // Layers added to the tree get committed. |
- ++expected_push_properties_child_; |
- ++expected_push_properties_grandchild_; |
- break; |
- case 8: |
- grandchild_->RemoveFromParent(); |
- // No layers need commit. |
- break; |
- case 9: |
- child_->AddChild(grandchild_); |
- // Layers added to the tree get committed. |
- ++expected_push_properties_grandchild_; |
- break; |
- case 10: |
- layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); |
- // No layers need commit. |
- break; |
- case 11: |
- layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f); |
- // No layers need commit. |
- break; |
- case 12: |
- child_->SetPosition(gfx::Point(1, 1)); |
- // The modified layer needs commit |
- ++expected_push_properties_child_; |
- break; |
- case 13: |
- child2_->SetPosition(gfx::Point(1, 1)); |
- // The modified layer needs commit |
- ++expected_push_properties_child2_; |
- break; |
- case 14: |
- child_->RemoveFromParent(); |
- root_->AddChild(child_); |
- // Layers added to the tree get committed. |
- ++expected_push_properties_child_; |
- ++expected_push_properties_grandchild_; |
- break; |
- case 15: |
- grandchild_->SetPosition(gfx::Point(1, 1)); |
- // The modified layer needs commit |
- ++expected_push_properties_grandchild_; |
- break; |
- case 16: |
- // SetNeedsDisplay does not always set needs commit (so call it |
- // explicitly), but is a property change. |
- child_->SetNeedsDisplay(); |
- ++expected_push_properties_child_; |
- layer_tree_host()->SetNeedsCommit(); |
- break; |
- case 17: |
- EndTest(); |
- break; |
- } |
- |
- // The leaf layer always pushes. |
- if (leaf_always_pushing_layer_->layer_tree_host()) |
- ++expected_push_properties_leaf_layer_; |
- } |
- |
- void AfterTest() override {} |
- |
- int num_commits_; |
- FakeContentLayerClient client_; |
- scoped_refptr<PushPropertiesCountingLayer> root_; |
- scoped_refptr<PushPropertiesCountingLayer> child_; |
- scoped_refptr<PushPropertiesCountingLayer> child2_; |
- scoped_refptr<PushPropertiesCountingLayer> grandchild_; |
- scoped_refptr<PushPropertiesCountingLayer> other_root_; |
- scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_; |
- size_t expected_push_properties_root_; |
- size_t expected_push_properties_child_; |
- size_t expected_push_properties_child2_; |
- size_t expected_push_properties_grandchild_; |
- size_t expected_push_properties_other_root_; |
- size_t expected_push_properties_leaf_layer_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties); |
- |
-class LayerTreeHostTestImplLayersPushProperties |
- : public LayerTreeHostTestLayersPushProperties { |
- protected: |
- void BeginTest() override { |
- expected_push_properties_root_impl_ = 0; |
- expected_push_properties_child_impl_ = 0; |
- expected_push_properties_grandchild_impl_ = 0; |
- expected_push_properties_child2_impl_ = 0; |
- expected_push_properties_grandchild2_impl_ = 0; |
- LayerTreeHostTestLayersPushProperties::BeginTest(); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- // These commits are in response to the changes made in |
- // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame() |
- switch (num_commits_) { |
- case 0: |
- // Tree hasn't been setup yet don't bother to check anything. |
- return; |
- case 1: |
- // Root gets set up, Everyone is initialized. |
- ++expected_push_properties_root_impl_; |
- ++expected_push_properties_child_impl_; |
- ++expected_push_properties_grandchild_impl_; |
- ++expected_push_properties_child2_impl_; |
- ++expected_push_properties_grandchild2_impl_; |
- break; |
- case 2: |
- // Tree doesn't change but the one leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild2_impl_; |
- break; |
- case 3: |
- // Root is swapped here. |
- // Clear the expected push properties the tree will be rebuilt. |
- expected_push_properties_root_impl_ = 0; |
- expected_push_properties_child_impl_ = 0; |
- expected_push_properties_grandchild_impl_ = 0; |
- expected_push_properties_child2_impl_ = 0; |
- expected_push_properties_grandchild2_impl_ = 0; |
- |
- // Make sure the new root is pushed. |
- EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>( |
- host_impl->RootLayer())->push_properties_count()); |
- return; |
- case 4: |
- // Root is swapped back all of the layers in the tree get pushed. |
- ++expected_push_properties_root_impl_; |
- ++expected_push_properties_child_impl_; |
- ++expected_push_properties_grandchild_impl_; |
- ++expected_push_properties_child2_impl_; |
- ++expected_push_properties_grandchild2_impl_; |
- break; |
- case 5: |
- // Tree doesn't change but the one leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild2_impl_; |
- break; |
- case 6: |
- // First child is removed. Structure of the tree changes here so swap |
- // some of the values. child_impl becomes child2_impl. |
- expected_push_properties_child_impl_ = |
- expected_push_properties_child2_impl_; |
- expected_push_properties_child2_impl_ = 0; |
- // grandchild_impl becomes grandchild2_impl. |
- expected_push_properties_grandchild_impl_ = |
- expected_push_properties_grandchild2_impl_; |
- expected_push_properties_grandchild2_impl_ = 0; |
- |
- // grandchild_impl is now the leaf that always pushes. It is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- case 7: |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- |
- // Child is added back. New layers are initialized. |
- ++expected_push_properties_grandchild2_impl_; |
- ++expected_push_properties_child2_impl_; |
- break; |
- case 8: |
- // Leaf is removed. |
- expected_push_properties_grandchild2_impl_ = 0; |
- |
- // Always pushing. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- case 9: |
- // Leaf is added back |
- ++expected_push_properties_grandchild2_impl_; |
- |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- case 10: |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- case 11: |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- case 12: |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- |
- // This child position was changed. |
- ++expected_push_properties_child2_impl_; |
- break; |
- case 13: |
- // The position of this child was changed. |
- ++expected_push_properties_child_impl_; |
- |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- case 14: |
- // Second child is removed from tree. Don't discard counts because |
- // they are added back before commit. |
- |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- |
- // Second child added back. |
- ++expected_push_properties_child2_impl_; |
- ++expected_push_properties_grandchild2_impl_; |
- |
- break; |
- case 15: |
- // The position of this child was changed. |
- ++expected_push_properties_grandchild2_impl_; |
- |
- // The leaf that always pushes is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- case 16: |
- // Second child is invalidated with SetNeedsDisplay |
- ++expected_push_properties_child2_impl_; |
- |
- // The leaf that always pushed is pushed. |
- ++expected_push_properties_grandchild_impl_; |
- break; |
- } |
- |
- PushPropertiesCountingLayerImpl* root_impl_ = NULL; |
- PushPropertiesCountingLayerImpl* child_impl_ = NULL; |
- PushPropertiesCountingLayerImpl* child2_impl_ = NULL; |
- PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL; |
- PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL; |
- |
- // Pull the layers that we need from the tree assuming the same structure |
- // as LayerTreeHostTestLayersPushProperties |
- root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( |
- host_impl->RootLayer()); |
- |
- if (root_impl_ && root_impl_->children().size() > 0) { |
- child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( |
- root_impl_->children()[0]); |
- |
- if (child_impl_ && child_impl_->children().size() > 0) |
- grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( |
- child_impl_->children()[0]); |
- } |
- |
- if (root_impl_ && root_impl_->children().size() > 1) { |
- child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( |
- root_impl_->children()[1]); |
- |
- if (child2_impl_ && child2_impl_->children().size() > 0) |
- leaf_always_pushing_layer_impl_ = |
- static_cast<PushPropertiesCountingLayerImpl*>( |
- child2_impl_->children()[0]); |
- } |
- |
- if (root_impl_) |
- EXPECT_EQ(expected_push_properties_root_impl_, |
- root_impl_->push_properties_count()); |
- if (child_impl_) |
- EXPECT_EQ(expected_push_properties_child_impl_, |
- child_impl_->push_properties_count()); |
- if (grandchild_impl_) |
- EXPECT_EQ(expected_push_properties_grandchild_impl_, |
- grandchild_impl_->push_properties_count()); |
- if (child2_impl_) |
- EXPECT_EQ(expected_push_properties_child2_impl_, |
- child2_impl_->push_properties_count()); |
- if (leaf_always_pushing_layer_impl_) |
- EXPECT_EQ(expected_push_properties_grandchild2_impl_, |
- leaf_always_pushing_layer_impl_->push_properties_count()); |
- } |
- |
- size_t expected_push_properties_root_impl_; |
- size_t expected_push_properties_child_impl_; |
- size_t expected_push_properties_child2_impl_; |
- size_t expected_push_properties_grandchild_impl_; |
- size_t expected_push_properties_grandchild2_impl_; |
-}; |
- |
-TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) { |
- RunTestWithImplSidePainting(); |
-} |
- |
-class LayerTreeHostTestPropertyChangesDuringUpdateArePushed |
- : public LayerTreeHostTest { |
- protected: |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void SetupTree() override { |
- root_ = Layer::Create(); |
- root_->CreateRenderSurface(); |
- root_->SetBounds(gfx::Size(1, 1)); |
- |
- bool paint_scrollbar = true; |
- bool has_thumb = false; |
- scrollbar_layer_ = FakePaintedScrollbarLayer::Create( |
- paint_scrollbar, has_thumb, root_->id()); |
- |
- root_->AddChild(scrollbar_layer_); |
- |
- layer_tree_host()->SetRootLayer(root_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 0: |
- break; |
- case 1: { |
- // During update, the ignore_set_needs_commit_ bit is set to true to |
- // avoid causing a second commit to be scheduled. If a property change |
- // is made during this, however, it needs to be pushed in the upcoming |
- // commit. |
- scoped_ptr<base::AutoReset<bool>> ignore = |
- scrollbar_layer_->IgnoreSetNeedsCommit(); |
- |
- scrollbar_layer_->SetBounds(gfx::Size(30, 30)); |
- |
- EXPECT_TRUE(scrollbar_layer_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- layer_tree_host()->SetNeedsCommit(); |
- |
- scrollbar_layer_->reset_push_properties_count(); |
- EXPECT_EQ(0u, scrollbar_layer_->push_properties_count()); |
- break; |
- } |
- case 2: |
- EXPECT_EQ(1u, scrollbar_layer_->push_properties_count()); |
- EndTest(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- scoped_refptr<Layer> root_; |
- scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed); |
- |
-class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { |
- protected: |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void SetupTree() override { |
- root_ = PushPropertiesCountingLayer::Create(); |
- root_->CreateRenderSurface(); |
- child_ = PushPropertiesCountingLayer::Create(); |
- root_->AddChild(child_); |
- |
- layer_tree_host()->SetRootLayer(root_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 0: |
- break; |
- case 1: { |
- // During update, the ignore_set_needs_commit_ bit is set to true to |
- // avoid causing a second commit to be scheduled. If a property change |
- // is made during this, however, it needs to be pushed in the upcoming |
- // commit. |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_EQ(0, root_->NumDescendantsThatDrawContent()); |
- root_->reset_push_properties_count(); |
- child_->reset_push_properties_count(); |
- child_->SetDrawsContent(true); |
- EXPECT_EQ(1, root_->NumDescendantsThatDrawContent()); |
- EXPECT_EQ(0u, root_->push_properties_count()); |
- EXPECT_EQ(0u, child_->push_properties_count()); |
- EXPECT_TRUE(root_->needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- break; |
- } |
- case 2: |
- EXPECT_EQ(1u, root_->push_properties_count()); |
- EXPECT_EQ(1u, child_->push_properties_count()); |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EndTest(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- scoped_refptr<PushPropertiesCountingLayer> root_; |
- scoped_refptr<PushPropertiesCountingLayer> child_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit); |
- |
-class LayerTreeHostTestCasePushPropertiesThreeGrandChildren |
- : public LayerTreeHostTest { |
- protected: |
- void BeginTest() override { |
- expected_push_properties_root_ = 0; |
- expected_push_properties_child_ = 0; |
- expected_push_properties_grandchild1_ = 0; |
- expected_push_properties_grandchild2_ = 0; |
- expected_push_properties_grandchild3_ = 0; |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void SetupTree() override { |
- root_ = PushPropertiesCountingLayer::Create(); |
- root_->CreateRenderSurface(); |
- child_ = PushPropertiesCountingLayer::Create(); |
- grandchild1_ = PushPropertiesCountingLayer::Create(); |
- grandchild2_ = PushPropertiesCountingLayer::Create(); |
- grandchild3_ = PushPropertiesCountingLayer::Create(); |
- |
- root_->AddChild(child_); |
- child_->AddChild(grandchild1_); |
- child_->AddChild(grandchild2_); |
- child_->AddChild(grandchild3_); |
- |
- // Don't set the root layer here. |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient client_; |
- scoped_refptr<PushPropertiesCountingLayer> root_; |
- scoped_refptr<PushPropertiesCountingLayer> child_; |
- scoped_refptr<PushPropertiesCountingLayer> grandchild1_; |
- scoped_refptr<PushPropertiesCountingLayer> grandchild2_; |
- scoped_refptr<PushPropertiesCountingLayer> grandchild3_; |
- size_t expected_push_properties_root_; |
- size_t expected_push_properties_child_; |
- size_t expected_push_properties_grandchild1_; |
- size_t expected_push_properties_grandchild2_; |
- size_t expected_push_properties_grandchild3_; |
-}; |
- |
-class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush |
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { |
- protected: |
- void DidCommitAndDrawFrame() override { |
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; |
- switch (last_source_frame_number) { |
- case 0: |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- layer_tree_host()->SetRootLayer(root_); |
- |
- EXPECT_TRUE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- break; |
- case 1: |
- EndTest(); |
- break; |
- } |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush); |
- |
-class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion |
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { |
- protected: |
- void DidCommitAndDrawFrame() override { |
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; |
- switch (last_source_frame_number) { |
- case 0: |
- layer_tree_host()->SetRootLayer(root_); |
- break; |
- case 1: |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- grandchild1_->RemoveFromParent(); |
- grandchild1_->SetPosition(gfx::Point(1, 1)); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- child_->AddChild(grandchild1_); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- grandchild2_->SetPosition(gfx::Point(1, 1)); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- // grandchild2_ will still need a push properties. |
- grandchild1_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- |
- // grandchild3_ does not need a push properties, so recursing should |
- // no longer be needed. |
- grandchild2_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EndTest(); |
- break; |
- } |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion); |
- |
-class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence |
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { |
- protected: |
- void DidCommitAndDrawFrame() override { |
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; |
- switch (last_source_frame_number) { |
- case 0: |
- layer_tree_host()->SetRootLayer(root_); |
- grandchild1_->set_persist_needs_push_properties(true); |
- grandchild2_->set_persist_needs_push_properties(true); |
- break; |
- case 1: |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- // grandchild2_ will still need a push properties. |
- grandchild1_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- |
- // grandchild3_ does not need a push properties, so recursing should |
- // no longer be needed. |
- grandchild2_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EndTest(); |
- break; |
- } |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F( |
- LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence); |
- |
-class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree |
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { |
- protected: |
- void DidCommitAndDrawFrame() override { |
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; |
- switch (last_source_frame_number) { |
- case 0: |
- layer_tree_host()->SetRootLayer(root_); |
- break; |
- case 1: |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- // Change grandchildren while their parent is not in the tree. |
- child_->RemoveFromParent(); |
- grandchild1_->SetPosition(gfx::Point(1, 1)); |
- grandchild2_->SetPosition(gfx::Point(1, 1)); |
- root_->AddChild(child_); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- grandchild1_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- |
- grandchild2_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- |
- grandchild3_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- |
- EndTest(); |
- break; |
- } |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F( |
- LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree); |
- |
-class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild |
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { |
- protected: |
- void DidCommitAndDrawFrame() override { |
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; |
- switch (last_source_frame_number) { |
- case 0: |
- layer_tree_host()->SetRootLayer(root_); |
- break; |
- case 1: |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- child_->SetPosition(gfx::Point(1, 1)); |
- grandchild1_->SetPosition(gfx::Point(1, 1)); |
- grandchild2_->SetPosition(gfx::Point(1, 1)); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- grandchild1_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- |
- grandchild2_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- |
- child_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- |
- EndTest(); |
- break; |
- } |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F( |
- LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild); |
- |
-class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent |
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { |
- protected: |
- void DidCommitAndDrawFrame() override { |
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; |
- switch (last_source_frame_number) { |
- case 0: |
- layer_tree_host()->SetRootLayer(root_); |
- break; |
- case 1: |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- EXPECT_FALSE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- grandchild1_->SetPosition(gfx::Point(1, 1)); |
- grandchild2_->SetPosition(gfx::Point(1, 1)); |
- child_->SetPosition(gfx::Point(1, 1)); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild1_->needs_push_properties()); |
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); |
- EXPECT_TRUE(grandchild2_->needs_push_properties()); |
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->needs_push_properties()); |
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); |
- |
- grandchild1_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_TRUE(child_->descendant_needs_push_properties()); |
- |
- grandchild2_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_TRUE(root_->descendant_needs_push_properties()); |
- EXPECT_TRUE(child_->needs_push_properties()); |
- EXPECT_FALSE(child_->descendant_needs_push_properties()); |
- |
- child_->RemoveFromParent(); |
- |
- EXPECT_FALSE(root_->needs_push_properties()); |
- EXPECT_FALSE(root_->descendant_needs_push_properties()); |
- |
- EndTest(); |
- break; |
- } |
- } |
-}; |
- |
-MULTI_THREAD_TEST_F( |
- LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent); |
- |
-// This test verifies that the tree activation callback is invoked correctly. |
-class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestTreeActivationCallback() |
- : num_commits_(0), callback_count_(0) {} |
- |
- void BeginTest() override { |
- EXPECT_TRUE(HasImplThread()); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- ++num_commits_; |
- switch (num_commits_) { |
- case 1: |
- EXPECT_EQ(0, callback_count_); |
- callback_count_ = 0; |
- SetCallback(true); |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 2: |
- EXPECT_EQ(1, callback_count_); |
- callback_count_ = 0; |
- SetCallback(false); |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 3: |
- EXPECT_EQ(0, callback_count_); |
- callback_count_ = 0; |
- EndTest(); |
- break; |
- default: |
- ADD_FAILURE() << num_commits_; |
- EndTest(); |
- break; |
- } |
- return LayerTreeHostTest::PrepareToDrawOnThread( |
- host_impl, frame_data, draw_result); |
- } |
- |
- void AfterTest() override { EXPECT_EQ(3, num_commits_); } |
- |
- void SetCallback(bool enable) { |
- output_surface()->SetTreeActivationCallback( |
- enable |
- ? base::Bind( |
- &LayerTreeHostTestTreeActivationCallback::ActivationCallback, |
- base::Unretained(this)) |
- : base::Closure()); |
- } |
- |
- void ActivationCallback() { ++callback_count_; } |
- |
- int num_commits_; |
- int callback_count_; |
-}; |
- |
-TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) { |
- RunTest(true, false, true); |
-} |
- |
-TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) { |
- RunTest(true, true, true); |
-} |
- |
-class LayerInvalidateCausesDraw : public LayerTreeHostTest { |
- public: |
- LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {} |
- |
- void BeginTest() override { |
- ASSERT_TRUE(!!invalidate_layer_.get()) |
- << "Derived tests must set this in SetupTree"; |
- |
- // One initial commit. |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidCommitAndDrawFrame() override { |
- // After commit, invalidate the layer. This should cause a commit. |
- if (layer_tree_host()->source_frame_number() == 1) |
- invalidate_layer_->SetNeedsDisplay(); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- num_draws_++; |
- if (impl->active_tree()->source_frame_number() == 1) |
- EndTest(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- num_commits_++; |
- } |
- |
- void AfterTest() override { |
- EXPECT_GE(2, num_commits_); |
- EXPECT_GE(2, num_draws_); |
- } |
- |
- protected: |
- scoped_refptr<Layer> invalidate_layer_; |
- |
- private: |
- int num_commits_; |
- int num_draws_; |
-}; |
- |
-// IOSurfaceLayer must support being invalidated and then passing that along |
-// to the compositor thread, even though no resources are updated in |
-// response to that invalidation. |
-class LayerTreeHostTestIOSurfaceLayerInvalidate |
- : public LayerInvalidateCausesDraw { |
- public: |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create(); |
- layer->SetBounds(gfx::Size(10, 10)); |
- uint32_t fake_io_surface_id = 7; |
- layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds()); |
- layer->SetIsDrawable(true); |
- layer_tree_host()->root_layer()->AddChild(layer); |
- |
- invalidate_layer_ = layer; |
- } |
-}; |
- |
-// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 |
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( |
- LayerTreeHostTestIOSurfaceLayerInvalidate); |
- |
-class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { |
- protected: |
- void SetupTree() override { |
- root_layer_ = Layer::Create(); |
- root_layer_->CreateRenderSurface(); |
- root_layer_->SetPosition(gfx::Point()); |
- root_layer_->SetBounds(gfx::Size(10, 10)); |
- |
- parent_layer_ = SolidColorLayer::Create(); |
- parent_layer_->SetPosition(gfx::Point()); |
- parent_layer_->SetBounds(gfx::Size(10, 10)); |
- parent_layer_->SetIsDrawable(true); |
- root_layer_->AddChild(parent_layer_); |
- |
- child_layer_ = SolidColorLayer::Create(); |
- child_layer_->SetPosition(gfx::Point()); |
- child_layer_->SetBounds(gfx::Size(10, 10)); |
- child_layer_->SetIsDrawable(true); |
- parent_layer_->AddChild(child_layer_); |
- |
- layer_tree_host()->SetRootLayer(root_layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidCommitAndDrawFrame() override { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- // The layer type used does not need to push properties every frame. |
- EXPECT_FALSE(child_layer_->needs_push_properties()); |
- |
- // Change the bounds of the child layer, but make it skipped |
- // by CalculateDrawProperties. |
- parent_layer_->SetOpacity(0.f); |
- child_layer_->SetBounds(gfx::Size(5, 5)); |
- break; |
- case 2: |
- // The bounds of the child layer were pushed to the impl side. |
- EXPECT_FALSE(child_layer_->needs_push_properties()); |
- |
- EndTest(); |
- break; |
- } |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- LayerImpl* root = impl->active_tree()->root_layer(); |
- LayerImpl* parent = root->children()[0]; |
- LayerImpl* child = parent->children()[0]; |
- |
- switch (impl->active_tree()->source_frame_number()) { |
- case 1: |
- EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString()); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- scoped_refptr<Layer> root_layer_; |
- scoped_refptr<SolidColorLayer> parent_layer_; |
- scoped_refptr<SolidColorLayer> child_layer_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer); |
- |
-class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- } |
- |
- void SetupTree() override { |
- root_layer_ = FakePictureLayer::Create(&client_); |
- root_layer_->SetBounds(gfx::Size(10, 10)); |
- |
- layer_tree_host()->SetRootLayer(root_layer_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { |
- // The viewport is empty, but we still need to update layers on the main |
- // thread. |
- layer_tree_host()->SetViewportSize(gfx::Size(0, 0)); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidCommit() override { |
- // The layer should be updated even though the viewport is empty, so we |
- // are capable of drawing it on the impl tree. |
- EXPECT_GT(root_layer_->update_count(), 0u); |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient client_; |
- scoped_refptr<FakePictureLayer> root_layer_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); |
- |
-class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestAbortEvictedTextures() |
- : num_will_begin_main_frames_(0), num_impl_commits_(0) {} |
- |
- protected: |
- void SetupTree() override { |
- scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create(); |
- root_layer->SetBounds(gfx::Size(200, 200)); |
- root_layer->SetIsDrawable(true); |
- root_layer->CreateRenderSurface(); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void WillBeginMainFrame() override { |
- num_will_begin_main_frames_++; |
- switch (num_will_begin_main_frames_) { |
- case 2: |
- // Send a redraw to the compositor thread. This will (wrongly) be |
- // ignored unless aborting resets the texture state. |
- layer_tree_host()->SetNeedsRedraw(); |
- break; |
- } |
- } |
- |
- void BeginCommitOnThread(LayerTreeHostImpl* impl) override { |
- num_impl_commits_++; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- switch (impl->SourceAnimationFrameNumber()) { |
- case 1: |
- // Prevent draws until commit. |
- impl->active_tree()->SetContentsTexturesPurged(); |
- EXPECT_FALSE(impl->CanDraw()); |
- // Trigger an abortable commit. |
- impl->SetNeedsCommit(); |
- break; |
- case 2: |
- EndTest(); |
- break; |
- } |
- } |
- |
- void AfterTest() override { |
- // Ensure that the commit was truly aborted. |
- EXPECT_EQ(2, num_will_begin_main_frames_); |
- EXPECT_EQ(1, num_impl_commits_); |
- } |
- |
- private: |
- int num_will_begin_main_frames_; |
- int num_impl_commits_; |
-}; |
- |
-// Commits can only be aborted when using the thread proxy. |
-MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures); |
- |
-class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- settings->use_zero_copy = false; |
- settings->use_one_copy = false; |
- } |
- |
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { |
- scoped_refptr<TestContextProvider> context_provider = |
- TestContextProvider::Create(); |
- context_provider->SetMaxTransferBufferUsageBytes(512 * 512); |
- if (delegating_renderer()) |
- return FakeOutputSurface::CreateDelegating3d(context_provider); |
- else |
- return FakeOutputSurface::Create3d(context_provider); |
- } |
- |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- scoped_refptr<FakePictureLayer> root_layer = |
- FakePictureLayer::Create(&client_); |
- root_layer->SetBounds(gfx::Size(1024, 1024)); |
- root_layer->SetIsDrawable(true); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { |
- TestWebGraphicsContext3D* context = TestContext(); |
- |
- // Expect that the transfer buffer memory used is equal to the |
- // MaxTransferBufferUsageBytes value set in CreateOutputSurface. |
- EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes()); |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
-}; |
- |
-// Impl-side painting is a multi-threaded compositor feature. |
-MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes); |
- |
-// Test ensuring that memory limits are sent to the prioritized resource |
-// manager. |
-class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestMemoryLimits() : num_commits_(0) {} |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void WillCommit() override { |
- // Some commits are aborted, so increment number of attempted commits here. |
- num_commits_++; |
- } |
- |
- void DidCommit() override { |
- switch (num_commits_) { |
- case 1: |
- // Verify default values. |
- EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), |
- layer_tree_host() |
- ->contents_texture_manager() |
- ->MaxMemoryLimitBytes()); |
- EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), |
- layer_tree_host() |
- ->contents_texture_manager() |
- ->ExternalPriorityCutoff()); |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 2: |
- // The values should remain the same until the commit after the policy |
- // is changed. |
- EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), |
- layer_tree_host() |
- ->contents_texture_manager() |
- ->MaxMemoryLimitBytes()); |
- EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), |
- layer_tree_host() |
- ->contents_texture_manager() |
- ->ExternalPriorityCutoff()); |
- break; |
- case 3: |
- // Verify values were correctly passed. |
- EXPECT_EQ(16u * 1024u * 1024u, |
- layer_tree_host() |
- ->contents_texture_manager() |
- ->MaxMemoryLimitBytes()); |
- EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(), |
- layer_tree_host() |
- ->contents_texture_manager() |
- ->ExternalPriorityCutoff()); |
- EndTest(); |
- break; |
- case 4: |
- // Make sure no extra commits happen. |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- switch (num_commits_) { |
- case 1: |
- break; |
- case 2: |
- // This will trigger a commit because the priority cutoff has changed. |
- impl->SetMemoryPolicy(ManagedMemoryPolicy( |
- 16u * 1024u * 1024u, |
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, |
- 1000)); |
- break; |
- case 3: |
- // This will not trigger a commit because the priority cutoff has not |
- // changed, and there is already enough memory for all allocations. |
- impl->SetMemoryPolicy(ManagedMemoryPolicy( |
- 32u * 1024u * 1024u, |
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, |
- 1000)); |
- break; |
- case 4: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- int num_commits_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits); |
- |
-} // namespace |
- |
-class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface |
- : public LayerTreeHostTest { |
- protected: |
- LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface() |
- : first_output_surface_memory_limit_(4321234), |
- second_output_surface_memory_limit_(1234321) {} |
- |
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { |
- if (!first_context_provider_.get()) { |
- first_context_provider_ = TestContextProvider::Create(); |
- } else { |
- EXPECT_FALSE(second_context_provider_.get()); |
- second_context_provider_ = TestContextProvider::Create(); |
- } |
- |
- scoped_refptr<TestContextProvider> provider(second_context_provider_.get() |
- ? second_context_provider_ |
- : first_context_provider_); |
- scoped_ptr<FakeOutputSurface> output_surface; |
- if (delegating_renderer()) |
- output_surface = FakeOutputSurface::CreateDelegating3d(provider); |
- else |
- output_surface = FakeOutputSurface::Create3d(provider); |
- output_surface->SetMemoryPolicyToSetAtBind( |
- make_scoped_ptr(new ManagedMemoryPolicy( |
- second_context_provider_.get() ? second_output_surface_memory_limit_ |
- : first_output_surface_memory_limit_, |
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, |
- ManagedMemoryPolicy::kDefaultNumResourcesLimit))); |
- return output_surface.Pass(); |
- } |
- |
- void SetupTree() override { |
- if (layer_tree_host()->settings().impl_side_painting) |
- root_ = FakePictureLayer::Create(&client_); |
- else |
- root_ = FakeContentLayer::Create(&client_); |
- root_->SetBounds(gfx::Size(20, 20)); |
- layer_tree_host()->SetRootLayer(root_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidCommitAndDrawFrame() override { |
- // Lost context sometimes takes two frames to recreate. The third frame |
- // is sometimes aborted, so wait until the fourth frame to verify that |
- // the memory has been set, and the fifth frame to end the test. |
- if (layer_tree_host()->source_frame_number() < 5) { |
- layer_tree_host()->SetNeedsCommit(); |
- } else if (layer_tree_host()->source_frame_number() == 5) { |
- EndTest(); |
- } |
- } |
- |
- void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override { |
- switch (impl->active_tree()->source_frame_number()) { |
- case 1: |
- EXPECT_EQ(first_output_surface_memory_limit_, |
- impl->memory_allocation_limit_bytes()); |
- // Lose the output surface. |
- first_context_provider_->TestContext3d()->loseContextCHROMIUM( |
- GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); |
- break; |
- case 4: |
- EXPECT_EQ(second_output_surface_memory_limit_, |
- impl->memory_allocation_limit_bytes()); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- scoped_refptr<TestContextProvider> first_context_provider_; |
- scoped_refptr<TestContextProvider> second_context_provider_; |
- size_t first_output_surface_memory_limit_; |
- size_t second_output_surface_memory_limit_; |
- FakeContentLayerClient client_; |
- scoped_refptr<Layer> root_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F( |
- LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface); |
- |
-struct TestSwapPromiseResult { |
- TestSwapPromiseResult() |
- : did_swap_called(false), |
- did_not_swap_called(false), |
- dtor_called(false), |
- reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {} |
- |
- bool did_swap_called; |
- bool did_not_swap_called; |
- bool dtor_called; |
- SwapPromise::DidNotSwapReason reason; |
- base::Lock lock; |
-}; |
- |
-class TestSwapPromise : public SwapPromise { |
- public: |
- explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {} |
- |
- ~TestSwapPromise() override { |
- base::AutoLock lock(result_->lock); |
- result_->dtor_called = true; |
- } |
- |
- void DidSwap(CompositorFrameMetadata* metadata) override { |
- base::AutoLock lock(result_->lock); |
- EXPECT_FALSE(result_->did_swap_called); |
- EXPECT_FALSE(result_->did_not_swap_called); |
- result_->did_swap_called = true; |
- } |
- |
- void DidNotSwap(DidNotSwapReason reason) override { |
- base::AutoLock lock(result_->lock); |
- EXPECT_FALSE(result_->did_swap_called); |
- EXPECT_FALSE(result_->did_not_swap_called); |
- result_->did_not_swap_called = true; |
- result_->reason = reason; |
- } |
- |
- int64 TraceId() const override { return 0; } |
- |
- private: |
- // Not owned. |
- TestSwapPromiseResult* result_; |
-}; |
- |
-class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { |
- protected: |
- LayerTreeHostTestBreakSwapPromise() |
- : commit_count_(0), commit_complete_count_(0) {} |
- |
- void WillBeginMainFrame() override { |
- ASSERT_LE(commit_count_, 2); |
- scoped_ptr<SwapPromise> swap_promise( |
- new TestSwapPromise(&swap_promise_result_[commit_count_])); |
- layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidCommit() override { |
- commit_count_++; |
- if (commit_count_ == 2) { |
- // This commit will finish. |
- layer_tree_host()->SetNeedsCommit(); |
- } |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- commit_complete_count_++; |
- if (commit_complete_count_ == 1) { |
- // This commit will be aborted because no actual update. |
- PostSetNeedsUpdateLayersToMainThread(); |
- } else { |
- EndTest(); |
- } |
- } |
- |
- void AfterTest() override { |
- // 3 commits are scheduled. 2 completes. 1 is aborted. |
- EXPECT_EQ(commit_count_, 3); |
- EXPECT_EQ(commit_complete_count_, 2); |
- |
- { |
- // The first commit completes and causes swap buffer which finishes |
- // the promise. |
- base::AutoLock lock(swap_promise_result_[0].lock); |
- EXPECT_TRUE(swap_promise_result_[0].did_swap_called); |
- EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); |
- EXPECT_TRUE(swap_promise_result_[0].dtor_called); |
- } |
- |
- { |
- // The second commit is aborted since it contains no updates. |
- base::AutoLock lock(swap_promise_result_[1].lock); |
- EXPECT_FALSE(swap_promise_result_[1].did_swap_called); |
- EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); |
- EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason); |
- EXPECT_TRUE(swap_promise_result_[1].dtor_called); |
- } |
- |
- { |
- // The last commit completes but it does not cause swap buffer because |
- // there is no damage in the frame data. |
- base::AutoLock lock(swap_promise_result_[2].lock); |
- EXPECT_FALSE(swap_promise_result_[2].did_swap_called); |
- EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); |
- EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); |
- EXPECT_TRUE(swap_promise_result_[2].dtor_called); |
- } |
- } |
- |
- int commit_count_; |
- int commit_complete_count_; |
- TestSwapPromiseResult swap_promise_result_[3]; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); |
- |
-class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest { |
- public: |
- LayerTreeHostTestKeepSwapPromise() {} |
- |
- void BeginTest() override { |
- layer_ = SolidColorLayer::Create(); |
- layer_->SetIsDrawable(true); |
- layer_->SetBounds(gfx::Size(10, 10)); |
- layer_tree_host()->SetRootLayer(layer_); |
- gfx::Size bounds(100, 100); |
- layer_tree_host()->SetViewportSize(bounds); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidCommit() override { |
- MainThreadTaskRunner()->PostTask( |
- FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame, |
- base::Unretained(this))); |
- } |
- |
- void ChangeFrame() { |
- switch (layer_tree_host()->source_frame_number()) { |
- case 1: |
- layer_->SetBounds(gfx::Size(10, 11)); |
- layer_tree_host()->QueueSwapPromise( |
- make_scoped_ptr(new TestSwapPromise(&swap_promise_result_))); |
- break; |
- case 2: |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { |
- EXPECT_TRUE(result); |
- if (host_impl->active_tree()->source_frame_number() >= 1) { |
- // The commit changes layers so it should cause a swap. |
- base::AutoLock lock(swap_promise_result_.lock); |
- EXPECT_TRUE(swap_promise_result_.did_swap_called); |
- EXPECT_FALSE(swap_promise_result_.did_not_swap_called); |
- EXPECT_TRUE(swap_promise_result_.dtor_called); |
- EndTest(); |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- scoped_refptr<Layer> layer_; |
- TestSwapPromiseResult swap_promise_result_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise); |
- |
-class LayerTreeHostTestBreakSwapPromiseForVisibility |
- : public LayerTreeHostTest { |
- protected: |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void SetVisibleFalseAndQueueSwapPromise() { |
- layer_tree_host()->SetVisible(false); |
- scoped_ptr<SwapPromise> swap_promise( |
- new TestSwapPromise(&swap_promise_result_)); |
- layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); |
- } |
- |
- void ScheduledActionWillSendBeginMainFrame() override { |
- MainThreadTaskRunner()->PostTask( |
- FROM_HERE, |
- base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility |
- ::SetVisibleFalseAndQueueSwapPromise, |
- base::Unretained(this))); |
- } |
- |
- void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, |
- CommitEarlyOutReason reason) override { |
- EndTest(); |
- } |
- |
- void AfterTest() override { |
- { |
- base::AutoLock lock(swap_promise_result_.lock); |
- EXPECT_FALSE(swap_promise_result_.did_swap_called); |
- EXPECT_TRUE(swap_promise_result_.did_not_swap_called); |
- EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); |
- EXPECT_TRUE(swap_promise_result_.dtor_called); |
- } |
- } |
- |
- TestSwapPromiseResult swap_promise_result_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility); |
- |
-class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest { |
- protected: |
- LayerTreeHostTestBreakSwapPromiseForContext() |
- : output_surface_lost_triggered_(false) { |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void LoseOutputSurfaceAndQueueSwapPromise() { |
- layer_tree_host()->DidLoseOutputSurface(); |
- scoped_ptr<SwapPromise> swap_promise( |
- new TestSwapPromise(&swap_promise_result_)); |
- layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); |
- } |
- |
- void ScheduledActionWillSendBeginMainFrame() override { |
- if (output_surface_lost_triggered_) |
- return; |
- output_surface_lost_triggered_ = true; |
- |
- MainThreadTaskRunner()->PostTask( |
- FROM_HERE, |
- base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext |
- ::LoseOutputSurfaceAndQueueSwapPromise, |
- base::Unretained(this))); |
- } |
- |
- void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, |
- CommitEarlyOutReason reason) override { |
- // This is needed so that the impl-thread state matches main-thread state. |
- host_impl->DidLoseOutputSurface(); |
- EndTest(); |
- } |
- |
- void AfterTest() override { |
- { |
- base::AutoLock lock(swap_promise_result_.lock); |
- EXPECT_FALSE(swap_promise_result_.did_swap_called); |
- EXPECT_TRUE(swap_promise_result_.did_not_swap_called); |
- EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); |
- EXPECT_TRUE(swap_promise_result_.dtor_called); |
- } |
- } |
- |
- bool output_surface_lost_triggered_; |
- TestSwapPromiseResult swap_promise_result_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F( |
- LayerTreeHostTestBreakSwapPromiseForContext); |
- |
-class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { |
- public: |
- SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, |
- LayerTreeHostImpl* layer_tree_host_impl, |
- int* set_needs_commit_count, |
- int* set_needs_redraw_count) |
- : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl), |
- set_needs_commit_count_(set_needs_commit_count) {} |
- |
- ~SimpleSwapPromiseMonitor() override {} |
- |
- void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; } |
- |
- void OnSetNeedsRedrawOnImpl() override { |
- ADD_FAILURE() << "Should not get called on main thread."; |
- } |
- |
- void OnForwardScrollUpdateToMainThreadOnImpl() override { |
- ADD_FAILURE() << "Should not get called on main thread."; |
- } |
- |
- private: |
- int* set_needs_commit_count_; |
-}; |
- |
-class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { |
- public: |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void WillBeginMainFrame() override { |
- if (TestEnded()) |
- return; |
- |
- int set_needs_commit_count = 0; |
- int set_needs_redraw_count = 0; |
- |
- { |
- scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( |
- new SimpleSwapPromiseMonitor(layer_tree_host(), |
- NULL, |
- &set_needs_commit_count, |
- &set_needs_redraw_count)); |
- layer_tree_host()->SetNeedsCommit(); |
- EXPECT_EQ(1, set_needs_commit_count); |
- EXPECT_EQ(0, set_needs_redraw_count); |
- } |
- |
- // Now the monitor is destroyed, SetNeedsCommit() is no longer being |
- // monitored. |
- layer_tree_host()->SetNeedsCommit(); |
- EXPECT_EQ(1, set_needs_commit_count); |
- EXPECT_EQ(0, set_needs_redraw_count); |
- |
- { |
- scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( |
- new SimpleSwapPromiseMonitor(layer_tree_host(), |
- NULL, |
- &set_needs_commit_count, |
- &set_needs_redraw_count)); |
- layer_tree_host()->SetNeedsUpdateLayers(); |
- EXPECT_EQ(2, set_needs_commit_count); |
- EXPECT_EQ(0, set_needs_redraw_count); |
- } |
- |
- { |
- scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( |
- new SimpleSwapPromiseMonitor(layer_tree_host(), |
- NULL, |
- &set_needs_commit_count, |
- &set_needs_redraw_count)); |
- layer_tree_host()->SetNeedsAnimate(); |
- EXPECT_EQ(3, set_needs_commit_count); |
- EXPECT_EQ(0, set_needs_redraw_count); |
- } |
- |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); |
- |
-class LayerTreeHostTestHighResRequiredAfterEvictingUIResources |
- : public LayerTreeHostTest { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- } |
- |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- host_impl->EvictAllUIResources(); |
- // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY |
- // mode. Active tree should require high-res to draw after entering this |
- // mode to ensure that high-res tiles are also required for a pending tree |
- // to be activated. |
- EXPECT_TRUE(host_impl->RequiresHighResToDraw()); |
- } |
- |
- void DidCommit() override { |
- int frame = layer_tree_host()->source_frame_number(); |
- switch (frame) { |
- case 1: |
- PostSetNeedsCommitToMainThread(); |
- break; |
- case 2: |
- ui_resource_ = nullptr; |
- EndTest(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient client_; |
- scoped_ptr<FakeScopedUIResource> ui_resource_; |
-}; |
- |
-// This test is flaky, see http://crbug.com/386199 |
-// MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources) |
- |
-class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- |
- EXPECT_FALSE(settings->gpu_rasterization_enabled); |
- EXPECT_FALSE(settings->gpu_rasterization_forced); |
- } |
- |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- |
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); |
- layer->SetBounds(gfx::Size(10, 10)); |
- layer->SetIsDrawable(true); |
- layer_tree_host()->root_layer()->AddChild(layer); |
- } |
- |
- void BeginTest() override { |
- Layer* root = layer_tree_host()->root_layer(); |
- PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); |
- RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); |
- |
- // Verify default values. |
- EXPECT_TRUE(root->IsSuitableForGpuRasterization()); |
- EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); |
- EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); |
- EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); |
- EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); |
- |
- // Setting gpu rasterization trigger does not enable gpu rasterization. |
- layer_tree_host()->SetHasGpuRasterizationTrigger(true); |
- EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); |
- EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); |
- EXPECT_FALSE(host_impl->use_gpu_rasterization()); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); |
- EXPECT_FALSE(host_impl->use_gpu_rasterization()); |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient layer_client_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); |
- |
-class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- |
- EXPECT_FALSE(settings->gpu_rasterization_enabled); |
- settings->gpu_rasterization_enabled = true; |
- } |
- |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- |
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); |
- layer->SetBounds(gfx::Size(10, 10)); |
- layer->SetIsDrawable(true); |
- layer_tree_host()->root_layer()->AddChild(layer); |
- } |
- |
- void BeginTest() override { |
- Layer* root = layer_tree_host()->root_layer(); |
- PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); |
- RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); |
- |
- // Verify default values. |
- EXPECT_TRUE(root->IsSuitableForGpuRasterization()); |
- EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); |
- EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); |
- EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); |
- EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); |
- |
- // Gpu rasterization trigger is relevant. |
- layer_tree_host()->SetHasGpuRasterizationTrigger(true); |
- EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); |
- EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); |
- |
- // Content-based veto is relevant as well. |
- recording_source->SetUnsuitableForGpuRasterizationForTesting(); |
- EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization()); |
- EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); |
- // Veto will take effect when layers are updated. |
- // The results will be verified after commit is completed below. |
- // Since we are manually marking picture pile as unsuitable, |
- // make sure that the layer gets a chance to update. |
- layer->SetNeedsDisplay(); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); |
- EXPECT_FALSE(host_impl->use_gpu_rasterization()); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); |
- EXPECT_FALSE(host_impl->use_gpu_rasterization()); |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient layer_client_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); |
- |
-class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- ASSERT_TRUE(settings->impl_side_painting); |
- |
- EXPECT_FALSE(settings->gpu_rasterization_forced); |
- settings->gpu_rasterization_forced = true; |
- } |
- |
- void SetupTree() override { |
- LayerTreeHostTest::SetupTree(); |
- |
- scoped_refptr<FakePictureLayer> layer = |
- FakePictureLayer::Create(&layer_client_); |
- layer->SetBounds(gfx::Size(10, 10)); |
- layer->SetIsDrawable(true); |
- layer_tree_host()->root_layer()->AddChild(layer); |
- } |
- |
- void BeginTest() override { |
- Layer* root = layer_tree_host()->root_layer(); |
- PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); |
- RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); |
- |
- // Verify default values. |
- EXPECT_TRUE(root->IsSuitableForGpuRasterization()); |
- EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); |
- EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); |
- EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); |
- |
- // With gpu rasterization forced, gpu rasterization trigger is irrelevant. |
- EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); |
- layer_tree_host()->SetHasGpuRasterizationTrigger(true); |
- EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); |
- EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); |
- |
- // Content-based veto is irrelevant as well. |
- recording_source->SetUnsuitableForGpuRasterizationForTesting(); |
- EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization()); |
- EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); |
- // Veto will take effect when layers are updated. |
- // The results will be verified after commit is completed below. |
- // Since we are manually marking picture pile as unsuitable, |
- // make sure that the layer gets a chance to update. |
- layer->SetNeedsDisplay(); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization()); |
- EXPECT_TRUE(host_impl->use_gpu_rasterization()); |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); |
- EXPECT_TRUE(host_impl->use_gpu_rasterization()); |
- EndTest(); |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient layer_client_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced); |
- |
-class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestContinuousPainting() |
- : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {} |
- |
- protected: |
- enum { kExpectedNumCommits = 10 }; |
- |
- void SetupTree() override { |
- scoped_refptr<Layer> root_layer = Layer::Create(); |
- root_layer->SetBounds(bounds_); |
- root_layer->CreateRenderSurface(); |
- |
- if (layer_tree_host()->settings().impl_side_painting) { |
- picture_layer_ = FakePictureLayer::Create(&client_); |
- child_layer_ = picture_layer_.get(); |
- } else { |
- content_layer_ = ContentLayerWithUpdateTracking::Create(&client_); |
- child_layer_ = content_layer_.get(); |
- } |
- child_layer_->SetBounds(bounds_); |
- child_layer_->SetIsDrawable(true); |
- root_layer->AddChild(child_layer_); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- layer_tree_host()->SetViewportSize(bounds_); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { |
- MainThreadTaskRunner()->PostTask( |
- FROM_HERE, |
- base::Bind( |
- &LayerTreeHostTestContinuousPainting::EnableContinuousPainting, |
- base::Unretained(this))); |
- // Wait 50x longer than expected. |
- double milliseconds_per_frame = |
- 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate; |
- MainThreadTaskRunner()->PostDelayedTask( |
- FROM_HERE, |
- base::Bind( |
- &LayerTreeHostTestContinuousPainting::DisableContinuousPainting, |
- base::Unretained(this)), |
- base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits * |
- milliseconds_per_frame)); |
- } |
- |
- void BeginMainFrame(const BeginFrameArgs& args) override { |
- child_layer_->SetNeedsDisplay(); |
- } |
- |
- void AfterTest() override { |
- EXPECT_LE(kExpectedNumCommits, num_commits_); |
- EXPECT_LE(kExpectedNumCommits, num_draws_); |
- int update_count = content_layer_.get() |
- ? content_layer_->PaintContentsCount() |
- : picture_layer_->update_count(); |
- EXPECT_LE(kExpectedNumCommits, update_count); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override { |
- if (++num_draws_ == kExpectedNumCommits) |
- EndTest(); |
- } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { |
- ++num_commits_; |
- } |
- |
- private: |
- void EnableContinuousPainting() { |
- LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); |
- debug_state.continuous_painting = true; |
- layer_tree_host()->SetDebugState(debug_state); |
- } |
- |
- void DisableContinuousPainting() { |
- LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); |
- debug_state.continuous_painting = false; |
- layer_tree_host()->SetDebugState(debug_state); |
- EndTest(); |
- } |
- |
- int num_commits_; |
- int num_draws_; |
- const gfx::Size bounds_; |
- FakeContentLayerClient client_; |
- scoped_refptr<ContentLayerWithUpdateTracking> content_layer_; |
- scoped_refptr<FakePictureLayer> picture_layer_; |
- Layer* child_layer_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting); |
- |
-class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSendBeginFramesToChildren() |
- : begin_frame_sent_to_children_(false) { |
- } |
- |
- void BeginTest() override { |
- // Kick off the test with a commit. |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void SendBeginFramesToChildren(const BeginFrameArgs& args) override { |
- begin_frame_sent_to_children_ = true; |
- EndTest(); |
- } |
- |
- void DidBeginMainFrame() override { |
- // Children requested BeginFrames. |
- layer_tree_host()->SetChildrenNeedBeginFrames(true); |
- } |
- |
- void AfterTest() override { |
- // Ensure that BeginFrame message is sent to children during parent |
- // scheduler handles its BeginFrame. |
- EXPECT_TRUE(begin_frame_sent_to_children_); |
- } |
- |
- private: |
- bool begin_frame_sent_to_children_; |
-}; |
- |
-SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren); |
- |
-class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS() |
- : begin_frame_sent_to_children_(false) { |
- } |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->use_external_begin_frame_source = true; |
- } |
- |
- void BeginTest() override { |
- // Kick off the test with a commit. |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void SendBeginFramesToChildren(const BeginFrameArgs& args) override { |
- begin_frame_sent_to_children_ = true; |
- EndTest(); |
- } |
- |
- void DidBeginMainFrame() override { |
- // Children requested BeginFrames. |
- layer_tree_host()->SetChildrenNeedBeginFrames(true); |
- } |
- |
- void AfterTest() override { |
- // Ensure that BeginFrame message is sent to children during parent |
- // scheduler handles its BeginFrame. |
- EXPECT_TRUE(begin_frame_sent_to_children_); |
- } |
- |
- private: |
- bool begin_frame_sent_to_children_; |
-}; |
- |
-SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS); |
- |
-class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestActivateOnInvisible() |
- : activation_count_(0), visible_(true) {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- } |
- |
- void BeginTest() override { |
- // Kick off the test with a commit. |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { |
- // Make sure we don't activate using the notify signal from tile manager. |
- host_impl->BlockNotifyReadyToActivateForTesting(true); |
- } |
- |
- void DidCommit() override { layer_tree_host()->SetVisible(false); } |
- |
- void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, |
- bool visible) override { |
- visible_ = visible; |
- |
- // Once invisible, we can go visible again. |
- if (!visible) { |
- PostSetVisibleToMainThread(true); |
- } else { |
- EXPECT_TRUE(host_impl->RequiresHighResToDraw()); |
- EndTest(); |
- } |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- ++activation_count_; |
- EXPECT_FALSE(visible_); |
- } |
- |
- void AfterTest() override { |
- // Ensure we activated even though the signal was blocked. |
- EXPECT_EQ(1, activation_count_); |
- EXPECT_TRUE(visible_); |
- } |
- |
- private: |
- int activation_count_; |
- bool visible_; |
- |
- FakeContentLayerClient client_; |
- scoped_refptr<FakePictureLayer> picture_layer_; |
-}; |
- |
-// TODO(vmpstr): Enable with single thread impl-side painting. |
-MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible); |
- |
-// Do a synchronous composite and assert that the swap promise succeeds. |
-class LayerTreeHostTestSynchronousCompositeSwapPromise |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->single_thread_proxy_scheduler = false; |
- } |
- |
- void BeginTest() override { |
- // Successful composite. |
- scoped_ptr<SwapPromise> swap_promise0( |
- new TestSwapPromise(&swap_promise_result_[0])); |
- layer_tree_host()->QueueSwapPromise(swap_promise0.Pass()); |
- layer_tree_host()->Composite(gfx::FrameTime::Now()); |
- |
- // Fail to swap (no damage). |
- scoped_ptr<SwapPromise> swap_promise1( |
- new TestSwapPromise(&swap_promise_result_[1])); |
- layer_tree_host()->QueueSwapPromise(swap_promise1.Pass()); |
- layer_tree_host()->SetNeedsCommit(); |
- layer_tree_host()->Composite(gfx::FrameTime::Now()); |
- |
- // Fail to draw (not visible). |
- scoped_ptr<SwapPromise> swap_promise2( |
- new TestSwapPromise(&swap_promise_result_[2])); |
- layer_tree_host()->QueueSwapPromise(swap_promise2.Pass()); |
- layer_tree_host()->SetNeedsDisplayOnAllLayers(); |
- layer_tree_host()->SetVisible(false); |
- layer_tree_host()->Composite(gfx::FrameTime::Now()); |
- |
- EndTest(); |
- } |
- |
- void DidCommit() override { |
- commit_count_++; |
- ASSERT_LE(commit_count_, 3); |
- } |
- |
- void AfterTest() override { |
- EXPECT_EQ(3, commit_count_); |
- |
- // Initial swap promise should have succeded. |
- { |
- base::AutoLock lock(swap_promise_result_[0].lock); |
- EXPECT_TRUE(swap_promise_result_[0].did_swap_called); |
- EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); |
- EXPECT_TRUE(swap_promise_result_[0].dtor_called); |
- } |
- |
- // Second swap promise fails to swap. |
- { |
- base::AutoLock lock(swap_promise_result_[1].lock); |
- EXPECT_FALSE(swap_promise_result_[1].did_swap_called); |
- EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); |
- EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); |
- EXPECT_TRUE(swap_promise_result_[1].dtor_called); |
- } |
- |
- // Third swap promises also fails to swap (and draw). |
- { |
- base::AutoLock lock(swap_promise_result_[2].lock); |
- EXPECT_FALSE(swap_promise_result_[2].did_swap_called); |
- EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); |
- EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); |
- EXPECT_TRUE(swap_promise_result_[2].dtor_called); |
- } |
- } |
- |
- int commit_count_; |
- TestSwapPromiseResult swap_promise_result_[3]; |
-}; |
- |
-// Impl-side painting is not supported for synchronous compositing. |
-SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise); |
- |
-// Make sure page scale and top control deltas are applied to the client even |
-// when the LayerTreeHost doesn't have a root layer. |
-class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer() |
- : deltas_sent_to_client_(false) {} |
- |
- void BeginTest() override { |
- layer_tree_host()->SetRootLayer(nullptr); |
- info_.page_scale_delta = 3.14f; |
- info_.top_controls_delta = 2.73f; |
- |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void BeginMainFrame(const BeginFrameArgs& args) override { |
- EXPECT_EQ(nullptr, layer_tree_host()->root_layer()); |
- |
- layer_tree_host()->ApplyScrollAndScale(&info_); |
- EndTest(); |
- } |
- |
- void ApplyViewportDeltas(const gfx::Vector2dF& inner, |
- const gfx::Vector2dF& outer, |
- const gfx::Vector2dF& elastic_overscroll_delta, |
- float scale_delta, |
- float top_controls_delta) override { |
- EXPECT_EQ(info_.page_scale_delta, scale_delta); |
- EXPECT_EQ(info_.top_controls_delta, top_controls_delta); |
- deltas_sent_to_client_ = true; |
- } |
- |
- void ApplyViewportDeltas( |
- const gfx::Vector2d& scroll, |
- float scale_delta, |
- float top_controls_delta) override { |
- EXPECT_EQ(info_.page_scale_delta, scale_delta); |
- EXPECT_EQ(info_.top_controls_delta, top_controls_delta); |
- deltas_sent_to_client_ = true; |
- } |
- |
- void AfterTest() override { |
- EXPECT_TRUE(deltas_sent_to_client_); |
- } |
- |
- ScrollAndScaleSet info_; |
- bool deltas_sent_to_client_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer); |
- |
-class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { |
- protected: |
- LayerTreeHostTestCrispUpAfterPinchEnds() |
- : playback_allowed_event_(true, true) {} |
- |
- void SetupTree() override { |
- frame_ = 1; |
- posted_ = false; |
- client_.set_fill_with_nonsolid_color(true); |
- |
- scoped_refptr<Layer> root = Layer::Create(); |
- root->SetBounds(gfx::Size(500, 500)); |
- |
- scoped_refptr<Layer> pinch = Layer::Create(); |
- pinch->SetBounds(gfx::Size(500, 500)); |
- pinch->SetScrollClipLayerId(root->id()); |
- pinch->SetIsContainerForFixedPositionLayers(true); |
- root->AddChild(pinch); |
- |
- scoped_ptr<FakePicturePile> pile( |
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, |
- ImplSidePaintingSettings().default_tile_grid_size)); |
- pile->SetPlaybackAllowedEvent(&playback_allowed_event_); |
- scoped_refptr<FakePictureLayer> layer = |
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); |
- layer->SetBounds(gfx::Size(500, 500)); |
- layer->SetContentsOpaque(true); |
- // Avoid LCD text on the layer so we don't cause extra commits when we |
- // pinch. |
- layer->disable_lcd_text(); |
- pinch->AddChild(layer); |
- |
- layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch); |
- layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); |
- layer_tree_host()->SetRootLayer(root); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- // Returns the delta scale of all quads in the frame's root pass from their |
- // ideal, or 0 if they are not all the same. |
- float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) { |
- if (frame_data->has_no_damage) |
- return 0.f; |
- float frame_scale = 0.f; |
- RenderPass* root_pass = frame_data->render_passes.back(); |
- for (const auto& draw_quad : root_pass->quad_list) { |
- // Checkerboards mean an incomplete frame. |
- if (draw_quad->material != DrawQuad::TILED_CONTENT) |
- return 0.f; |
- const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad); |
- float quad_scale = |
- quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width()); |
- float transform_scale = |
- SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0)); |
- float scale = quad_scale / transform_scale; |
- if (frame_scale != 0.f && frame_scale != scale) |
- return 0.f; |
- frame_scale = scale; |
- } |
- return frame_scale; |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data); |
- switch (frame_) { |
- case 1: |
- // Drew at page scale 1 before any pinching. |
- EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); |
- EXPECT_EQ(1.f, quad_scale_delta); |
- PostNextAfterDraw(host_impl); |
- break; |
- case 2: |
- if (quad_scale_delta != 1.f) |
- break; |
- // Drew at page scale 1.5 after pinching in. |
- EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); |
- EXPECT_EQ(1.f, quad_scale_delta); |
- PostNextAfterDraw(host_impl); |
- break; |
- case 3: |
- // By pinching out, we will create a new tiling and raster it. This may |
- // cause some additional draws, though we should still be drawing with |
- // the old 1.5 tiling. |
- if (frame_data->has_no_damage) |
- break; |
- // Drew at page scale 1 with the 1.5 tiling while pinching out. |
- EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); |
- EXPECT_EQ(1.5f, quad_scale_delta); |
- // We don't PostNextAfterDraw here, instead we wait for the new tiling |
- // to finish rastering so we don't get any noise in further steps. |
- break; |
- case 4: |
- // Drew at page scale 1 with the 1.5 tiling after pinching out completed |
- // while waiting for texture uploads to complete. |
- EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); |
- // This frame will not have any damage, since it's actually the same as |
- // the last frame, and should contain no incomplete tiles. We just want |
- // to make sure we drew here at least once after the pinch ended to be |
- // sure that drawing after pinch doesn't leave us at the wrong scale |
- EXPECT_TRUE(frame_data->has_no_damage); |
- PostNextAfterDraw(host_impl); |
- break; |
- case 5: |
- if (quad_scale_delta != 1.f) |
- break; |
- // Drew at scale 1 after texture uploads are done. |
- EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); |
- EXPECT_EQ(1.f, quad_scale_delta); |
- EndTest(); |
- break; |
- } |
- return draw_result; |
- } |
- |
- void PostNextAfterDraw(LayerTreeHostImpl* host_impl) { |
- if (posted_) |
- return; |
- posted_ = true; |
- ImplThreadTaskRunner()->PostDelayedTask( |
- FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next, |
- base::Unretained(this), host_impl), |
- // Use a delay to allow raster/upload to happen in between frames. This |
- // should cause flakiness if we fail to block raster/upload when |
- // desired. |
- base::TimeDelta::FromMilliseconds(16 * 4)); |
- } |
- |
- void Next(LayerTreeHostImpl* host_impl) { |
- ++frame_; |
- posted_ = false; |
- switch (frame_) { |
- case 2: |
- // Pinch zoom in. |
- host_impl->PinchGestureBegin(); |
- host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100)); |
- host_impl->PinchGestureEnd(); |
- break; |
- case 3: |
- // Pinch zoom back to 1.f but don't end it. |
- host_impl->PinchGestureBegin(); |
- host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100)); |
- break; |
- case 4: |
- // End the pinch, but delay tile production. |
- playback_allowed_event_.Reset(); |
- host_impl->PinchGestureEnd(); |
- break; |
- case 5: |
- // Let tiles complete. |
- playback_allowed_event_.Signal(); |
- break; |
- } |
- } |
- |
- void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, |
- const Tile* tile) override { |
- if (frame_ == 3) { |
- // On frame 3, we will have a lower res tile complete for the pinch-out |
- // gesture even though it's not displayed. We wait for it here to prevent |
- // flakiness. |
- EXPECT_EQ(0.75f, tile->contents_scale()); |
- PostNextAfterDraw(host_impl); |
- } |
- // On frame_ == 4, we are preventing texture uploads from completing, |
- // so this verifies they are not completing before frame_ == 5. |
- // Flaky failures here indicate we're failing to prevent uploads from |
- // completing. |
- EXPECT_NE(4, frame_) << tile->contents_scale(); |
- } |
- |
- void AfterTest() override {} |
- |
- FakeContentLayerClient client_; |
- int frame_; |
- bool posted_; |
- base::WaitableEvent playback_allowed_event_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds); |
- |
-class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy |
- : public LayerTreeHostTestCrispUpAfterPinchEnds { |
- protected: |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->use_one_copy = true; |
- } |
- |
- scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { |
- scoped_ptr<TestWebGraphicsContext3D> context3d = |
- TestWebGraphicsContext3D::Create(); |
- context3d->set_support_image(true); |
- context3d->set_support_sync_query(true); |
-#if defined(OS_MACOSX) |
- context3d->set_support_texture_rectangle(true); |
-#endif |
- |
- if (delegating_renderer()) |
- return FakeOutputSurface::CreateDelegating3d(context3d.Pass()); |
- else |
- return FakeOutputSurface::Create3d(context3d.Pass()); |
- } |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy); |
- |
-class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest { |
- protected: |
- RasterizeWithGpuRasterizationCreatesResources() {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- settings->gpu_rasterization_forced = true; |
- } |
- |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- |
- scoped_refptr<Layer> root = Layer::Create(); |
- root->SetBounds(gfx::Size(500, 500)); |
- |
- scoped_ptr<FakePicturePile> pile( |
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, |
- ImplSidePaintingSettings().default_tile_grid_size)); |
- scoped_refptr<FakePictureLayer> layer = |
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); |
- layer->SetBounds(gfx::Size(500, 500)); |
- layer->SetContentsOpaque(true); |
- root->AddChild(layer); |
- |
- layer_tree_host()->SetRootLayer(root); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- EXPECT_NE(0u, host_impl->resource_provider()->num_resources()); |
- EndTest(); |
- return draw_result; |
- } |
- void AfterTest() override {} |
- |
- FakeContentLayerClient client_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources); |
- |
-class SynchronousGpuRasterizationRasterizesVisibleOnly |
- : public LayerTreeHostTest { |
- protected: |
- SynchronousGpuRasterizationRasterizesVisibleOnly() |
- : viewport_size_(1024, 2048) {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- settings->gpu_rasterization_enabled = true; |
- settings->gpu_rasterization_forced = true; |
- settings->threaded_gpu_rasterization_enabled = false; |
- } |
- |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- |
- scoped_ptr<FakePicturePile> pile( |
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, |
- ImplSidePaintingSettings().default_tile_grid_size)); |
- scoped_refptr<FakePictureLayer> root = |
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); |
- root->SetBounds(gfx::Size(viewport_size_.width(), 10000)); |
- root->SetContentsOpaque(true); |
- |
- layer_tree_host()->SetRootLayer(root); |
- LayerTreeHostTest::SetupTree(); |
- layer_tree_host()->SetViewportSize(viewport_size_); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- EXPECT_EQ(4u, host_impl->resource_provider()->num_resources()); |
- |
- // Verify which tiles got resources using an eviction iterator, which has to |
- // return all tiles that have resources. |
- scoped_ptr<EvictionTilePriorityQueue> eviction_queue( |
- host_impl->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); |
- int tile_count = 0; |
- for (; !eviction_queue->IsEmpty(); eviction_queue->Pop()) { |
- Tile* tile = eviction_queue->Top(); |
- // Ensure this tile is within the viewport. |
- EXPECT_TRUE(tile->content_rect().Intersects(gfx::Rect(viewport_size_))); |
- // Ensure that the tile is 1/4 of the viewport tall (plus padding). |
- EXPECT_EQ(tile->content_rect().height(), |
- (viewport_size_.height() / 4) + 2); |
- ++tile_count; |
- } |
- EXPECT_EQ(4, tile_count); |
- EndTest(); |
- return draw_result; |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- gfx::Size viewport_size_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(SynchronousGpuRasterizationRasterizesVisibleOnly); |
- |
-class ThreadedGpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest { |
- protected: |
- ThreadedGpuRasterizationRasterizesBorderTiles() |
- : viewport_size_(1024, 2048) {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- settings->gpu_rasterization_enabled = true; |
- settings->gpu_rasterization_forced = true; |
- settings->threaded_gpu_rasterization_enabled = true; |
- } |
- |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- |
- scoped_ptr<FakePicturePile> pile( |
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, |
- ImplSidePaintingSettings().default_tile_grid_size)); |
- scoped_refptr<FakePictureLayer> root = |
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); |
- root->SetBounds(gfx::Size(10000, 10000)); |
- root->SetContentsOpaque(true); |
- |
- layer_tree_host()->SetRootLayer(root); |
- LayerTreeHostTest::SetupTree(); |
- layer_tree_host()->SetViewportSize(viewport_size_); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- EXPECT_EQ(10u, host_impl->resource_provider()->num_resources()); |
- EndTest(); |
- return draw_result; |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- gfx::Size viewport_size_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(ThreadedGpuRasterizationRasterizesBorderTiles); |
- |
-class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles |
- : public LayerTreeHostTest { |
- protected: |
- LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles() |
- : playback_allowed_event_(true, true) {} |
- |
- void InitializeSettings(LayerTreeSettings* settings) override { |
- settings->impl_side_painting = true; |
- } |
- |
- void SetupTree() override { |
- step_ = 1; |
- continuous_draws_ = 0; |
- client_.set_fill_with_nonsolid_color(true); |
- |
- scoped_refptr<Layer> root = Layer::Create(); |
- root->SetBounds(gfx::Size(500, 500)); |
- |
- scoped_refptr<Layer> pinch = Layer::Create(); |
- pinch->SetBounds(gfx::Size(500, 500)); |
- pinch->SetScrollClipLayerId(root->id()); |
- pinch->SetIsContainerForFixedPositionLayers(true); |
- root->AddChild(pinch); |
- |
- scoped_ptr<FakePicturePile> pile( |
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, |
- ImplSidePaintingSettings().default_tile_grid_size)); |
- pile->SetPlaybackAllowedEvent(&playback_allowed_event_); |
- scoped_refptr<FakePictureLayer> layer = |
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); |
- layer->SetBounds(gfx::Size(500, 500)); |
- layer->SetContentsOpaque(true); |
- // Avoid LCD text on the layer so we don't cause extra commits when we |
- // pinch. |
- layer->disable_lcd_text(); |
- pinch->AddChild(layer); |
- |
- layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch); |
- layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); |
- layer_tree_host()->SetRootLayer(root); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- // Returns the delta scale of all quads in the frame's root pass from their |
- // ideal, or 0 if they are not all the same. |
- float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) { |
- if (frame_data->has_no_damage) |
- return 0.f; |
- float frame_scale = 0.f; |
- RenderPass* root_pass = frame_data->render_passes.back(); |
- for (const auto& draw_quad : root_pass->quad_list) { |
- const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad); |
- float quad_scale = |
- quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width()); |
- float transform_scale = |
- SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0)); |
- float scale = quad_scale / transform_scale; |
- if (frame_scale != 0.f && frame_scale != scale) |
- return 0.f; |
- frame_scale = scale; |
- } |
- return frame_scale; |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, |
- LayerTreeHostImpl::FrameData* frame_data, |
- DrawResult draw_result) override { |
- float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data); |
- switch (step_) { |
- case 1: |
- // Drew at scale 1 before any pinching. |
- EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); |
- EXPECT_EQ(1.f, quad_scale_delta); |
- break; |
- case 2: |
- if (quad_scale_delta != 1.f / 1.5f) |
- break; |
- // Drew at scale 1 still though the ideal is 1.5. |
- EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); |
- EXPECT_EQ(1.f / 1.5f, quad_scale_delta); |
- break; |
- case 3: |
- // Continuous draws are attempted. |
- EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); |
- if (!frame_data->has_no_damage) |
- EXPECT_EQ(1.f / 1.5f, quad_scale_delta); |
- break; |
- case 4: |
- if (quad_scale_delta != 1.f) |
- break; |
- // Drew at scale 1.5 when all the tiles completed. |
- EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); |
- EXPECT_EQ(1.f, quad_scale_delta); |
- break; |
- case 5: |
- // TODO(danakj): We get more draws before the NotifyReadyToDraw |
- // because it is asynchronous from the previous draw and happens late. |
- break; |
- case 6: |
- // NotifyReadyToDraw happened. If we were already inside a frame, we may |
- // try to draw once more. |
- break; |
- case 7: |
- NOTREACHED() << "No draws should happen once we have a complete frame."; |
- break; |
- } |
- return draw_result; |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- switch (step_) { |
- case 1: |
- // Delay tile production. |
- playback_allowed_event_.Reset(); |
- // Pinch zoom in to cause new tiles to be required. |
- host_impl->PinchGestureBegin(); |
- host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100)); |
- host_impl->PinchGestureEnd(); |
- ++step_; |
- break; |
- case 2: |
- ++step_; |
- break; |
- case 3: |
- // We should continue to try draw while there are incomplete visible |
- // tiles. |
- if (++continuous_draws_ > 5) { |
- // Allow the tiles to complete. |
- playback_allowed_event_.Signal(); |
- ++step_; |
- } |
- break; |
- case 4: |
- ++step_; |
- break; |
- case 5: |
- // Waiting for NotifyReadyToDraw. |
- break; |
- case 6: |
- // NotifyReadyToDraw happened. |
- ++step_; |
- break; |
- } |
- } |
- |
- void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override { |
- if (step_ == 5) { |
- ++step_; |
- // NotifyReadyToDraw has happened, we may draw once more, but should not |
- // get any more draws after that. End the test after a timeout to watch |
- // for any extraneous draws. |
- // TODO(brianderson): We could remove this delay and instead wait until |
- // the BeginFrameSource decides it doesn't need to send frames anymore, |
- // or test that it already doesn't here. |
- EndTestAfterDelayMs(16 * 4); |
- } |
- } |
- |
- void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, |
- const Tile* tile) override { |
- // On step_ == 2, we are preventing texture uploads from completing, |
- // so this verifies they are not completing before step_ == 3. |
- // Flaky failures here indicate we're failing to prevent uploads from |
- // completing. |
- EXPECT_NE(2, step_); |
- } |
- |
- void AfterTest() override { EXPECT_GT(continuous_draws_, 5); } |
- |
- FakeContentLayerClient client_; |
- int step_; |
- int continuous_draws_; |
- base::WaitableEvent playback_allowed_event_; |
-}; |
- |
-MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles); |
- |
-class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestOneActivatePerPrepareTiles() |
- : notify_ready_to_activate_count_(0u), |
- scheduled_prepare_tiles_count_(0) {} |
- |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- scoped_refptr<FakePictureLayer> root_layer = |
- FakePictureLayer::Create(&client_); |
- root_layer->SetBounds(gfx::Size(1500, 1500)); |
- root_layer->SetIsDrawable(true); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { |
- layer_tree_host()->SetViewportSize(gfx::Size(16, 16)); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, |
- bool success) override { |
- ASSERT_TRUE(success); |
- host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1); |
- } |
- |
- void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { |
- ++notify_ready_to_activate_count_; |
- EndTestAfterDelayMs(100); |
- } |
- |
- void ScheduledActionPrepareTiles() override { |
- ++scheduled_prepare_tiles_count_; |
- } |
- |
- void AfterTest() override { |
- // Expect at most a notification for each scheduled prepare tiles, plus one |
- // for the initial commit (which doesn't go through scheduled actions). |
- // The reason this is not an equality is because depending on timing, we |
- // might get a prepare tiles but not yet get a notification that we're |
- // ready to activate. The intent of a test is to ensure that we don't |
- // get more than one notification per prepare tiles, so this is OK. |
- EXPECT_LE(notify_ready_to_activate_count_, |
- 1u + scheduled_prepare_tiles_count_); |
- } |
- |
- protected: |
- FakeContentLayerClient client_; |
- size_t notify_ready_to_activate_count_; |
- size_t scheduled_prepare_tiles_count_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles); |
- |
-class LayerTreeHostTestFrameTimingRequestsSaveTimestamps |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestFrameTimingRequestsSaveTimestamps() |
- : check_results_on_commit_(false) {} |
- |
- void SetupTree() override { |
- scoped_refptr<FakePictureLayer> root_layer = |
- FakePictureLayer::Create(&client_); |
- root_layer->SetBounds(gfx::Size(200, 200)); |
- root_layer->SetIsDrawable(true); |
- |
- scoped_refptr<FakePictureLayer> child_layer = |
- FakePictureLayer::Create(&client_); |
- child_layer->SetBounds(gfx::Size(1500, 1500)); |
- child_layer->SetIsDrawable(true); |
- |
- std::vector<FrameTimingRequest> requests; |
- requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100))); |
- requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100))); |
- child_layer->SetFrameTimingRequests(requests); |
- |
- root_layer->AddChild(child_layer); |
- layer_tree_host()->SetRootLayer(root_layer); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { |
- if (!check_results_on_commit_) |
- return; |
- |
- // Since in reality, the events will be read by LayerTreeHost during commit, |
- // we check the requests here to ensure that they are correct at the next |
- // commit time (as opposed to checking in DrawLayers for instance). |
- // TODO(vmpstr): Change this to read things from the main thread when this |
- // information is propagated to the main thread (not yet implemented). |
- FrameTimingTracker* tracker = host_impl->frame_timing_tracker(); |
- scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set = |
- tracker->GroupCountsByRectId(); |
- EXPECT_EQ(1u, timing_set->size()); |
- auto rect_1_it = timing_set->find(1); |
- EXPECT_TRUE(rect_1_it != timing_set->end()); |
- const auto& timing_events = rect_1_it->second; |
- EXPECT_EQ(1u, timing_events.size()); |
- EXPECT_EQ(host_impl->active_tree()->source_frame_number(), |
- timing_events[0].frame_id); |
- EXPECT_GT(timing_events[0].timestamp, base::TimeTicks()); |
- |
- EndTest(); |
- } |
- |
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { |
- check_results_on_commit_ = true; |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- FakeContentLayerClient client_; |
- bool check_results_on_commit_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps); |
- |
-class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestActivationCausesPrepareTiles() |
- : scheduled_prepare_tiles_count_(0) {} |
- |
- void SetupTree() override { |
- client_.set_fill_with_nonsolid_color(true); |
- scoped_refptr<FakePictureLayer> root_layer = |
- FakePictureLayer::Create(&client_); |
- root_layer->SetBounds(gfx::Size(150, 150)); |
- root_layer->SetIsDrawable(true); |
- |
- layer_tree_host()->SetRootLayer(root_layer); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { |
- // Ensure we've already activated. |
- EXPECT_FALSE(impl->pending_tree()); |
- |
- // After activating, we either need to prepare tiles, or we've already |
- // called a scheduled prepare tiles. This is done because activation might |
- // cause us to have to memory available (old active tree is gone), so we |
- // need to ensure we will get a PrepareTiles call. |
- if (!impl->prepare_tiles_needed()) |
- EXPECT_GE(scheduled_prepare_tiles_count_, 1); |
- EndTest(); |
- } |
- |
- void ScheduledActionPrepareTiles() override { |
- ++scheduled_prepare_tiles_count_; |
- } |
- |
- void AfterTest() override {} |
- |
- protected: |
- FakeContentLayerClient client_; |
- int scheduled_prepare_tiles_count_; |
-}; |
- |
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles); |
- |
-// This tests an assertion that DidCommit and WillCommit happen in the same |
-// stack frame with no tasks that run between them. Various embedders of |
-// cc depend on this logic. ui::Compositor holds a compositor lock between |
-// these events and the inspector timeline wants begin/end CompositeLayers |
-// to be properly nested with other begin/end events. |
-class LayerTreeHostTestNoTasksBetweenWillAndDidCommit |
- : public LayerTreeHostTest { |
- public: |
- LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {} |
- |
- void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
- |
- void WillCommit() override { |
- MainThreadTaskRunner()->PostTask( |
- FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit:: |
- EndTestShouldRunAfterDidCommit, |
- base::Unretained(this))); |
- } |
- |
- void EndTestShouldRunAfterDidCommit() { |
- EXPECT_TRUE(did_commit_); |
- EndTest(); |
- } |
- |
- void DidCommit() override { |
- EXPECT_FALSE(did_commit_); |
- did_commit_ = true; |
- } |
- |
- void AfterTest() override { EXPECT_TRUE(did_commit_); } |
- |
- private: |
- bool did_commit_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit); |
- |
-// Verify that if a LayerImpl holds onto a copy request for multiple |
-// frames that it will continue to have a render surface through |
-// multiple commits, even though the Layer itself has no reason |
-// to have a render surface. |
-class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest { |
- protected: |
- void SetupTree() override { |
- scoped_refptr<Layer> root = Layer::Create(); |
- root->CreateRenderSurface(); |
- root->SetBounds(gfx::Size(10, 10)); |
- child_ = Layer::Create(); |
- child_->SetBounds(gfx::Size(20, 20)); |
- root->AddChild(child_); |
- |
- layer_tree_host()->SetRootLayer(root); |
- LayerTreeHostTest::SetupTree(); |
- } |
- |
- static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} |
- |
- void BeginTest() override { |
- child_->RequestCopyOfOutput( |
- CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback))); |
- EXPECT_TRUE(child_->HasCopyRequest()); |
- PostSetNeedsCommitToMainThread(); |
- } |
- |
- void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); } |
- |
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
- LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id()); |
- |
- switch (host_impl->sync_tree()->source_frame_number()) { |
- case 0: |
- EXPECT_TRUE(child_impl->HasCopyRequest()); |
- EXPECT_TRUE(child_impl->render_surface()); |
- break; |
- case 1: |
- if (host_impl->proxy()->CommitToActiveTree()) { |
- EXPECT_TRUE(child_impl->HasCopyRequest()); |
- EXPECT_TRUE(child_impl->render_surface()); |
- } else { |
- EXPECT_FALSE(child_impl->HasCopyRequest()); |
- EXPECT_FALSE(child_impl->render_surface()); |
- } |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
- LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id()); |
- EXPECT_TRUE(child_impl->HasCopyRequest()); |
- EXPECT_TRUE(child_impl->render_surface()); |
- |
- switch (host_impl->active_tree()->source_frame_number()) { |
- case 0: |
- // Lose output surface to prevent drawing and cause another commit. |
- host_impl->DidLoseOutputSurface(); |
- break; |
- case 1: |
- EndTest(); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- } |
- |
- void AfterTest() override {} |
- |
- private: |
- scoped_refptr<Layer> child_; |
-}; |
- |
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests); |
- |
-} // namespace cc |