Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: cc/trees/layer_tree_host_unittest.cc

Issue 671653005: SetNeedsRedraw directly when updating a visible tile. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pinchblurmerge-test: nits Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/layer_tree_host.h" 5 #include "cc/trees/layer_tree_host.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "cc/animation/timing_function.h" 11 #include "cc/animation/timing_function.h"
12 #include "cc/base/swap_promise.h" 12 #include "cc/base/swap_promise.h"
13 #include "cc/debug/frame_rate_counter.h" 13 #include "cc/debug/frame_rate_counter.h"
14 #include "cc/layers/content_layer.h" 14 #include "cc/layers/content_layer.h"
15 #include "cc/layers/content_layer_client.h" 15 #include "cc/layers/content_layer_client.h"
16 #include "cc/layers/io_surface_layer.h" 16 #include "cc/layers/io_surface_layer.h"
17 #include "cc/layers/layer_impl.h" 17 #include "cc/layers/layer_impl.h"
18 #include "cc/layers/painted_scrollbar_layer.h" 18 #include "cc/layers/painted_scrollbar_layer.h"
19 #include "cc/layers/picture_layer.h" 19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h" 20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/video_layer.h" 21 #include "cc/layers/video_layer.h"
22 #include "cc/output/begin_frame_args.h" 22 #include "cc/output/begin_frame_args.h"
23 #include "cc/output/compositor_frame_ack.h" 23 #include "cc/output/compositor_frame_ack.h"
24 #include "cc/output/copy_output_request.h" 24 #include "cc/output/copy_output_request.h"
25 #include "cc/output/copy_output_result.h" 25 #include "cc/output/copy_output_result.h"
26 #include "cc/output/output_surface.h" 26 #include "cc/output/output_surface.h"
27 #include "cc/quads/draw_quad.h" 27 #include "cc/quads/draw_quad.h"
28 #include "cc/quads/io_surface_draw_quad.h" 28 #include "cc/quads/io_surface_draw_quad.h"
29 #include "cc/quads/tile_draw_quad.h"
29 #include "cc/resources/prioritized_resource.h" 30 #include "cc/resources/prioritized_resource.h"
30 #include "cc/resources/prioritized_resource_manager.h" 31 #include "cc/resources/prioritized_resource_manager.h"
31 #include "cc/resources/resource_update_queue.h" 32 #include "cc/resources/resource_update_queue.h"
32 #include "cc/test/fake_content_layer.h" 33 #include "cc/test/fake_content_layer.h"
33 #include "cc/test/fake_content_layer_client.h" 34 #include "cc/test/fake_content_layer_client.h"
34 #include "cc/test/fake_content_layer_impl.h" 35 #include "cc/test/fake_content_layer_impl.h"
35 #include "cc/test/fake_layer_tree_host_client.h" 36 #include "cc/test/fake_layer_tree_host_client.h"
36 #include "cc/test/fake_output_surface.h" 37 #include "cc/test/fake_output_surface.h"
37 #include "cc/test/fake_painted_scrollbar_layer.h" 38 #include "cc/test/fake_painted_scrollbar_layer.h"
38 #include "cc/test/fake_picture_layer.h" 39 #include "cc/test/fake_picture_layer.h"
(...skipping 4146 matching lines...) Expand 10 before | Expand all | Expand 10 after
4185 void InitializeSettings(LayerTreeSettings* settings) override { 4186 void InitializeSettings(LayerTreeSettings* settings) override {
4186 settings->impl_side_painting = true; 4187 settings->impl_side_painting = true;
4187 settings->use_zero_copy = false; 4188 settings->use_zero_copy = false;
4188 settings->use_one_copy = false; 4189 settings->use_one_copy = false;
4189 } 4190 }
4190 4191
4191 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( 4192 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(
4192 bool fallback) override { 4193 bool fallback) override {
4193 scoped_refptr<TestContextProvider> context_provider = 4194 scoped_refptr<TestContextProvider> context_provider =
4194 TestContextProvider::Create(); 4195 TestContextProvider::Create();
4195 context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024); 4196 context_provider->SetMaxTransferBufferUsageBytes(512 * 512);
4196 if (delegating_renderer()) 4197 if (delegating_renderer())
4197 return FakeOutputSurface::CreateDelegating3d(context_provider); 4198 return FakeOutputSurface::CreateDelegating3d(context_provider);
4198 else 4199 else
4199 return FakeOutputSurface::Create3d(context_provider); 4200 return FakeOutputSurface::Create3d(context_provider);
4200 } 4201 }
4201 4202
4202 void SetupTree() override { 4203 void SetupTree() override {
4203 client_.set_fill_with_nonsolid_color(true); 4204 client_.set_fill_with_nonsolid_color(true);
4204 scoped_refptr<FakePictureLayer> root_layer = 4205 scoped_refptr<FakePictureLayer> root_layer =
4205 FakePictureLayer::Create(&client_); 4206 FakePictureLayer::Create(&client_);
4206 root_layer->SetBounds(gfx::Size(6000, 6000)); 4207 root_layer->SetBounds(gfx::Size(1024, 1024));
4207 root_layer->SetIsDrawable(true); 4208 root_layer->SetIsDrawable(true);
4208 4209
4209 layer_tree_host()->SetRootLayer(root_layer); 4210 layer_tree_host()->SetRootLayer(root_layer);
4210 LayerTreeHostTest::SetupTree(); 4211 LayerTreeHostTest::SetupTree();
4211 } 4212 }
4212 4213
4213 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 4214 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
4214 4215
4215 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { 4216 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
4216 TestWebGraphicsContext3D* context = TestContext(); 4217 TestWebGraphicsContext3D* context = TestContext();
4217 4218
4218 // Expect that the transfer buffer memory used is equal to the 4219 // Expect that the transfer buffer memory used is equal to the
4219 // MaxTransferBufferUsageBytes value set in CreateOutputSurface. 4220 // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4220 EXPECT_EQ(1024 * 1024u, context->max_used_transfer_buffer_usage_bytes()); 4221 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes());
4221 EndTest(); 4222 EndTest();
4222 } 4223 }
4223 4224
4224 void AfterTest() override {} 4225 void AfterTest() override {}
4225 4226
4226 private: 4227 private:
4227 FakeContentLayerClient client_; 4228 FakeContentLayerClient client_;
4228 }; 4229 };
4229 4230
4230 // Impl-side painting is a multi-threaded compositor feature. 4231 // Impl-side painting is a multi-threaded compositor feature.
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after
5198 5199
5199 void AfterTest() override { 5200 void AfterTest() override {
5200 EXPECT_TRUE(deltas_sent_to_client_); 5201 EXPECT_TRUE(deltas_sent_to_client_);
5201 } 5202 }
5202 5203
5203 ScrollAndScaleSet info_; 5204 ScrollAndScaleSet info_;
5204 bool deltas_sent_to_client_; 5205 bool deltas_sent_to_client_;
5205 }; 5206 };
5206 5207
5207 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer); 5208 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer);
5209
5210 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
5211 protected:
5212 void InitializeSettings(LayerTreeSettings* settings) override {
5213 settings->impl_side_painting = true;
5214 }
5215
5216 void SetupTree() override {
5217 frame_ = 1;
5218 posted_ = false;
5219 client_.set_fill_with_nonsolid_color(true);
5220
5221 scoped_refptr<Layer> root = Layer::Create();
5222 root->SetBounds(gfx::Size(500, 500));
5223
5224 scoped_refptr<Layer> pinch = Layer::Create();
5225 pinch->SetBounds(gfx::Size(500, 500));
5226 pinch->SetScrollClipLayerId(root->id());
5227 pinch->SetIsContainerForFixedPositionLayers(true);
5228 root->AddChild(pinch);
5229
5230 scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_);
5231 layer->SetBounds(gfx::Size(500, 500));
5232 layer->SetContentsOpaque(true);
5233 pinch->AddChild(layer);
5234
5235 layer_tree_host()->RegisterViewportLayers(root, pinch, pinch);
5236 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5237 layer_tree_host()->SetRootLayer(root);
5238 LayerTreeHostTest::SetupTree();
5239 }
5240
5241 // Returns the delta scale of all quads in the frame's root pass from their
5242 // ideal, or 0 if they are not all the same.
5243 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5244 if (frame_data->has_no_damage)
5245 return 0.f;
5246 float frame_scale = 0.f;
5247 RenderPass* root_pass = frame_data->render_passes.back();
5248 for (const auto& draw_quad : root_pass->quad_list) {
5249 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(&draw_quad);
5250 float quad_scale =
5251 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5252 float transform_scale =
5253 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5254 float scale = quad_scale / transform_scale;
5255 if (frame_scale != 0.f && frame_scale != scale) {
5256 return 0.f;
5257 }
5258 frame_scale = scale;
5259 }
5260 return frame_scale;
5261 }
5262
5263 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5264
5265 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5266 LayerTreeHostImpl::FrameData* frame_data,
5267 DrawResult draw_result) override {
5268 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5269 switch (frame_) {
5270 case 1:
5271 // Drew at scale 1 before any pinching.
5272 EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
5273 EXPECT_EQ(1.f, quad_scale_delta);
5274 PostNextAfterDraw(host_impl);
5275 break;
5276 case 2:
5277 if (quad_scale_delta != 1.f)
5278 break;
5279 // Drew at scale 2.2 after pinching in.
5280 EXPECT_EQ(2.2f, host_impl->active_tree()->total_page_scale_factor());
5281 EXPECT_EQ(1.f, quad_scale_delta);
5282 PostNextAfterDraw(host_impl);
5283 break;
5284 case 3:
5285 if (quad_scale_delta != 1.1f)
5286 break;
5287 // Drew at scale 1 with the 1.1 tiling while pinching out.
5288 EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
5289 EXPECT_EQ(1.1f, quad_scale_delta);
5290 PostNextAfterDraw(host_impl);
5291 break;
5292 case 4:
5293 // Drew at scale 1 with the 1.1 tiling after pinching out completed
5294 // while waiting for texture uploads to complete.
5295 EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
5296 // This frame may not have any damage, since it's actually the same as
5297 // the last frame, and should contain incomplete tiles. We just want to
5298 // make sure we drew here at least once after the pinch ended to be sure
5299 // that drawing after pinch doesn't leave us at the wrong scale forever.
5300 if (!frame_data->has_no_damage)
5301 EXPECT_EQ(1.1f, quad_scale_delta);
5302 PostNextAfterDraw(host_impl);
5303 break;
5304 case 5:
5305 if (quad_scale_delta != 1.f)
5306 break;
5307 // Drew at scale 1 after texture uploads are done.
5308 EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
5309 EXPECT_EQ(1.f, quad_scale_delta);
5310 EndTest();
5311 break;
5312 }
5313 return draw_result;
5314 }
5315
5316 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) {
5317 if (posted_)
5318 return;
5319 posted_ = true;
5320 ImplThreadTaskRunner()->PostDelayedTask(
5321 FROM_HERE,
5322 base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next,
5323 base::Unretained(this),
5324 host_impl),
5325 // Use a delay to allow raster/upload to happen in between frames. This
5326 // should cause flakiness if we fail to block raster/upload when
5327 // desired.
5328 base::TimeDelta::FromMilliseconds(16 * 6));
5329 }
5330
5331 void Next(LayerTreeHostImpl* host_impl) {
5332 ++frame_;
5333 posted_ = false;
5334 switch (frame_) {
5335 case 2:
5336 // Pinch zoom in.
5337 host_impl->PinchGestureBegin();
5338 host_impl->PinchGestureUpdate(2.2f, gfx::Point(100, 100));
5339 host_impl->PinchGestureEnd();
5340 break;
5341 case 3:
5342 // Pinch zoom back to 1.f but don't end it.
5343 host_impl->PinchGestureBegin();
5344 host_impl->PinchGestureUpdate(1.f / 2.2f, gfx::Point(100, 100));
5345 break;
5346 case 4:
5347 // End the pinch, but delay texture uploads.
5348 TestContext()->set_query_result_available_ext(0);
5349 host_impl->PinchGestureEnd();
5350 break;
5351 case 5:
5352 // Let texture uploads complete.
5353 TestContext()->set_query_result_available_ext(1);
5354 break;
5355 }
5356 }
5357
5358 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5359 const Tile* tile) override {
5360 // On frame_ == 4, we are preventing texture uploads from completing,
5361 // so this verifies they are not completing before frame_ == 5.
5362 // Flaky failures here indicate we're failing to prevent uploads from
5363 // completing.
5364 EXPECT_NE(4, frame_);
5365 }
5366
5367 void AfterTest() override {}
5368
5369 FakeContentLayerClient client_;
5370 int frame_;
5371 bool posted_;
5372 };
5373
5374 MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
5375
5376 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
5377 : public LayerTreeHostTest {
5378 protected:
5379 void InitializeSettings(LayerTreeSettings* settings) override {
5380 settings->impl_side_painting = true;
5381 }
5382
5383 void SetupTree() override {
5384 step_ = 1;
5385 continuous_draws_ = 0;
5386 client_.set_fill_with_nonsolid_color(true);
5387
5388 scoped_refptr<Layer> root = Layer::Create();
5389 root->SetBounds(gfx::Size(500, 500));
5390
5391 scoped_refptr<Layer> pinch = Layer::Create();
5392 pinch->SetBounds(gfx::Size(500, 500));
5393 pinch->SetScrollClipLayerId(root->id());
5394 pinch->SetIsContainerForFixedPositionLayers(true);
5395 root->AddChild(pinch);
5396
5397 scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_);
5398 layer->SetBounds(gfx::Size(500, 500));
5399 layer->SetContentsOpaque(true);
5400 pinch->AddChild(layer);
5401
5402 layer_tree_host()->RegisterViewportLayers(root, pinch, pinch);
5403 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
5404 layer_tree_host()->SetRootLayer(root);
5405 LayerTreeHostTest::SetupTree();
5406 }
5407
5408 // Returns the delta scale of all quads in the frame's root pass from their
5409 // ideal, or 0 if they are not all the same.
5410 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) {
5411 if (frame_data->has_no_damage)
5412 return 0.f;
5413 float frame_scale = 0.f;
5414 RenderPass* root_pass = frame_data->render_passes.back();
5415 for (const auto& draw_quad : root_pass->quad_list) {
5416 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(&draw_quad);
5417 float quad_scale =
5418 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
5419 float transform_scale =
5420 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
5421 float scale = quad_scale / transform_scale;
5422 if (frame_scale != 0.f && frame_scale != scale) {
5423 return 0.f;
5424 }
5425 frame_scale = scale;
5426 }
5427 return frame_scale;
5428 }
5429
5430 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
5431
5432 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
5433 LayerTreeHostImpl::FrameData* frame_data,
5434 DrawResult draw_result) override {
5435 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data);
5436 switch (step_) {
5437 case 1:
5438 // Drew at scale 1 before any pinching.
5439 EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
5440 EXPECT_EQ(1.f, quad_scale_delta);
5441 break;
5442 case 2:
5443 // Drew at scale 1 still though the ideal is 1.5.
5444 EXPECT_EQ(1.5f, host_impl->active_tree()->total_page_scale_factor());
5445 EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
5446 break;
5447 case 3:
5448 // Continuous draws are attempted but fail.
5449 EXPECT_TRUE(frame_data->has_no_damage);
5450 break;
5451 case 4:
5452 if (quad_scale_delta != 1.f)
5453 break;
5454 // Drew at scale 1.5 when all the tiles completed.
5455 EXPECT_EQ(1.5f, host_impl->active_tree()->total_page_scale_factor());
5456 EXPECT_EQ(1.f, quad_scale_delta);
5457
5458 // We should not continue to draw any more. End the test after a timeout
5459 // to watch for any extraneous draws.
5460 EndTestAfterDelayMs(16 * 4);
5461 ++step_;
5462 break;
5463 case 5:
5464 // No draws should happen once we have a complete frame.
5465 EXPECT_TRUE(false);
5466 break;
5467 }
5468 return draw_result;
5469 }
5470
5471 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
5472 switch (step_) {
5473 case 1:
5474 // Prevent texture uploads from completing.
5475 TestContext()->set_query_result_available_ext(0);
5476 // Pinch zoom in to cause new tiles to be required.
5477 host_impl->PinchGestureBegin();
5478 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100));
5479 host_impl->PinchGestureEnd();
5480 ++step_;
5481 break;
5482 case 2:
5483 ++step_;
5484 break;
5485 case 3:
5486 // We should continue to try draw while there are incomplete visible
5487 // tiles.
5488 if (++continuous_draws_ > 5) {
5489 // Allow the tiles to complete.
5490 TestContext()->set_query_result_available_ext(1);
5491 ++step_;
5492 }
5493 break;
5494 }
5495 }
5496
5497 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl,
5498 const Tile* tile) override {
5499 // On step_ == 2, we are preventing texture uploads from completing,
5500 // so this verifies they are not completing before step_ == 3.
5501 // Flaky failures here indicate we're failing to prevent uploads from
5502 // completing.
5503 EXPECT_NE(2, step_);
5504 }
5505
5506 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); }
5507
5508 FakeContentLayerClient client_;
5509 int step_;
5510 int continuous_draws_;
5511 };
5512
5513 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles);
5514
5208 } // namespace cc 5515 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698