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