1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
9 #include "base/synchronization/lock.h"
10 #include "cc/animation/timing_function.h"
11 #include "cc/layers/content_layer.h"
12 #include "cc/layers/content_layer_client.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/layers/picture_layer.h"
15 #include "cc/layers/scrollbar_layer.h"
16 #include "cc/output/output_surface.h"
17 #include "cc/resources/prioritized_resource.h"
18 #include "cc/resources/prioritized_resource_manager.h"
19 #include "cc/resources/resource_update_queue.h"
20 #include "cc/scheduler/frame_rate_controller.h"
21 #include "cc/test/fake_content_layer.h"
22 #include "cc/test/fake_content_layer_client.h"
23 #include "cc/test/fake_layer_tree_host_client.h"
24 #include "cc/test/fake_output_surface.h"
25 #include "cc/test/fake_proxy.h"
26 #include "cc/test/fake_scrollbar_layer.h"
27 #include "cc/test/geometry_test_utils.h"
28 #include "cc/test/layer_tree_test.h"
29 #include "cc/test/occlusion_tracker_test_common.h"
30 #include "cc/trees/layer_tree_host_impl.h"
31 #include "cc/trees/layer_tree_impl.h"
32 #include "cc/trees/single_thread_proxy.h"
33 #include "cc/trees/thread_proxy.h"
34 #include "skia/ext/refptr.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
37 #include "third_party/khronos/GLES2/gl2.h"
38 #include "third_party/khronos/GLES2/gl2ext.h"
39 #include "third_party/skia/include/core/SkPicture.h"
40 #include "ui/gfx/point_conversions.h"
41 #include "ui/gfx/size_conversions.h"
42 #include "ui/gfx/vector2d_conversions.h"
47 class LayerTreeHostTest
: public LayerTreeTest
{
50 // Test interleaving of redraws and commits
51 class LayerTreeHostTestCommitingWithContinuousRedraw
52 : public LayerTreeHostTest
{
54 LayerTreeHostTestCommitingWithContinuousRedraw()
55 : num_complete_commits_(0), num_draws_(0) {}
57 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
59 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
60 num_complete_commits_
++;
61 if (num_complete_commits_
== 2)
65 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
67 PostSetNeedsCommitToMainThread();
69 PostSetNeedsRedrawToMainThread();
72 virtual void AfterTest() OVERRIDE
{}
75 int num_complete_commits_
;
79 MULTI_THREAD_TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw
);
81 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
83 class LayerTreeHostTestSetNeedsCommit1
: public LayerTreeHostTest
{
85 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
87 virtual void BeginTest() OVERRIDE
{
88 PostSetNeedsCommitToMainThread();
89 PostSetNeedsCommitToMainThread();
92 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
94 if (!impl
->active_tree()->source_frame_number())
98 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
102 virtual void AfterTest() OVERRIDE
{
103 EXPECT_GE(1, num_commits_
);
104 EXPECT_GE(1, num_draws_
);
112 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1
);
114 // A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
115 // first committed frame draws should lead to another commit.
116 class LayerTreeHostTestSetNeedsCommit2
: public LayerTreeHostTest
{
118 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
120 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
122 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
126 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
128 if (impl
->active_tree()->source_frame_number() == 0)
129 PostSetNeedsCommitToMainThread();
130 else if (impl
->active_tree()->source_frame_number() == 1)
134 virtual void AfterTest() OVERRIDE
{
135 EXPECT_EQ(2, num_commits_
);
136 EXPECT_LE(1, num_draws_
);
144 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2
);
146 // 1 setNeedsRedraw after the first commit has completed should lead to 1
148 class LayerTreeHostTestSetNeedsRedraw
: public LayerTreeHostTest
{
150 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
152 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
154 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
155 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
157 // Redraw again to verify that the second redraw doesn't commit.
158 PostSetNeedsRedrawToMainThread();
165 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
166 EXPECT_EQ(0, num_draws_
);
170 virtual void AfterTest() OVERRIDE
{
171 EXPECT_GE(2, num_draws_
);
172 EXPECT_EQ(1, num_commits_
);
180 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw
);
182 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
183 // must contain invalid_rect.
184 class LayerTreeHostTestSetNeedsRedrawRect
: public LayerTreeHostTest
{
186 LayerTreeHostTestSetNeedsRedrawRect()
189 invalid_rect_(10, 10, 20, 20),
190 root_layer_(ContentLayer::Create(&client_
)) {
193 virtual void BeginTest() OVERRIDE
{
194 root_layer_
->SetIsDrawable(true);
195 root_layer_
->SetBounds(bounds_
);
196 layer_tree_host()->SetRootLayer(root_layer_
);
197 layer_tree_host()->SetViewportSize(bounds_
);
198 PostSetNeedsCommitToMainThread();
201 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
202 LayerTreeHostImpl::FrameData
* frame_data
,
203 bool result
) OVERRIDE
{
206 gfx::RectF root_damage_rect
;
207 if (!frame_data
->render_passes
.empty())
208 root_damage_rect
= frame_data
->render_passes
.back()->damage_rect
;
211 // If this is the first frame, expect full frame damage.
212 EXPECT_RECT_EQ(root_damage_rect
, gfx::Rect(bounds_
));
214 // Check that invalid_rect_ is indeed repainted.
215 EXPECT_TRUE(root_damage_rect
.Contains(invalid_rect_
));
221 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
223 PostSetNeedsRedrawRectToMainThread(invalid_rect_
);
230 virtual void AfterTest() OVERRIDE
{
231 EXPECT_EQ(2, num_draws_
);
236 const gfx::Size bounds_
;
237 const gfx::Rect invalid_rect_
;
238 FakeContentLayerClient client_
;
239 scoped_refptr
<ContentLayer
> root_layer_
;
242 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect
);
244 class LayerTreeHostTestNoExtraCommitFromInvalidate
: public LayerTreeHostTest
{
246 LayerTreeHostTestNoExtraCommitFromInvalidate()
247 : root_layer_(ContentLayer::Create(&client_
)) {}
249 virtual void BeginTest() OVERRIDE
{
250 root_layer_
->SetAutomaticallyComputeRasterScale(false);
251 root_layer_
->SetIsDrawable(true);
252 root_layer_
->SetBounds(gfx::Size(1, 1));
253 layer_tree_host()->SetRootLayer(root_layer_
);
254 PostSetNeedsCommitToMainThread();
257 virtual void DidCommit() OVERRIDE
{
258 switch (layer_tree_host()->commit_number()) {
260 // Changing the content bounds will cause a single commit!
261 root_layer_
->SetRasterScale(4.f
);
265 EXPECT_EQ(2, layer_tree_host()->commit_number());
270 virtual void AfterTest() OVERRIDE
{}
273 FakeContentLayerClient client_
;
274 scoped_refptr
<ContentLayer
> root_layer_
;
277 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate
);
279 class LayerTreeHostTestCompositeAndReadback
: public LayerTreeHostTest
{
281 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
283 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
285 virtual void DidCommit() OVERRIDE
{
287 if (num_commits_
== 1) {
289 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
290 } else if (num_commits_
== 2) {
291 // This is inside the readback. We should get another commit after it.
292 } else if (num_commits_
== 3) {
299 virtual void AfterTest() OVERRIDE
{}
305 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback
);
307 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
308 : public LayerTreeHostTest
{
310 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
313 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
315 virtual void DidCommit() OVERRIDE
{
317 if (num_commits_
== 1) {
318 layer_tree_host()->SetNeedsCommit();
319 } else if (num_commits_
== 2) {
321 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
322 } else if (num_commits_
== 3) {
323 // This is inside the readback. We should get another commit after it.
324 } else if (num_commits_
== 4) {
331 virtual void AfterTest() OVERRIDE
{}
338 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
);
340 // If the layerTreeHost says it can't draw, Then we should not try to draw.
341 class LayerTreeHostTestCanDrawBlocksDrawing
: public LayerTreeHostTest
{
343 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
345 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
347 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
350 // Only the initial draw should bring us here.
351 EXPECT_TRUE(impl
->CanDraw());
352 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
355 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
358 if (num_commits_
>= 1) {
359 // After the first commit, we should not be able to draw.
360 EXPECT_FALSE(impl
->CanDraw());
364 virtual void DidCommit() OVERRIDE
{
366 if (num_commits_
== 1) {
367 // Make the viewport empty so the host says it can't draw.
368 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
369 } else if (num_commits_
== 2) {
371 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
372 } else if (num_commits_
== 3) {
373 // Let it draw so we go idle and end the test.
374 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
380 virtual void AfterTest() OVERRIDE
{}
387 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing
);
389 // beginLayerWrite should prevent draws from executing until a commit occurs
390 class LayerTreeHostTestWriteLayersRedraw
: public LayerTreeHostTest
{
392 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
394 virtual void BeginTest() OVERRIDE
{
395 PostAcquireLayerTextures();
396 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
397 PostSetNeedsCommitToMainThread();
400 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
402 EXPECT_EQ(num_draws_
, num_commits_
);
405 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
410 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_commits_
); }
417 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw
);
419 // Verify that when resuming visibility, Requesting layer write permission
420 // will not deadlock the main thread even though there are not yet any
421 // scheduled redraws. This behavior is critical for reliably surviving tab
422 // switching. There are no failure conditions to this test, it just passes
423 // by not timing out.
424 class LayerTreeHostTestWriteLayersAfterVisible
: public LayerTreeHostTest
{
426 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
428 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
430 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
432 if (num_commits_
== 2)
434 else if (num_commits_
< 2) {
435 PostSetVisibleToMainThread(false);
436 PostSetVisibleToMainThread(true);
437 PostAcquireLayerTextures();
438 PostSetNeedsCommitToMainThread();
442 virtual void AfterTest() OVERRIDE
{}
448 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible
);
450 // A compositeAndReadback while invisible should force a normal commit without
452 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
453 : public LayerTreeHostTest
{
455 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
457 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
459 virtual void DidCommitAndDrawFrame() OVERRIDE
{
461 if (num_commits_
== 1) {
462 layer_tree_host()->SetVisible(false);
463 layer_tree_host()->SetNeedsCommit();
464 layer_tree_host()->SetNeedsCommit();
466 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
472 virtual void AfterTest() OVERRIDE
{}
478 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible
);
480 class LayerTreeHostTestAbortFrameWhenInvisible
: public LayerTreeHostTest
{
482 LayerTreeHostTestAbortFrameWhenInvisible() {}
484 virtual void BeginTest() OVERRIDE
{
485 // Request a commit (from the main thread), Which will trigger the commit
486 // flow from the impl side.
487 layer_tree_host()->SetNeedsCommit();
488 // Then mark ourselves as not visible before processing any more messages
489 // on the main thread.
490 layer_tree_host()->SetVisible(false);
491 // If we make it without kicking a frame, we pass!
492 EndTestAfterDelay(1);
495 virtual void Layout() OVERRIDE
{
500 virtual void AfterTest() OVERRIDE
{}
505 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible
);
507 // This test verifies that properties on the layer tree host are commited
509 class LayerTreeHostTestCommit
: public LayerTreeHostTest
{
511 LayerTreeHostTestCommit() {}
513 virtual void BeginTest() OVERRIDE
{
514 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
515 layer_tree_host()->set_background_color(SK_ColorGRAY
);
516 layer_tree_host()->SetPageScaleFactorAndLimits(5.f
, 5.f
, 5.f
);
518 PostSetNeedsCommitToMainThread();
521 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
522 EXPECT_EQ(gfx::Size(20, 20), impl
->device_viewport_size());
523 EXPECT_EQ(SK_ColorGRAY
, impl
->active_tree()->background_color());
524 EXPECT_EQ(5.f
, impl
->active_tree()->page_scale_factor());
529 virtual void AfterTest() OVERRIDE
{}
532 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit
);
534 // Verifies that StartPageScaleAnimation events propagate correctly
535 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
536 class LayerTreeHostTestStartPageScaleAnimation
: public LayerTreeHostTest
{
538 LayerTreeHostTestStartPageScaleAnimation() {}
540 virtual void BeginTest() OVERRIDE
{
541 layer_tree_host()->root_layer()->SetScrollable(true);
542 layer_tree_host()->root_layer()->SetScrollOffset(gfx::Vector2d());
543 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 2.f
);
544 layer_tree_host()->StartPageScaleAnimation(
545 gfx::Vector2d(), false, 1.25f
, base::TimeDelta());
546 PostSetNeedsCommitToMainThread();
547 PostSetNeedsRedrawToMainThread();
550 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
, float scale
)
552 gfx::Vector2d offset
= layer_tree_host()->root_layer()->scroll_offset();
553 layer_tree_host()->root_layer()->SetScrollOffset(offset
+ scroll_delta
);
554 layer_tree_host()->SetPageScaleFactorAndLimits(scale
, 0.5f
, 2.f
);
557 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
558 impl
->ProcessScrollDeltas();
559 // We get one commit before the first draw, and the animation doesn't happen
560 // until the second draw.
561 if (impl
->active_tree()->source_frame_number() == 1) {
562 EXPECT_EQ(1.25f
, impl
->active_tree()->page_scale_factor());
565 PostSetNeedsRedrawToMainThread();
569 virtual void AfterTest() OVERRIDE
{}
572 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation
);
574 class LayerTreeHostTestSetVisible
: public LayerTreeHostTest
{
576 LayerTreeHostTestSetVisible() : num_draws_(0) {}
578 virtual void BeginTest() OVERRIDE
{
579 PostSetNeedsCommitToMainThread();
580 PostSetVisibleToMainThread(false);
581 // This is suppressed while we're invisible.
582 PostSetNeedsRedrawToMainThread();
583 // Triggers the redraw.
584 PostSetVisibleToMainThread(true);
587 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
588 EXPECT_TRUE(impl
->visible());
593 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_draws_
); }
599 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible
);
601 class TestOpacityChangeLayerDelegate
: public ContentLayerClient
{
603 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
605 void SetTestLayer(Layer
* test_layer
) { test_layer_
= test_layer
; }
607 virtual void PaintContents(SkCanvas
*, gfx::Rect
, gfx::RectF
*) OVERRIDE
{
608 // Set layer opacity to 0.
610 test_layer_
->SetOpacity(0.f
);
612 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
618 class ContentLayerWithUpdateTracking
: public ContentLayer
{
620 static scoped_refptr
<ContentLayerWithUpdateTracking
> Create(
621 ContentLayerClient
* client
) {
622 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client
));
625 int PaintContentsCount() { return paint_contents_count_
; }
626 void ResetPaintContentsCount() { paint_contents_count_
= 0; }
628 virtual void Update(ResourceUpdateQueue
* queue
,
629 const OcclusionTracker
* occlusion
,
630 RenderingStats
* stats
) OVERRIDE
{
631 ContentLayer::Update(queue
, occlusion
, stats
);
632 paint_contents_count_
++;
636 explicit ContentLayerWithUpdateTracking(ContentLayerClient
* client
)
637 : ContentLayer(client
), paint_contents_count_(0) {
638 SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
639 SetBounds(gfx::Size(10, 10));
642 virtual ~ContentLayerWithUpdateTracking() {}
644 int paint_contents_count_
;
647 // Layer opacity change during paint should not prevent compositor resources
648 // from being updated during commit.
649 class LayerTreeHostTestOpacityChange
: public LayerTreeHostTest
{
651 LayerTreeHostTestOpacityChange()
652 : test_opacity_change_delegate_(),
653 update_check_layer_(ContentLayerWithUpdateTracking::Create(
654 &test_opacity_change_delegate_
)) {
655 test_opacity_change_delegate_
.SetTestLayer(update_check_layer_
.get());
658 virtual void BeginTest() OVERRIDE
{
659 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
660 layer_tree_host()->root_layer()->AddChild(update_check_layer_
);
662 PostSetNeedsCommitToMainThread();
665 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
669 virtual void AfterTest() OVERRIDE
{
670 // Update() should have been called once.
671 EXPECT_EQ(1, update_check_layer_
->PaintContentsCount());
675 TestOpacityChangeLayerDelegate test_opacity_change_delegate_
;
676 scoped_refptr
<ContentLayerWithUpdateTracking
> update_check_layer_
;
679 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange
);
681 class NoScaleContentLayer
: public ContentLayer
{
683 static scoped_refptr
<NoScaleContentLayer
> Create(ContentLayerClient
* client
) {
684 return make_scoped_refptr(new NoScaleContentLayer(client
));
687 virtual void CalculateContentsScale(float ideal_contents_scale
,
688 bool animating_transform_to_screen
,
689 float* contents_scale_x
,
690 float* contents_scale_y
,
691 gfx::Size
* contentBounds
) OVERRIDE
{
692 // Skip over the ContentLayer's method to the base Layer class.
693 Layer::CalculateContentsScale(ideal_contents_scale
,
694 animating_transform_to_screen
,
701 explicit NoScaleContentLayer(ContentLayerClient
* client
)
702 : ContentLayer(client
) {}
703 virtual ~NoScaleContentLayer() {}
706 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
707 : public LayerTreeHostTest
{
709 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
710 : root_layer_(NoScaleContentLayer::Create(&client_
)),
711 child_layer_(ContentLayer::Create(&client_
)) {}
713 virtual void BeginTest() OVERRIDE
{
714 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
715 layer_tree_host()->SetDeviceScaleFactor(1.5);
716 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
718 root_layer_
->AddChild(child_layer_
);
720 root_layer_
->SetIsDrawable(true);
721 root_layer_
->SetBounds(gfx::Size(30, 30));
722 root_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
724 child_layer_
->SetIsDrawable(true);
725 child_layer_
->SetPosition(gfx::Point(2, 2));
726 child_layer_
->SetBounds(gfx::Size(10, 10));
727 child_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
729 layer_tree_host()->SetRootLayer(root_layer_
);
731 ASSERT_TRUE(layer_tree_host()->InitializeRendererIfNeeded());
732 ResourceUpdateQueue queue
;
733 layer_tree_host()->UpdateLayers(&queue
, std::numeric_limits
<size_t>::max());
734 PostSetNeedsCommitToMainThread();
737 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
738 // Should only do one commit.
739 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
740 // Device scale factor should come over to impl.
741 EXPECT_NEAR(impl
->device_scale_factor(), 1.5f
, 0.00001f
);
743 // Both layers are on impl.
744 ASSERT_EQ(1u, impl
->active_tree()->root_layer()->children().size());
746 // Device viewport is scaled.
747 EXPECT_EQ(gfx::Size(60, 60), impl
->device_viewport_size());
749 LayerImpl
* root
= impl
->active_tree()->root_layer();
750 LayerImpl
* child
= impl
->active_tree()->root_layer()->children()[0];
752 // Positions remain in layout pixels.
753 EXPECT_EQ(gfx::Point(0, 0), root
->position());
754 EXPECT_EQ(gfx::Point(2, 2), child
->position());
756 // Compute all the layer transforms for the frame.
757 LayerTreeHostImpl::FrameData frame_data
;
758 impl
->PrepareToDraw(&frame_data
, gfx::Rect());
759 impl
->DidDrawAllLayers(frame_data
);
761 const LayerImplList
& render_surface_layer_list
=
762 *frame_data
.render_surface_layer_list
;
764 // Both layers should be drawing into the root render surface.
765 ASSERT_EQ(1u, render_surface_layer_list
.size());
766 ASSERT_EQ(root
->render_surface(),
767 render_surface_layer_list
[0]->render_surface());
768 ASSERT_EQ(2u, root
->render_surface()->layer_list().size());
770 // The root render surface is the size of the viewport.
771 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
772 root
->render_surface()->content_rect());
774 // The content bounds of the child should be scaled.
775 gfx::Size child_bounds_scaled
=
776 gfx::ToCeiledSize(gfx::ScaleSize(child
->bounds(), 1.5));
777 EXPECT_EQ(child_bounds_scaled
, child
->content_bounds());
779 gfx::Transform scale_transform
;
780 scale_transform
.Scale(impl
->device_scale_factor(),
781 impl
->device_scale_factor());
783 // The root layer is scaled by 2x.
784 gfx::Transform root_screen_space_transform
= scale_transform
;
785 gfx::Transform root_draw_transform
= scale_transform
;
787 EXPECT_EQ(root_draw_transform
, root
->draw_transform());
788 EXPECT_EQ(root_screen_space_transform
, root
->screen_space_transform());
790 // The child is at position 2,2, which is transformed to 3,3 after the scale
791 gfx::Transform child_screen_space_transform
;
792 child_screen_space_transform
.Translate(3.f
, 3.f
);
793 gfx::Transform child_draw_transform
= child_screen_space_transform
;
795 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform
,
796 child
->draw_transform());
797 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform
,
798 child
->screen_space_transform());
803 virtual void AfterTest() OVERRIDE
{}
806 FakeContentLayerClient client_
;
807 scoped_refptr
<NoScaleContentLayer
> root_layer_
;
808 scoped_refptr
<ContentLayer
> child_layer_
;
811 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
);
813 // Verify atomicity of commits and reuse of textures.
814 class LayerTreeHostTestAtomicCommit
: public LayerTreeHostTest
{
816 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
817 // Make sure partial texture updates are turned off.
818 settings
->max_partial_texture_updates
= 0;
819 // Linear fade animator prevents scrollbars from drawing immediately.
820 settings
->use_linear_fade_scrollbar_animator
= false;
823 virtual void SetupTree() OVERRIDE
{
824 layer_
= FakeContentLayer::Create(&client_
);
825 layer_
->SetBounds(gfx::Size(10, 20));
827 bool paint_scrollbar
= true;
828 bool has_thumb
= false;
830 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, layer_
->id());
831 scrollbar_
->SetPosition(gfx::Point(0, 10));
832 scrollbar_
->SetBounds(gfx::Size(10, 10));
834 layer_
->AddChild(scrollbar_
);
836 layer_tree_host()->SetRootLayer(layer_
);
837 LayerTreeHostTest::SetupTree();
840 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
842 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
843 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates
);
845 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
846 impl
->output_surface()->context3d());
848 switch (impl
->active_tree()->source_frame_number()) {
850 // Number of textures should be one for each layer
851 ASSERT_EQ(2u, context
->NumTextures());
852 // Number of textures used for commit should be one for each layer.
853 EXPECT_EQ(2u, context
->NumUsedTextures());
854 // Verify that used texture is correct.
855 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
856 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
858 context
->ResetUsedTextures();
859 PostSetNeedsCommitToMainThread();
862 // Number of textures should be doubled as the first textures
863 // are used by impl thread and cannot by used for update.
864 ASSERT_EQ(4u, context
->NumTextures());
865 // Number of textures used for commit should still be
866 // one for each layer.
867 EXPECT_EQ(2u, context
->NumUsedTextures());
868 // First textures should not have been used.
869 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
870 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
871 // New textures should have been used.
872 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
873 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
875 context
->ResetUsedTextures();
876 PostSetNeedsCommitToMainThread();
887 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
888 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
889 impl
->output_surface()->context3d());
891 // Number of textures used for draw should always be one for each layer.
892 EXPECT_EQ(2u, context
->NumUsedTextures());
893 context
->ResetUsedTextures();
896 virtual void Layout() OVERRIDE
{
897 layer_
->SetNeedsDisplay();
898 scrollbar_
->SetNeedsDisplay();
901 virtual void AfterTest() OVERRIDE
{}
904 FakeContentLayerClient client_
;
905 scoped_refptr
<FakeContentLayer
> layer_
;
906 scoped_refptr
<FakeScrollbarLayer
> scrollbar_
;
909 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit
);
911 static void SetLayerPropertiesForTesting(Layer
* layer
,
913 const gfx::Transform
& transform
,
915 gfx::PointF position
,
918 layer
->RemoveAllChildren();
920 parent
->AddChild(layer
);
921 layer
->SetTransform(transform
);
922 layer
->SetAnchorPoint(anchor
);
923 layer
->SetPosition(position
);
924 layer
->SetBounds(bounds
);
925 layer
->SetContentsOpaque(opaque
);
928 class LayerTreeHostTestAtomicCommitWithPartialUpdate
929 : public LayerTreeHostTest
{
931 LayerTreeHostTestAtomicCommitWithPartialUpdate() : num_commits_(0) {}
933 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
934 // Allow one partial texture update.
935 settings
->max_partial_texture_updates
= 1;
936 // Linear fade animator prevents scrollbars from drawing immediately.
937 settings
->use_linear_fade_scrollbar_animator
= false;
940 virtual void SetupTree() OVERRIDE
{
941 parent_
= FakeContentLayer::Create(&client_
);
942 parent_
->SetBounds(gfx::Size(10, 20));
944 child_
= FakeContentLayer::Create(&client_
);
945 child_
->SetPosition(gfx::Point(0, 10));
946 child_
->SetBounds(gfx::Size(3, 10));
948 bool paint_scrollbar
= true;
949 bool has_thumb
= false;
950 scrollbar_with_paints_
=
951 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, parent_
->id());
952 scrollbar_with_paints_
->SetPosition(gfx::Point(3, 10));
953 scrollbar_with_paints_
->SetBounds(gfx::Size(3, 10));
955 paint_scrollbar
= false;
956 scrollbar_without_paints_
=
957 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, parent_
->id());
958 scrollbar_without_paints_
->SetPosition(gfx::Point(6, 10));
959 scrollbar_without_paints_
->SetBounds(gfx::Size(3, 10));
961 parent_
->AddChild(child_
);
962 parent_
->AddChild(scrollbar_with_paints_
);
963 parent_
->AddChild(scrollbar_without_paints_
);
965 layer_tree_host()->SetRootLayer(parent_
);
966 LayerTreeHostTest::SetupTree();
969 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
971 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
972 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates
);
974 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
975 impl
->output_surface()->context3d());
977 switch (impl
->active_tree()->source_frame_number()) {
979 // Number of textures should be one for each layer.
980 ASSERT_EQ(4u, context
->NumTextures());
981 // Number of textures used for commit should be one for each layer.
982 EXPECT_EQ(4u, context
->NumUsedTextures());
983 // Verify that used textures are correct.
984 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
985 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
986 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
987 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
989 context
->ResetUsedTextures();
990 PostSetNeedsCommitToMainThread();
993 // Number of textures should be two for each content layer and one
994 // for each scrollbar, since they always do a partial update.
995 ASSERT_EQ(6u, context
->NumTextures());
996 // Number of textures used for commit should be one for each content
997 // layer, and one for the scrollbar layer that paints.
998 EXPECT_EQ(3u, context
->NumUsedTextures());
1000 // First content textures should not have been used.
1001 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1002 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1003 // The non-painting scrollbar's texture wasn't updated.
1004 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1005 // The painting scrollbar's partial update texture was used.
1006 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1007 // New textures should have been used.
1008 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1009 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(5)));
1011 context
->ResetUsedTextures();
1012 PostSetNeedsCommitToMainThread();
1015 // Number of textures should be two for each content layer and one
1016 // for each scrollbar, since they always do a partial update.
1017 ASSERT_EQ(6u, context
->NumTextures());
1018 // Number of textures used for commit should be one for each content
1019 // layer, and one for the scrollbar layer that paints.
1020 EXPECT_EQ(3u, context
->NumUsedTextures());
1022 // The non-painting scrollbar's texture wasn't updated.
1023 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1024 // The painting scrollbar does a partial update.
1025 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1026 // One content layer does a partial update also.
1027 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1028 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(5)));
1030 context
->ResetUsedTextures();
1031 PostSetNeedsCommitToMainThread();
1034 // No textures should be used for commit.
1035 EXPECT_EQ(0u, context
->NumUsedTextures());
1037 context
->ResetUsedTextures();
1038 PostSetNeedsCommitToMainThread();
1041 // Number of textures used for commit should be two. One for the
1042 // content layer, and one for the painting scrollbar. The
1043 // non-painting scrollbar doesn't update its texture.
1044 EXPECT_EQ(2u, context
->NumUsedTextures());
1046 context
->ResetUsedTextures();
1047 PostSetNeedsCommitToMainThread();
1058 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1059 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
1060 impl
->output_surface()->context3d());
1062 // Number of textures used for drawing should one per layer except for
1063 // frame 3 where the viewport only contains one layer.
1064 if (impl
->active_tree()->source_frame_number() == 3)
1065 EXPECT_EQ(1u, context
->NumUsedTextures());
1067 EXPECT_EQ(4u, context
->NumUsedTextures());
1069 context
->ResetUsedTextures();
1072 virtual void Layout() OVERRIDE
{
1073 switch (num_commits_
++) {
1076 parent_
->SetNeedsDisplay();
1077 child_
->SetNeedsDisplay();
1078 scrollbar_with_paints_
->SetNeedsDisplay();
1079 scrollbar_without_paints_
->SetNeedsDisplay();
1082 // Damage part of layers.
1083 parent_
->SetNeedsDisplayRect(gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1084 child_
->SetNeedsDisplayRect(gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1085 scrollbar_with_paints_
->SetNeedsDisplayRect(
1086 gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1087 scrollbar_without_paints_
->SetNeedsDisplayRect(
1088 gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1091 child_
->SetNeedsDisplay();
1092 scrollbar_with_paints_
->SetNeedsDisplay();
1093 scrollbar_without_paints_
->SetNeedsDisplay();
1094 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1097 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1107 virtual void AfterTest() OVERRIDE
{}
1110 FakeContentLayerClient client_
;
1111 scoped_refptr
<FakeContentLayer
> parent_
;
1112 scoped_refptr
<FakeContentLayer
> child_
;
1113 scoped_refptr
<FakeScrollbarLayer
> scrollbar_with_paints_
;
1114 scoped_refptr
<FakeScrollbarLayer
> scrollbar_without_paints_
;
1118 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate
);
1120 class LayerTreeHostTestFinishAllRendering
: public LayerTreeHostTest
{
1122 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1124 virtual void BeginTest() OVERRIDE
{
1125 layer_tree_host()->SetNeedsRedraw();
1126 PostSetNeedsCommitToMainThread();
1129 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1133 layer_tree_host()->SetNeedsRedraw();
1134 layer_tree_host()->AcquireLayerTextures();
1136 base::AutoLock
lock(lock_
);
1139 layer_tree_host()->FinishAllRendering();
1141 base::AutoLock
lock(lock_
);
1142 EXPECT_EQ(0, draw_count_
);
1147 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1148 base::AutoLock
lock(lock_
);
1152 virtual void AfterTest() OVERRIDE
{}
1160 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering
);
1162 class LayerTreeHostTestCompositeAndReadbackCleanup
: public LayerTreeHostTest
{
1164 LayerTreeHostTestCompositeAndReadbackCleanup() {}
1166 virtual void BeginTest() OVERRIDE
{
1167 Layer
* root_layer
= layer_tree_host()->root_layer();
1170 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels
),
1171 gfx::Rect(0, 0, 1, 1));
1172 EXPECT_FALSE(root_layer
->render_surface());
1177 virtual void AfterTest() OVERRIDE
{}
1180 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup
);
1182 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1183 : public LayerTreeHostTest
{
1185 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
1186 : root_layer_(FakeContentLayer::Create(&client_
)),
1188 FakeContentLayer::Create(&client_
)),
1190 FakeContentLayer::Create(&client_
)),
1192 FakeContentLayer::Create(&client_
)),
1194 FakeContentLayer::Create(&client_
)) {}
1196 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1197 settings
->cache_render_pass_contents
= true;
1200 virtual void BeginTest() OVERRIDE
{
1201 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
1203 root_layer_
->SetBounds(gfx::Size(100, 100));
1204 surface_layer1_
->SetBounds(gfx::Size(100, 100));
1205 surface_layer1_
->SetForceRenderSurface(true);
1206 surface_layer1_
->SetOpacity(0.5f
);
1207 surface_layer2_
->SetBounds(gfx::Size(100, 100));
1208 surface_layer2_
->SetForceRenderSurface(true);
1209 surface_layer2_
->SetOpacity(0.5f
);
1211 surface_layer1_
->SetReplicaLayer(replica_layer1_
.get());
1212 surface_layer2_
->SetReplicaLayer(replica_layer2_
.get());
1214 root_layer_
->AddChild(surface_layer1_
);
1215 surface_layer1_
->AddChild(surface_layer2_
);
1216 layer_tree_host()->SetRootLayer(root_layer_
);
1218 PostSetNeedsCommitToMainThread();
1221 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1222 Renderer
* renderer
= host_impl
->renderer();
1223 RenderPass::Id surface1_render_pass_id
= host_impl
->active_tree()
1224 ->root_layer()->children()[0]->render_surface()->RenderPassId();
1225 RenderPass::Id surface2_render_pass_id
=
1226 host_impl
->active_tree()->root_layer()->children()[0]->children()[0]
1227 ->render_surface()->RenderPassId();
1229 switch (host_impl
->active_tree()->source_frame_number()) {
1231 EXPECT_TRUE(renderer
->HaveCachedResourcesForRenderPassId(
1232 surface1_render_pass_id
));
1233 EXPECT_TRUE(renderer
->HaveCachedResourcesForRenderPassId(
1234 surface2_render_pass_id
));
1236 // Reduce the memory limit to only fit the root layer and one render
1237 // surface. This prevents any contents drawing into surfaces
1238 // from being allocated.
1239 host_impl
->SetManagedMemoryPolicy(
1240 ManagedMemoryPolicy(100 * 100 * 4 * 2));
1243 EXPECT_FALSE(renderer
->HaveCachedResourcesForRenderPassId(
1244 surface1_render_pass_id
));
1245 EXPECT_FALSE(renderer
->HaveCachedResourcesForRenderPassId(
1246 surface2_render_pass_id
));
1253 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1255 root_layer_
->SetNeedsDisplay();
1258 virtual void AfterTest() OVERRIDE
{
1259 EXPECT_EQ(3u, root_layer_
->update_count());
1260 EXPECT_EQ(3u, surface_layer1_
->update_count());
1261 EXPECT_EQ(3u, surface_layer2_
->update_count());
1265 FakeContentLayerClient client_
;
1266 scoped_refptr
<FakeContentLayer
> root_layer_
;
1267 scoped_refptr
<FakeContentLayer
> surface_layer1_
;
1268 scoped_refptr
<FakeContentLayer
> replica_layer1_
;
1269 scoped_refptr
<FakeContentLayer
> surface_layer2_
;
1270 scoped_refptr
<FakeContentLayer
> replica_layer2_
;
1273 SINGLE_AND_MULTI_THREAD_TEST_F(
1274 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
);
1276 class EvictionTestLayer
: public Layer
{
1278 static scoped_refptr
<EvictionTestLayer
> Create() {
1279 return make_scoped_refptr(new EvictionTestLayer());
1282 virtual void Update(ResourceUpdateQueue
*,
1283 const OcclusionTracker
*,
1284 RenderingStats
*) OVERRIDE
;
1285 virtual bool DrawsContent() const OVERRIDE
{ return true; }
1287 virtual scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
)
1289 virtual void PushPropertiesTo(LayerImpl
* impl
) OVERRIDE
;
1290 virtual void SetTexturePriorities(const PriorityCalculator
&) OVERRIDE
;
1292 bool HaveBackingTexture() const {
1293 return texture_
.get() ? texture_
->have_backing_texture() : false;
1297 EvictionTestLayer() : Layer() {}
1298 virtual ~EvictionTestLayer() {}
1300 void CreateTextureIfNeeded() {
1303 texture_
= PrioritizedResource::Create(
1304 layer_tree_host()->contents_texture_manager());
1305 texture_
->SetDimensions(gfx::Size(10, 10), GL_RGBA
);
1306 bitmap_
.setConfig(SkBitmap::kARGB_8888_Config
, 10, 10);
1309 scoped_ptr
<PrioritizedResource
> texture_
;
1313 class EvictionTestLayerImpl
: public LayerImpl
{
1315 static scoped_ptr
<EvictionTestLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1317 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl
, id
));
1319 virtual ~EvictionTestLayerImpl() {}
1321 virtual void AppendQuads(QuadSink
* quad_sink
,
1322 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1323 ASSERT_TRUE(has_texture_
);
1324 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1327 void SetHasTexture(bool has_texture
) { has_texture_
= has_texture
; }
1330 EvictionTestLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
1331 : LayerImpl(tree_impl
, id
), has_texture_(false) {}
1336 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator
&) {
1337 CreateTextureIfNeeded();
1338 if (!texture_
.get())
1340 texture_
->set_request_priority(PriorityCalculator::UIPriority(true));
1343 void EvictionTestLayer::Update(ResourceUpdateQueue
* queue
,
1344 const OcclusionTracker
*,
1346 CreateTextureIfNeeded();
1347 if (!texture_
.get())
1350 gfx::Rect
full_rect(0, 0, 10, 10);
1351 ResourceUpdate upload
= ResourceUpdate::Create(
1352 texture_
.get(), &bitmap_
, full_rect
, full_rect
, gfx::Vector2d());
1353 queue
->AppendFullUpload(upload
);
1356 scoped_ptr
<LayerImpl
> EvictionTestLayer::CreateLayerImpl(
1357 LayerTreeImpl
* tree_impl
) {
1358 return EvictionTestLayerImpl::Create(tree_impl
, layer_id_
)
1359 .PassAs
<LayerImpl
>();
1362 void EvictionTestLayer::PushPropertiesTo(LayerImpl
* layer_impl
) {
1363 Layer::PushPropertiesTo(layer_impl
);
1365 EvictionTestLayerImpl
* test_layer_impl
=
1366 static_cast<EvictionTestLayerImpl
*>(layer_impl
);
1367 test_layer_impl
->SetHasTexture(texture_
->have_backing_texture());
1370 class LayerTreeHostTestEvictTextures
: public LayerTreeHostTest
{
1372 LayerTreeHostTestEvictTextures()
1373 : layer_(EvictionTestLayer::Create()),
1374 impl_for_evict_textures_(0),
1377 virtual void BeginTest() OVERRIDE
{
1378 layer_tree_host()->SetRootLayer(layer_
);
1379 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1381 gfx::Transform identity_matrix
;
1382 SetLayerPropertiesForTesting(layer_
.get(),
1385 gfx::PointF(0.f
, 0.f
),
1386 gfx::PointF(0.f
, 0.f
),
1390 PostSetNeedsCommitToMainThread();
1393 void PostEvictTextures() {
1394 DCHECK(ImplThread());
1395 ImplThread()->PostTask(
1396 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread
,
1397 base::Unretained(this)));
1400 void EvictTexturesOnImplThread() {
1401 DCHECK(impl_for_evict_textures_
);
1402 impl_for_evict_textures_
->EnforceManagedMemoryPolicy(
1403 ManagedMemoryPolicy(0));
1406 // Commit 1: Just commit and draw normally, then post an eviction at the end
1407 // that will trigger a commit.
1408 // Commit 2: Triggered by the eviction, let it go through and then set
1410 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1411 // task, which will be handled before the commit. Don't set needsCommit, it
1412 // should have been posted. A frame should not be drawn (note,
1413 // didCommitAndDrawFrame may be called anyway).
1414 // Commit 4: Triggered by the eviction, let it go through and then set
1416 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1417 // Layout(), a frame should not be drawn but a commit will be posted.
1418 // Commit 6: Triggered by the eviction, post an eviction task in
1419 // Layout(), which will be a noop, letting the commit (which recreates the
1420 // textures) go through and draw a frame, then end the test.
1422 // Commits 1+2 test the eviction recovery path where eviction happens outside
1423 // of the beginFrame/commit pair.
1424 // Commits 3+4 test the eviction recovery path where eviction happens inside
1425 // the beginFrame/commit pair.
1426 // Commits 5+6 test the path where an eviction happens during the eviction
1428 virtual void DidCommit() OVERRIDE
{
1429 switch (num_commits_
) {
1431 EXPECT_TRUE(layer_
->HaveBackingTexture());
1432 PostEvictTextures();
1435 EXPECT_TRUE(layer_
->HaveBackingTexture());
1436 layer_tree_host()->SetNeedsCommit();
1441 EXPECT_TRUE(layer_
->HaveBackingTexture());
1442 layer_tree_host()->SetNeedsCommit();
1447 EXPECT_TRUE(layer_
->HaveBackingTexture());
1456 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1457 impl_for_evict_textures_
= impl
;
1460 virtual void Layout() OVERRIDE
{
1462 switch (num_commits_
) {
1467 PostEvictTextures();
1470 // We couldn't check in didCommitAndDrawFrame on commit 3,
1472 EXPECT_FALSE(layer_
->HaveBackingTexture());
1475 PostEvictTextures();
1478 // We couldn't check in didCommitAndDrawFrame on commit 5,
1480 EXPECT_FALSE(layer_
->HaveBackingTexture());
1481 PostEvictTextures();
1489 virtual void AfterTest() OVERRIDE
{}
1492 FakeContentLayerClient client_
;
1493 scoped_refptr
<EvictionTestLayer
> layer_
;
1494 LayerTreeHostImpl
* impl_for_evict_textures_
;
1498 MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures
);
1500 class LayerTreeHostTestContinuousCommit
: public LayerTreeHostTest
{
1502 LayerTreeHostTestContinuousCommit()
1503 : num_commit_complete_(0), num_draw_layers_(0) {}
1505 virtual void BeginTest() OVERRIDE
{
1506 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1507 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1509 PostSetNeedsCommitToMainThread();
1512 virtual void DidCommit() OVERRIDE
{
1513 if (num_draw_layers_
== 2)
1515 layer_tree_host()->root_layer()->SetNeedsDisplay();
1518 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1519 if (num_draw_layers_
== 1)
1520 num_commit_complete_
++;
1523 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1525 if (num_draw_layers_
== 2)
1529 virtual void AfterTest() OVERRIDE
{
1530 // Check that we didn't commit twice between first and second draw.
1531 EXPECT_EQ(1, num_commit_complete_
);
1535 int num_commit_complete_
;
1536 int num_draw_layers_
;
1539 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit
);
1541 class LayerTreeHostTestContinuousInvalidate
: public LayerTreeHostTest
{
1543 LayerTreeHostTestContinuousInvalidate()
1544 : num_commit_complete_(0), num_draw_layers_(0) {}
1546 virtual void BeginTest() OVERRIDE
{
1547 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1548 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1550 content_layer_
= ContentLayer::Create(&client_
);
1551 content_layer_
->SetBounds(gfx::Size(10, 10));
1552 content_layer_
->SetPosition(gfx::PointF(0.f
, 0.f
));
1553 content_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
1554 content_layer_
->SetIsDrawable(true);
1555 layer_tree_host()->root_layer()->AddChild(content_layer_
);
1557 PostSetNeedsCommitToMainThread();
1560 virtual void DidCommit() OVERRIDE
{
1561 if (num_draw_layers_
== 2)
1563 content_layer_
->SetNeedsDisplay();
1566 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1567 if (num_draw_layers_
== 1)
1568 num_commit_complete_
++;
1571 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1573 if (num_draw_layers_
== 2)
1577 virtual void AfterTest() OVERRIDE
{
1578 // Check that we didn't commit twice between first and second draw.
1579 EXPECT_EQ(1, num_commit_complete_
);
1583 FakeContentLayerClient client_
;
1584 scoped_refptr
<Layer
> content_layer_
;
1585 int num_commit_complete_
;
1586 int num_draw_layers_
;
1589 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate
);
1591 class LayerTreeHostTestDeferCommits
: public LayerTreeHostTest
{
1593 LayerTreeHostTestDeferCommits()
1594 : num_commits_deferred_(0), num_complete_commits_(0) {}
1596 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1598 virtual void DidDeferCommit() OVERRIDE
{
1599 num_commits_deferred_
++;
1600 layer_tree_host()->SetDeferCommits(false);
1603 virtual void DidCommit() OVERRIDE
{
1604 num_complete_commits_
++;
1605 switch (num_complete_commits_
) {
1607 EXPECT_EQ(0, num_commits_deferred_
);
1608 layer_tree_host()->SetDeferCommits(true);
1609 PostSetNeedsCommitToMainThread();
1620 virtual void AfterTest() OVERRIDE
{
1621 EXPECT_EQ(1, num_commits_deferred_
);
1622 EXPECT_EQ(2, num_complete_commits_
);
1626 int num_commits_deferred_
;
1627 int num_complete_commits_
;
1630 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits
);
1632 class LayerTreeHostWithProxy
: public LayerTreeHost
{
1634 LayerTreeHostWithProxy(FakeLayerTreeHostClient
* client
,
1635 const LayerTreeSettings
& settings
,
1636 scoped_ptr
<Proxy
> proxy
)
1637 : LayerTreeHost(client
, settings
) {
1638 EXPECT_TRUE(InitializeForTesting(proxy
.Pass()));
1642 TEST(LayerTreeHostTest
, LimitPartialUpdates
) {
1643 // When partial updates are not allowed, max updates should be 0.
1645 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1647 scoped_ptr
<FakeProxy
> proxy
=
1648 make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1649 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= false;
1650 proxy
->SetMaxPartialTextureUpdates(5);
1652 LayerTreeSettings settings
;
1653 settings
.max_partial_texture_updates
= 10;
1655 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1656 EXPECT_TRUE(host
.InitializeRendererIfNeeded());
1658 EXPECT_EQ(0u, host
.settings().max_partial_texture_updates
);
1661 // When partial updates are allowed,
1662 // max updates should be limited by the proxy.
1664 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1666 scoped_ptr
<FakeProxy
> proxy
=
1667 make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1668 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= true;
1669 proxy
->SetMaxPartialTextureUpdates(5);
1671 LayerTreeSettings settings
;
1672 settings
.max_partial_texture_updates
= 10;
1674 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1675 EXPECT_TRUE(host
.InitializeRendererIfNeeded());
1677 EXPECT_EQ(5u, host
.settings().max_partial_texture_updates
);
1680 // When partial updates are allowed,
1681 // max updates should also be limited by the settings.
1683 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1685 scoped_ptr
<FakeProxy
> proxy
=
1686 make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1687 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= true;
1688 proxy
->SetMaxPartialTextureUpdates(20);
1690 LayerTreeSettings settings
;
1691 settings
.max_partial_texture_updates
= 10;
1693 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1694 EXPECT_TRUE(host
.InitializeRendererIfNeeded());
1696 EXPECT_EQ(10u, host
.settings().max_partial_texture_updates
);
1700 TEST(LayerTreeHostTest
, PartialUpdatesWithGLRenderer
) {
1701 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1703 LayerTreeSettings settings
;
1704 settings
.max_partial_texture_updates
= 4;
1706 scoped_ptr
<LayerTreeHost
> host
=
1707 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1708 EXPECT_TRUE(host
->InitializeRendererIfNeeded());
1709 EXPECT_EQ(4u, host
->settings().max_partial_texture_updates
);
1712 TEST(LayerTreeHostTest
, PartialUpdatesWithSoftwareRenderer
) {
1713 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_SOFTWARE
);
1715 LayerTreeSettings settings
;
1716 settings
.max_partial_texture_updates
= 4;
1718 scoped_ptr
<LayerTreeHost
> host
=
1719 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1720 EXPECT_TRUE(host
->InitializeRendererIfNeeded());
1721 EXPECT_EQ(4u, host
->settings().max_partial_texture_updates
);
1724 TEST(LayerTreeHostTest
, PartialUpdatesWithDelegatingRendererAndGLContent
) {
1725 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DELEGATED_3D
);
1727 LayerTreeSettings settings
;
1728 settings
.max_partial_texture_updates
= 4;
1730 scoped_ptr
<LayerTreeHost
> host
=
1731 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1732 EXPECT_TRUE(host
->InitializeRendererIfNeeded());
1733 EXPECT_EQ(0u, host
->settings().max_partial_texture_updates
);
1736 TEST(LayerTreeHostTest
,
1737 PartialUpdatesWithDelegatingRendererAndSoftwareContent
) {
1738 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE
);
1740 LayerTreeSettings settings
;
1741 settings
.max_partial_texture_updates
= 4;
1743 scoped_ptr
<LayerTreeHost
> host
=
1744 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1745 EXPECT_TRUE(host
->InitializeRendererIfNeeded());
1746 EXPECT_EQ(0u, host
->settings().max_partial_texture_updates
);
1749 class LayerTreeHostTestCapturePicture
: public LayerTreeHostTest
{
1751 LayerTreeHostTestCapturePicture()
1752 : bounds_(gfx::Size(100, 100)),
1753 layer_(PictureLayer::Create(&content_client_
)) {}
1755 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1756 settings
->impl_side_painting
= true;
1759 class FillRectContentLayerClient
: public ContentLayerClient
{
1761 virtual void PaintContents(SkCanvas
* canvas
,
1763 gfx::RectF
* opaque
) OVERRIDE
{
1765 paint
.setColor(SK_ColorGREEN
);
1767 SkRect rect
= SkRect::MakeWH(canvas
->getDeviceSize().width(),
1768 canvas
->getDeviceSize().height());
1769 *opaque
= gfx::RectF(rect
.width(), rect
.height());
1770 canvas
->drawRect(rect
, paint
);
1772 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
1775 virtual void BeginTest() OVERRIDE
{
1776 layer_
->SetIsDrawable(true);
1777 layer_
->SetBounds(bounds_
);
1778 // Outside viewport so tiles don't have to be initialized for commit.
1779 layer_
->SetPosition(gfx::Point(100, 100));
1780 layer_tree_host()->SetViewportSize(bounds_
);
1781 layer_tree_host()->SetRootLayer(layer_
);
1783 EXPECT_TRUE(layer_tree_host()->InitializeRendererIfNeeded());
1784 PostSetNeedsCommitToMainThread();
1787 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1788 picture_
= layer_tree_host()->CapturePicture();
1792 virtual void AfterTest() OVERRIDE
{
1793 EXPECT_EQ(bounds_
, gfx::Size(picture_
->width(), picture_
->height()));
1797 SkBitmap::kARGB_8888_Config
, bounds_
.width(), bounds_
.height());
1798 bitmap
.allocPixels();
1799 bitmap
.eraseARGB(0, 0, 0, 0);
1800 SkCanvas
canvas(bitmap
);
1802 picture_
->draw(&canvas
);
1804 bitmap
.lockPixels();
1805 SkColor
* pixels
= reinterpret_cast<SkColor
*>(bitmap
.getPixels());
1806 EXPECT_EQ(SK_ColorGREEN
, pixels
[0]);
1807 bitmap
.unlockPixels();
1812 FillRectContentLayerClient content_client_
;
1813 scoped_refptr
<PictureLayer
> layer_
;
1814 skia::RefPtr
<SkPicture
> picture_
;
1817 MULTI_THREAD_TEST_F(LayerTreeHostTestCapturePicture
);
1819 class LayerTreeHostTestMaxPendingFrames
: public LayerTreeHostTest
{
1821 LayerTreeHostTestMaxPendingFrames() : LayerTreeHostTest() {}
1823 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
1824 if (delegating_renderer_
)
1825 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
1826 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
1829 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1831 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1832 DCHECK(host_impl
->proxy()->HasImplThread());
1834 const ThreadProxy
* proxy
= static_cast<ThreadProxy
*>(host_impl
->proxy());
1835 if (delegating_renderer_
) {
1836 EXPECT_EQ(1, proxy
->MaxFramesPendingForTesting());
1838 EXPECT_EQ(FrameRateController::DEFAULT_MAX_FRAMES_PENDING
,
1839 proxy
->MaxFramesPendingForTesting());
1844 virtual void AfterTest() OVERRIDE
{}
1847 bool delegating_renderer_
;
1850 TEST_F(LayerTreeHostTestMaxPendingFrames
, DelegatingRenderer
) {
1851 delegating_renderer_
= true;
1855 TEST_F(LayerTreeHostTestMaxPendingFrames
, GLRenderer
) {
1856 delegating_renderer_
= false;
1860 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
1861 : public LayerTreeHostTest
{
1863 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
1864 : root_layer_(FakeContentLayer::Create(&client_
)),
1865 child_layer1_(FakeContentLayer::Create(&client_
)),
1866 child_layer2_(FakeContentLayer::Create(&client_
)),
1869 virtual void BeginTest() OVERRIDE
{
1870 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
1871 root_layer_
->SetBounds(gfx::Size(100, 100));
1872 child_layer1_
->SetBounds(gfx::Size(100, 100));
1873 child_layer2_
->SetBounds(gfx::Size(100, 100));
1874 root_layer_
->AddChild(child_layer1_
);
1875 root_layer_
->AddChild(child_layer2_
);
1876 layer_tree_host()->SetRootLayer(root_layer_
);
1877 PostSetNeedsCommitToMainThread();
1880 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl
* host_impl
,
1881 bool visible
) OVERRIDE
{
1882 // One backing should remain unevicted.
1883 EXPECT_EQ(100u * 100u * 4u * 1u,
1884 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1885 // Make sure that contents textures are marked as having been
1887 EXPECT_TRUE(host_impl
->active_tree()->ContentsTexturesPurged());
1888 // End the test in this state.
1892 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1894 switch (num_commits_
) {
1896 // All three backings should have memory.
1898 100u * 100u * 4u * 3u,
1899 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1900 // Set a new policy that will kick out 1 of the 3 resources.
1901 // Because a resource was evicted, a commit will be kicked off.
1902 host_impl
->SetManagedMemoryPolicy(
1903 ManagedMemoryPolicy(100 * 100 * 4 * 2,
1904 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING
,
1906 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING
));
1909 // Only two backings should have memory.
1911 100u * 100u * 4u * 2u,
1912 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1913 // Become backgrounded, which will cause 1 more resource to be
1915 PostSetVisibleToMainThread(false);
1918 // No further commits should happen because this is not visible
1925 virtual void AfterTest() OVERRIDE
{}
1928 FakeContentLayerClient client_
;
1929 scoped_refptr
<FakeContentLayer
> root_layer_
;
1930 scoped_refptr
<FakeContentLayer
> child_layer1_
;
1931 scoped_refptr
<FakeContentLayer
> child_layer2_
;
1935 SINGLE_AND_MULTI_THREAD_TEST_F(
1936 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
);
1938 class LayerTreeHostTestPinchZoomScrollbarCreation
: public LayerTreeHostTest
{
1940 LayerTreeHostTestPinchZoomScrollbarCreation()
1941 : root_layer_(ContentLayer::Create(&client_
)) {}
1943 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1944 settings
->use_pinch_zoom_scrollbars
= true;
1947 virtual void BeginTest() OVERRIDE
{
1948 root_layer_
->SetIsDrawable(true);
1949 root_layer_
->SetBounds(gfx::Size(100, 100));
1950 layer_tree_host()->SetRootLayer(root_layer_
);
1951 PostSetNeedsCommitToMainThread();
1954 virtual void DidCommit() OVERRIDE
{
1955 // We always expect two pinch-zoom scrollbar layers.
1956 ASSERT_EQ(2u, root_layer_
->children().size());
1958 // Pinch-zoom scrollbar layers always have invalid scrollLayerIds.
1959 ScrollbarLayer
* layer1
= root_layer_
->children()[0]->ToScrollbarLayer();
1960 ASSERT_TRUE(layer1
);
1961 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
1962 layer1
->scroll_layer_id());
1963 EXPECT_EQ(0.f
, layer1
->opacity());
1964 EXPECT_TRUE(layer1
->OpacityCanAnimateOnImplThread());
1965 EXPECT_TRUE(layer1
->DrawsContent());
1967 ScrollbarLayer
* layer2
= root_layer_
->children()[1]->ToScrollbarLayer();
1968 ASSERT_TRUE(layer2
);
1969 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
1970 layer2
->scroll_layer_id());
1971 EXPECT_EQ(0.f
, layer2
->opacity());
1972 EXPECT_TRUE(layer2
->OpacityCanAnimateOnImplThread());
1973 EXPECT_TRUE(layer2
->DrawsContent());
1978 virtual void AfterTest() OVERRIDE
{}
1981 FakeContentLayerClient client_
;
1982 scoped_refptr
<ContentLayer
> root_layer_
;
1985 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarCreation
);
1987 class LayerTreeHostTestPinchZoomScrollbarResize
: public LayerTreeHostTest
{
1989 LayerTreeHostTestPinchZoomScrollbarResize()
1990 : root_layer_(ContentLayer::Create(&client_
)), num_commits_(0) {}
1992 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1993 settings
->use_pinch_zoom_scrollbars
= true;
1996 virtual void BeginTest() OVERRIDE
{
1997 root_layer_
->SetIsDrawable(true);
1998 root_layer_
->SetBounds(gfx::Size(100, 100));
1999 layer_tree_host()->SetRootLayer(root_layer_
);
2000 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2001 PostSetNeedsCommitToMainThread();
2004 virtual void DidCommit() OVERRIDE
{
2007 ScrollbarLayer
* layer1
= root_layer_
->children()[0]->ToScrollbarLayer();
2008 ASSERT_TRUE(layer1
);
2009 ScrollbarLayer
* layer2
= root_layer_
->children()[1]->ToScrollbarLayer();
2010 ASSERT_TRUE(layer2
);
2012 // Get scrollbar thickness from horizontal scrollbar's height.
2013 int thickness
= layer1
->bounds().height();
2015 if (!layer1
->Orientation() == WebKit::WebScrollbar::Horizontal
)
2016 std::swap(layer1
, layer2
);
2018 gfx::Size viewport_size
= layer_tree_host()->device_viewport_size();
2019 EXPECT_EQ(viewport_size
.width() - thickness
, layer1
->bounds().width());
2020 EXPECT_EQ(viewport_size
.height() - thickness
, layer2
->bounds().height());
2022 switch (num_commits_
) {
2024 // Resizing the viewport should also resize the pinch-zoom scrollbars.
2025 layer_tree_host()->SetViewportSize(gfx::Size(120, 150));
2032 virtual void AfterTest() OVERRIDE
{}
2035 FakeContentLayerClient client_
;
2036 scoped_refptr
<ContentLayer
> root_layer_
;
2040 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarResize
);
2042 class LayerTreeHostTestPinchZoomScrollbarNewRootLayer
2043 : public LayerTreeHostTest
{
2045 LayerTreeHostTestPinchZoomScrollbarNewRootLayer()
2046 : root_layer_(ContentLayer::Create(&client_
)), num_commits_(0) {}
2048 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2049 settings
->use_pinch_zoom_scrollbars
= true;
2052 virtual void BeginTest() OVERRIDE
{
2053 root_layer_
->SetIsDrawable(true);
2054 root_layer_
->SetBounds(gfx::Size(100, 100));
2055 layer_tree_host()->SetRootLayer(root_layer_
);
2056 PostSetNeedsCommitToMainThread();
2059 virtual void DidCommit() OVERRIDE
{
2062 // We always expect two pinch-zoom scrollbar layers.
2063 ASSERT_EQ(2u, root_layer_
->children().size());
2065 // Pinch-zoom scrollbar layers always have invalid scrollLayerIds.
2066 ScrollbarLayer
* layer1
= root_layer_
->children()[0]->ToScrollbarLayer();
2067 ASSERT_TRUE(layer1
);
2068 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
2069 layer1
->scroll_layer_id());
2070 EXPECT_EQ(0.f
, layer1
->opacity());
2071 EXPECT_TRUE(layer1
->DrawsContent());
2073 ScrollbarLayer
* layer2
= root_layer_
->children()[1]->ToScrollbarLayer();
2074 ASSERT_TRUE(layer2
);
2075 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
2076 layer2
->scroll_layer_id());
2077 EXPECT_EQ(0.f
, layer2
->opacity());
2078 EXPECT_TRUE(layer2
->DrawsContent());
2080 if (num_commits_
== 1) {
2081 // Create a new root layer and attach to tree to verify the pinch
2082 // zoom scrollbars get correctly re-attached.
2083 root_layer_
= ContentLayer::Create(&client_
);
2084 root_layer_
->SetIsDrawable(true);
2085 root_layer_
->SetBounds(gfx::Size(100, 100));
2086 layer_tree_host()->SetRootLayer(root_layer_
);
2087 PostSetNeedsCommitToMainThread();
2093 virtual void AfterTest() OVERRIDE
{}
2096 FakeContentLayerClient client_
;
2097 scoped_refptr
<ContentLayer
> root_layer_
;
2101 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarNewRootLayer
);
2103 class LayerTreeHostTestLCDNotification
: public LayerTreeHostTest
{
2105 class NotificationClient
: public ContentLayerClient
{
2107 NotificationClient()
2108 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2110 void set_layer(Layer
* layer
) { layer_
= layer
; }
2111 int paint_count() const { return paint_count_
; }
2112 int lcd_notification_count() const { return lcd_notification_count_
; }
2114 virtual void PaintContents(SkCanvas
* canvas
,
2116 gfx::RectF
* opaque
) OVERRIDE
{
2119 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{
2120 ++lcd_notification_count_
;
2121 layer_
->SetNeedsDisplay();
2127 int lcd_notification_count_
;
2130 virtual void SetupTree() OVERRIDE
{
2131 scoped_refptr
<ContentLayer
> root_layer
= ContentLayer::Create(&client_
);
2132 root_layer
->SetIsDrawable(true);
2133 root_layer
->SetBounds(gfx::Size(1, 1));
2135 layer_tree_host()->SetRootLayer(root_layer
);
2136 client_
.set_layer(root_layer
.get());
2138 // The expecations are based on the assumption that the default
2139 // LCD settings are:
2140 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text
);
2141 EXPECT_FALSE(root_layer
->can_use_lcd_text());
2143 LayerTreeHostTest::SetupTree();
2146 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
2147 virtual void AfterTest() OVERRIDE
{}
2149 virtual void DidCommit() OVERRIDE
{
2150 switch (layer_tree_host()->commit_number()) {
2152 // The first update consists one LCD notification and one paint.
2153 EXPECT_EQ(1, client_
.lcd_notification_count());
2154 EXPECT_EQ(1, client_
.paint_count());
2155 // LCD text must have been enabled on the layer.
2156 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2157 PostSetNeedsCommitToMainThread();
2160 // Since nothing changed on layer, there should be no notification
2161 // or paint on the second update.
2162 EXPECT_EQ(1, client_
.lcd_notification_count());
2163 EXPECT_EQ(1, client_
.paint_count());
2164 // LCD text must not have changed.
2165 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2166 // Change layer opacity that should trigger lcd notification.
2167 layer_tree_host()->root_layer()->SetOpacity(.5f
);
2168 // No need to request a commit - setting opacity will do it.
2171 // Verify that there is not extra commit due to layer invalidation.
2172 EXPECT_EQ(3, layer_tree_host()->commit_number());
2173 // LCD notification count should have incremented due to
2174 // change in layer opacity.
2175 EXPECT_EQ(2, client_
.lcd_notification_count());
2176 // Paint count should be incremented due to invalidation.
2177 EXPECT_EQ(2, client_
.paint_count());
2178 // LCD text must have been disabled on the layer due to opacity.
2179 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2186 NotificationClient client_
;
2189 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification
);
2191 // Verify that the vsync notification is used to initiate rendering.
2192 class LayerTreeHostTestVSyncNotification
: public LayerTreeHostTest
{
2194 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2195 settings
->render_vsync_notification_enabled
= true;
2198 virtual void BeginTest() OVERRIDE
{
2199 PostSetNeedsCommitToMainThread();
2202 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2203 FakeOutputSurface
* fake_output_surface
=
2204 reinterpret_cast<FakeOutputSurface
*>(host_impl
->output_surface());
2206 // The vsync notification is turned off now but will get enabled once we
2207 // return, so post a task to trigger it.
2208 ASSERT_FALSE(fake_output_surface
->vsync_notification_enabled());
2209 PostVSyncOnImplThread(fake_output_surface
);
2212 void PostVSyncOnImplThread(FakeOutputSurface
* fake_output_surface
) {
2213 DCHECK(ImplThread());
2214 ImplThread()->PostTask(
2215 base::Bind(&LayerTreeHostTestVSyncNotification::DidVSync
,
2216 base::Unretained(this),
2217 base::Unretained(fake_output_surface
)));
2220 void DidVSync(FakeOutputSurface
* fake_output_surface
) {
2221 ASSERT_TRUE(fake_output_surface
->vsync_notification_enabled());
2222 fake_output_surface
->DidVSync(frame_time_
);
2225 virtual bool PrepareToDrawOnThread(
2226 LayerTreeHostImpl
* host_impl
,
2227 LayerTreeHostImpl::FrameData
* frame
,
2228 bool result
) OVERRIDE
{
2233 virtual void AfterTest() OVERRIDE
{
2237 base::TimeTicks frame_time_
;
2240 MULTI_THREAD_TEST_F(LayerTreeHostTestVSyncNotification
);
2242 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2243 : public LayerTreeHostTest
{
2245 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2246 settings
->impl_side_painting
= true;
2249 virtual void SetupTree() OVERRIDE
{
2250 LayerTreeHostTest::SetupTree();
2252 scoped_refptr
<Layer
> layer
= PictureLayer::Create(&client_
);
2253 layer
->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2254 layer
->SetBounds(gfx::Size(10, 10));
2255 layer_tree_host()->root_layer()->AddChild(layer
);
2258 virtual void BeginTest() OVERRIDE
{
2259 PostSetNeedsCommitToMainThread();
2262 virtual void TreeActivatedOnThread(LayerTreeHostImpl
* host_impl
) {
2266 virtual void AfterTest() OVERRIDE
{
2269 FakeContentLayerClient client_
;
2272 MULTI_THREAD_TEST_F(
2273 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
);
2275 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2276 : public LayerTreeHostTest
{
2278 class SetBoundsClient
: public ContentLayerClient
{
2280 SetBoundsClient() : layer_(0) {}
2282 void set_layer(Layer
* layer
) { layer_
= layer
; }
2284 virtual void PaintContents(SkCanvas
* canvas
,
2286 gfx::RectF
* opaque
) OVERRIDE
{
2287 layer_
->SetBounds(gfx::Size(2, 2));
2290 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
2296 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2298 virtual void SetupTree() OVERRIDE
{
2299 scoped_refptr
<ContentLayer
> root_layer
= ContentLayer::Create(&client_
);
2300 root_layer
->SetIsDrawable(true);
2301 root_layer
->SetBounds(gfx::Size(1, 1));
2303 layer_tree_host()->SetRootLayer(root_layer
);
2304 client_
.set_layer(root_layer
.get());
2306 LayerTreeHostTest::SetupTree();
2309 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
2310 virtual void AfterTest() OVERRIDE
{}
2312 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2314 if (num_commits_
== 1) {
2315 LayerImpl
* root_layer
= host_impl
->active_tree()->root_layer();
2316 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer
->bounds());
2318 LayerImpl
* root_layer
= host_impl
->active_tree()->root_layer();
2319 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer
->bounds());
2325 SetBoundsClient client_
;
2329 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents
);