| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "cc/base/completion_event.h" |
| 6 #include "cc/test/begin_frame_args_test.h" |
| 7 #include "cc/test/fake_content_layer_client.h" |
| 8 #include "cc/test/fake_external_begin_frame_source.h" |
| 9 #include "cc/test/fake_picture_layer.h" |
| 10 #include "cc/test/layer_tree_test.h" |
| 11 #include "cc/test/skia_common.h" |
| 12 #include "cc/test/test_compositor_frame_sink.h" |
| 13 #include "cc/trees/layer_tree_impl.h" |
| 14 |
| 15 namespace cc { |
| 16 namespace { |
| 17 |
| 18 class LayerTreeHostCheckerImagingTest : public LayerTreeTest { |
| 19 public: |
| 20 void BeginTest() override { PostSetNeedsCommitToMainThread(); } |
| 21 void AfterTest() override {} |
| 22 |
| 23 void InitializeSettings(LayerTreeSettings* settings) override { |
| 24 settings->image_decode_tasks_enabled = true; |
| 25 settings->enable_checker_imaging = true; |
| 26 } |
| 27 |
| 28 void SetupTree() override { |
| 29 // Set up a content client which creates the following tiling, x denoting |
| 30 // the image to checker: |
| 31 // |---|---|---|---| |
| 32 // | x | x | | | |
| 33 // |---|---|---|---| |
| 34 // | x | x | | | |
| 35 // |---|---|---|---| |
| 36 gfx::Size layer_size(1000, 500); |
| 37 content_layer_client_.set_bounds(layer_size); |
| 38 content_layer_client_.set_fill_with_nonsolid_color(true); |
| 39 sk_sp<SkImage> checkerable_image = |
| 40 CreateDiscardableImage(gfx::Size(450, 450)); |
| 41 content_layer_client_.add_draw_image(checkerable_image, gfx::Point(0, 0), |
| 42 PaintFlags()); |
| 43 |
| 44 layer_tree_host()->SetRootLayer( |
| 45 FakePictureLayer::Create(&content_layer_client_)); |
| 46 layer_tree_host()->root_layer()->SetBounds(layer_size); |
| 47 LayerTreeTest::SetupTree(); |
| 48 } |
| 49 |
| 50 void FlushImageDecodeTasks() { |
| 51 CompletionEvent completion_event; |
| 52 image_worker_task_runner()->PostTask( |
| 53 FROM_HERE, |
| 54 base::Bind([](CompletionEvent* event) { event->Signal(); }, |
| 55 base::Unretained(&completion_event))); |
| 56 completion_event.Wait(); |
| 57 } |
| 58 |
| 59 private: |
| 60 // Accessed only on the main thread. |
| 61 FakeContentLayerClient content_layer_client_; |
| 62 }; |
| 63 |
| 64 class LayerTreeHostCheckerImagingTestMergeWithMainFrame |
| 65 : public LayerTreeHostCheckerImagingTest { |
| 66 void BeginMainFrame(const BeginFrameArgs& args) override { |
| 67 if (layer_tree_host()->SourceFrameNumber() == 1) { |
| 68 // The first commit has happened, invalidate a tile outside the region |
| 69 // for the image to ensure that the final invalidation on the pending |
| 70 // tree is the union of this and impl-side invalidation. |
| 71 layer_tree_host()->root_layer()->SetNeedsDisplayRect( |
| 72 gfx::Rect(600, 0, 50, 500)); |
| 73 layer_tree_host()->SetNeedsCommit(); |
| 74 } |
| 75 } |
| 76 |
| 77 void ReadyToCommitOnThread(LayerTreeHostImpl* host_impl) override { |
| 78 if (num_of_commits_ == 1) { |
| 79 // Send the blocked invalidation request before notifying that we're ready |
| 80 // to commit, since the invalidation will be merged with the commit. |
| 81 host_impl->BlockImplSideInvalidationRequestsForTesting(false); |
| 82 } |
| 83 } |
| 84 |
| 85 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
| 86 switch (++num_of_commits_) { |
| 87 case 1: { |
| 88 // The first commit has happened. Run all tasks on the image worker to |
| 89 // ensure that the decode completion triggers an impl-side invalidation |
| 90 // request. |
| 91 FlushImageDecodeTasks(); |
| 92 |
| 93 // Block notifying the scheduler of this request until we get a commit. |
| 94 host_impl->BlockImplSideInvalidationRequestsForTesting(true); |
| 95 host_impl->SetNeedsCommit(); |
| 96 } break; |
| 97 case 2: { |
| 98 // Ensure that the expected tiles are invalidated on the sync tree. |
| 99 PictureLayerImpl* sync_layer_impl = static_cast<PictureLayerImpl*>( |
| 100 host_impl->sync_tree()->root_layer_for_testing()); |
| 101 PictureLayerTiling* sync_tiling = |
| 102 sync_layer_impl->picture_layer_tiling_set() |
| 103 ->FindTilingWithResolution(TileResolution::HIGH_RESOLUTION); |
| 104 |
| 105 for (int i = 0; i < 4; i++) { |
| 106 for (int j = 0; j < 2; j++) { |
| 107 Tile* tile = |
| 108 sync_tiling->TileAt(i, j) ? sync_tiling->TileAt(i, j) : nullptr; |
| 109 |
| 110 // If this is the pending tree, then only the invalidated tiles |
| 111 // exist and have a raster task. If its the active tree, then only |
| 112 // the invalidated tiles have a raster task. |
| 113 if (i < 3) { |
| 114 EXPECT_TRUE(tile->HasRasterTask()); |
| 115 } else if (host_impl->pending_tree()) { |
| 116 EXPECT_EQ(tile, nullptr); |
| 117 } else { |
| 118 EXPECT_FALSE(tile->HasRasterTask()); |
| 119 } |
| 120 } |
| 121 } |
| 122 EndTest(); |
| 123 } break; |
| 124 default: |
| 125 NOTREACHED(); |
| 126 } |
| 127 } |
| 128 |
| 129 void AfterTest() override { EXPECT_EQ(num_of_commits_, 2); } |
| 130 |
| 131 int num_of_commits_ = 0; |
| 132 }; |
| 133 |
| 134 SINGLE_AND_MULTI_THREAD_TEST_F( |
| 135 LayerTreeHostCheckerImagingTestMergeWithMainFrame); |
| 136 |
| 137 class LayerTreeHostCheckerImagingTestImplSideTree |
| 138 : public LayerTreeHostCheckerImagingTest { |
| 139 void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { |
| 140 ++num_of_impl_side_invalidations_; |
| 141 |
| 142 // The source_frame_number of the sync tree should be from the first main |
| 143 // frame, since this is an impl-side sync tree. |
| 144 EXPECT_EQ(host_impl->sync_tree()->source_frame_number(), 0); |
| 145 |
| 146 // Ensure that the expected tiles are invalidated on the sync tree. |
| 147 PictureLayerImpl* sync_layer_impl = static_cast<PictureLayerImpl*>( |
| 148 host_impl->sync_tree()->root_layer_for_testing()); |
| 149 PictureLayerTiling* sync_tiling = |
| 150 sync_layer_impl->picture_layer_tiling_set()->FindTilingWithResolution( |
| 151 TileResolution::HIGH_RESOLUTION); |
| 152 |
| 153 for (int i = 0; i < 4; i++) { |
| 154 for (int j = 0; j < 2; j++) { |
| 155 Tile* tile = |
| 156 sync_tiling->TileAt(i, j) ? sync_tiling->TileAt(i, j) : nullptr; |
| 157 |
| 158 // If this is the pending tree, then only the invalidated tiles |
| 159 // exist and have a raster task. If its the active tree, then only |
| 160 // the invalidated tiles have a raster task. |
| 161 if (i < 2) { |
| 162 EXPECT_TRUE(tile->HasRasterTask()); |
| 163 } else if (host_impl->pending_tree()) { |
| 164 EXPECT_EQ(tile, nullptr); |
| 165 } else { |
| 166 EXPECT_FALSE(tile->HasRasterTask()); |
| 167 } |
| 168 } |
| 169 } |
| 170 } |
| 171 |
| 172 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { |
| 173 num_of_commits_++; |
| 174 } |
| 175 |
| 176 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { |
| 177 num_of_activations_++; |
| 178 if (num_of_activations_ == 2) |
| 179 EndTest(); |
| 180 } |
| 181 |
| 182 void AfterTest() override { |
| 183 EXPECT_EQ(num_of_activations_, 2); |
| 184 EXPECT_EQ(num_of_commits_, 1); |
| 185 EXPECT_EQ(num_of_impl_side_invalidations_, 1); |
| 186 } |
| 187 |
| 188 int num_of_activations_ = 0; |
| 189 int num_of_commits_ = 0; |
| 190 int num_of_impl_side_invalidations_ = 0; |
| 191 }; |
| 192 |
| 193 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCheckerImagingTestImplSideTree); |
| 194 |
| 195 } // namespace |
| 196 } // namespace cc |
| OLD | NEW |