Fix build break
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blobedf6722a07d8b7bddd8de1295148d541c0f956d2
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"
7 #include <algorithm>
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"
44 namespace cc {
45 namespace {
47 class LayerTreeHostTest : public LayerTreeTest {
50 // Test interleaving of redraws and commits
51 class LayerTreeHostTestCommitingWithContinuousRedraw
52 : public LayerTreeHostTest {
53 public:
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)
62 EndTest();
65 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
66 if (num_draws_ == 1)
67 PostSetNeedsCommitToMainThread();
68 num_draws_++;
69 PostSetNeedsRedrawToMainThread();
72 virtual void AfterTest() OVERRIDE {}
74 private:
75 int num_complete_commits_;
76 int num_draws_;
79 MULTI_THREAD_TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw);
81 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
82 // draw with frame 0.
83 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
84 public:
85 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
87 virtual void BeginTest() OVERRIDE {
88 PostSetNeedsCommitToMainThread();
89 PostSetNeedsCommitToMainThread();
92 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
93 num_draws_++;
94 if (!impl->active_tree()->source_frame_number())
95 EndTest();
98 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
99 num_commits_++;
102 virtual void AfterTest() OVERRIDE {
103 EXPECT_GE(1, num_commits_);
104 EXPECT_GE(1, num_draws_);
107 private:
108 int num_commits_;
109 int 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 {
117 public:
118 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
120 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
122 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
123 ++num_draws_;
126 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
127 ++num_commits_;
128 if (impl->active_tree()->source_frame_number() == 0)
129 PostSetNeedsCommitToMainThread();
130 else if (impl->active_tree()->source_frame_number() == 1)
131 EndTest();
134 virtual void AfterTest() OVERRIDE {
135 EXPECT_EQ(2, num_commits_);
136 EXPECT_LE(1, num_draws_);
139 private:
140 int num_commits_;
141 int num_draws_;
144 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
146 // 1 setNeedsRedraw after the first commit has completed should lead to 1
147 // additional draw.
148 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
149 public:
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());
156 if (!num_draws_) {
157 // Redraw again to verify that the second redraw doesn't commit.
158 PostSetNeedsRedrawToMainThread();
159 } else {
160 EndTest();
162 num_draws_++;
165 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
166 EXPECT_EQ(0, num_draws_);
167 num_commits_++;
170 virtual void AfterTest() OVERRIDE {
171 EXPECT_GE(2, num_draws_);
172 EXPECT_EQ(1, num_commits_);
175 private:
176 int num_commits_;
177 int num_draws_;
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 {
185 public:
186 LayerTreeHostTestSetNeedsRedrawRect()
187 : num_draws_(0),
188 bounds_(50, 50),
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 {
204 EXPECT_TRUE(result);
206 gfx::RectF root_damage_rect;
207 if (!frame_data->render_passes.empty())
208 root_damage_rect = frame_data->render_passes.back()->damage_rect;
210 if (!num_draws_) {
211 // If this is the first frame, expect full frame damage.
212 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
213 } else {
214 // Check that invalid_rect_ is indeed repainted.
215 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
218 return result;
221 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
222 if (!num_draws_) {
223 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
224 } else {
225 EndTest();
227 num_draws_++;
230 virtual void AfterTest() OVERRIDE {
231 EXPECT_EQ(2, num_draws_);
234 private:
235 int 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 {
245 public:
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()) {
259 case 1:
260 // Changing the content bounds will cause a single commit!
261 root_layer_->SetRasterScale(4.f);
262 break;
263 default:
264 // No extra commits.
265 EXPECT_EQ(2, layer_tree_host()->commit_number());
266 EndTest();
270 virtual void AfterTest() OVERRIDE {}
272 private:
273 FakeContentLayerClient client_;
274 scoped_refptr<ContentLayer> root_layer_;
277 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
279 class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
280 public:
281 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
283 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
285 virtual void DidCommit() OVERRIDE {
286 num_commits_++;
287 if (num_commits_ == 1) {
288 char pixels[4];
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) {
293 EndTest();
294 } else {
295 NOTREACHED();
299 virtual void AfterTest() OVERRIDE {}
301 private:
302 int num_commits_;
305 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
307 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
308 : public LayerTreeHostTest {
309 public:
310 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
311 : num_commits_(0) {}
313 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
315 virtual void DidCommit() OVERRIDE {
316 num_commits_++;
317 if (num_commits_ == 1) {
318 layer_tree_host()->SetNeedsCommit();
319 } else if (num_commits_ == 2) {
320 char pixels[4];
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) {
325 EndTest();
326 } else {
327 NOTREACHED();
331 virtual void AfterTest() OVERRIDE {}
333 private:
334 int num_commits_;
337 MULTI_THREAD_TEST_F(
338 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
340 // If the layerTreeHost says it can't draw, Then we should not try to draw.
341 class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
342 public:
343 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
345 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
347 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
348 if (done_)
349 return;
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 {
356 if (done_)
357 return;
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 {
365 num_commits_++;
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) {
370 char pixels[4];
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));
375 done_ = true;
376 EndTest();
380 virtual void AfterTest() OVERRIDE {}
382 private:
383 int num_commits_;
384 bool done_;
387 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
389 // beginLayerWrite should prevent draws from executing until a commit occurs
390 class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
391 public:
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 {
401 num_draws_++;
402 EXPECT_EQ(num_draws_, num_commits_);
405 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
406 num_commits_++;
407 EndTest();
410 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
412 private:
413 int num_commits_;
414 int num_draws_;
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 {
425 public:
426 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
428 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
430 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
431 num_commits_++;
432 if (num_commits_ == 2)
433 EndTest();
434 else if (num_commits_ < 2) {
435 PostSetVisibleToMainThread(false);
436 PostSetVisibleToMainThread(true);
437 PostAcquireLayerTextures();
438 PostSetNeedsCommitToMainThread();
442 virtual void AfterTest() OVERRIDE {}
444 private:
445 int num_commits_;
448 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
450 // A compositeAndReadback while invisible should force a normal commit without
451 // assertion.
452 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
453 : public LayerTreeHostTest {
454 public:
455 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
457 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
459 virtual void DidCommitAndDrawFrame() OVERRIDE {
460 num_commits_++;
461 if (num_commits_ == 1) {
462 layer_tree_host()->SetVisible(false);
463 layer_tree_host()->SetNeedsCommit();
464 layer_tree_host()->SetNeedsCommit();
465 char pixels[4];
466 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
467 } else {
468 EndTest();
472 virtual void AfterTest() OVERRIDE {}
474 private:
475 int num_commits_;
478 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
480 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
481 public:
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 {
496 ASSERT_FALSE(true);
497 EndTest();
500 virtual void AfterTest() OVERRIDE {}
502 private:
505 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
507 // This test verifies that properties on the layer tree host are commited
508 // to the impl side.
509 class LayerTreeHostTestCommit : public LayerTreeHostTest {
510 public:
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());
526 EndTest();
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 {
537 public:
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)
551 OVERRIDE {
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());
563 EndTest();
564 } else {
565 PostSetNeedsRedrawToMainThread();
569 virtual void AfterTest() OVERRIDE {}
572 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
574 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
575 public:
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());
589 ++num_draws_;
590 EndTest();
593 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
595 private:
596 int num_draws_;
599 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
601 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
602 public:
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.
609 if (test_layer_)
610 test_layer_->SetOpacity(0.f);
612 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
614 private:
615 Layer* test_layer_;
618 class ContentLayerWithUpdateTracking : public ContentLayer {
619 public:
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_++;
635 private:
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));
640 SetIsDrawable(true);
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 {
650 public:
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 {
666 EndTest();
669 virtual void AfterTest() OVERRIDE {
670 // Update() should have been called once.
671 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
674 private:
675 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
676 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
679 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
681 class NoScaleContentLayer : public ContentLayer {
682 public:
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,
695 contents_scale_x,
696 contents_scale_y,
697 contentBounds);
700 private:
701 explicit NoScaleContentLayer(ContentLayerClient* client)
702 : ContentLayer(client) {}
703 virtual ~NoScaleContentLayer() {}
706 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
707 : public LayerTreeHostTest {
708 public:
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());
800 EndTest();
803 virtual void AfterTest() OVERRIDE {}
805 private:
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 {
815 public:
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;
829 scrollbar_ =
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()) {
849 case 0:
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();
860 break;
861 case 1:
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();
877 break;
878 case 2:
879 EndTest();
880 break;
881 default:
882 NOTREACHED();
883 break;
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 {}
903 private:
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,
912 Layer* parent,
913 const gfx::Transform& transform,
914 gfx::PointF anchor,
915 gfx::PointF position,
916 gfx::Size bounds,
917 bool opaque) {
918 layer->RemoveAllChildren();
919 if (parent)
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 {
930 public:
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()) {
978 case 0:
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();
991 break;
992 case 1:
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();
1013 break;
1014 case 2:
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();
1032 break;
1033 case 3:
1034 // No textures should be used for commit.
1035 EXPECT_EQ(0u, context->NumUsedTextures());
1037 context->ResetUsedTextures();
1038 PostSetNeedsCommitToMainThread();
1039 break;
1040 case 4:
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();
1048 break;
1049 case 5:
1050 EndTest();
1051 break;
1052 default:
1053 NOTREACHED();
1054 break;
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());
1066 else
1067 EXPECT_EQ(4u, context->NumUsedTextures());
1069 context->ResetUsedTextures();
1072 virtual void Layout() OVERRIDE {
1073 switch (num_commits_++) {
1074 case 0:
1075 case 1:
1076 parent_->SetNeedsDisplay();
1077 child_->SetNeedsDisplay();
1078 scrollbar_with_paints_->SetNeedsDisplay();
1079 scrollbar_without_paints_->SetNeedsDisplay();
1080 break;
1081 case 2:
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));
1089 break;
1090 case 3:
1091 child_->SetNeedsDisplay();
1092 scrollbar_with_paints_->SetNeedsDisplay();
1093 scrollbar_without_paints_->SetNeedsDisplay();
1094 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1095 break;
1096 case 4:
1097 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1098 break;
1099 case 5:
1100 break;
1101 default:
1102 NOTREACHED();
1103 break;
1107 virtual void AfterTest() OVERRIDE {}
1109 private:
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_;
1115 int num_commits_;
1118 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate);
1120 class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1121 public:
1122 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1124 virtual void BeginTest() OVERRIDE {
1125 layer_tree_host()->SetNeedsRedraw();
1126 PostSetNeedsCommitToMainThread();
1129 virtual void DidCommitAndDrawFrame() OVERRIDE {
1130 if (once_)
1131 return;
1132 once_ = true;
1133 layer_tree_host()->SetNeedsRedraw();
1134 layer_tree_host()->AcquireLayerTextures();
1136 base::AutoLock lock(lock_);
1137 draw_count_ = 0;
1139 layer_tree_host()->FinishAllRendering();
1141 base::AutoLock lock(lock_);
1142 EXPECT_EQ(0, draw_count_);
1144 EndTest();
1147 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1148 base::AutoLock lock(lock_);
1149 ++draw_count_;
1152 virtual void AfterTest() OVERRIDE {}
1154 private:
1155 bool once_;
1156 base::Lock lock_;
1157 int draw_count_;
1160 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
1162 class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1163 public:
1164 LayerTreeHostTestCompositeAndReadbackCleanup() {}
1166 virtual void BeginTest() OVERRIDE {
1167 Layer* root_layer = layer_tree_host()->root_layer();
1169 char pixels[4];
1170 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1171 gfx::Rect(0, 0, 1, 1));
1172 EXPECT_FALSE(root_layer->render_surface());
1174 EndTest();
1177 virtual void AfterTest() OVERRIDE {}
1180 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1182 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1183 : public LayerTreeHostTest {
1184 public:
1185 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
1186 : root_layer_(FakeContentLayer::Create(&client_)),
1187 surface_layer1_(
1188 FakeContentLayer::Create(&client_)),
1189 replica_layer1_(
1190 FakeContentLayer::Create(&client_)),
1191 surface_layer2_(
1192 FakeContentLayer::Create(&client_)),
1193 replica_layer2_(
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()) {
1230 case 0:
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));
1241 break;
1242 case 1:
1243 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1244 surface1_render_pass_id));
1245 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1246 surface2_render_pass_id));
1248 EndTest();
1249 break;
1253 virtual void DidCommitAndDrawFrame() OVERRIDE {
1254 if (!TestEnded())
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());
1264 private:
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 {
1277 public:
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)
1288 OVERRIDE;
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;
1296 private:
1297 EvictionTestLayer() : Layer() {}
1298 virtual ~EvictionTestLayer() {}
1300 void CreateTextureIfNeeded() {
1301 if (texture_.get())
1302 return;
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_;
1310 SkBitmap bitmap_;
1313 class EvictionTestLayerImpl : public LayerImpl {
1314 public:
1315 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1316 int id) {
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; }
1329 private:
1330 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1331 : LayerImpl(tree_impl, id), has_texture_(false) {}
1333 bool has_texture_;
1336 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1337 CreateTextureIfNeeded();
1338 if (!texture_.get())
1339 return;
1340 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1343 void EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1344 const OcclusionTracker*,
1345 RenderingStats*) {
1346 CreateTextureIfNeeded();
1347 if (!texture_.get())
1348 return;
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 {
1371 public:
1372 LayerTreeHostTestEvictTextures()
1373 : layer_(EvictionTestLayer::Create()),
1374 impl_for_evict_textures_(0),
1375 num_commits_(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(),
1384 identity_matrix,
1385 gfx::PointF(0.f, 0.f),
1386 gfx::PointF(0.f, 0.f),
1387 gfx::Size(10, 20),
1388 true);
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
1409 // needsCommit.
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
1415 // needsCommit.
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
1427 // recovery path.
1428 virtual void DidCommit() OVERRIDE {
1429 switch (num_commits_) {
1430 case 1:
1431 EXPECT_TRUE(layer_->HaveBackingTexture());
1432 PostEvictTextures();
1433 break;
1434 case 2:
1435 EXPECT_TRUE(layer_->HaveBackingTexture());
1436 layer_tree_host()->SetNeedsCommit();
1437 break;
1438 case 3:
1439 break;
1440 case 4:
1441 EXPECT_TRUE(layer_->HaveBackingTexture());
1442 layer_tree_host()->SetNeedsCommit();
1443 break;
1444 case 5:
1445 break;
1446 case 6:
1447 EXPECT_TRUE(layer_->HaveBackingTexture());
1448 EndTest();
1449 break;
1450 default:
1451 NOTREACHED();
1452 break;
1456 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1457 impl_for_evict_textures_ = impl;
1460 virtual void Layout() OVERRIDE {
1461 ++num_commits_;
1462 switch (num_commits_) {
1463 case 1:
1464 case 2:
1465 break;
1466 case 3:
1467 PostEvictTextures();
1468 break;
1469 case 4:
1470 // We couldn't check in didCommitAndDrawFrame on commit 3,
1471 // so check here.
1472 EXPECT_FALSE(layer_->HaveBackingTexture());
1473 break;
1474 case 5:
1475 PostEvictTextures();
1476 break;
1477 case 6:
1478 // We couldn't check in didCommitAndDrawFrame on commit 5,
1479 // so check here.
1480 EXPECT_FALSE(layer_->HaveBackingTexture());
1481 PostEvictTextures();
1482 break;
1483 default:
1484 NOTREACHED();
1485 break;
1489 virtual void AfterTest() OVERRIDE {}
1491 private:
1492 FakeContentLayerClient client_;
1493 scoped_refptr<EvictionTestLayer> layer_;
1494 LayerTreeHostImpl* impl_for_evict_textures_;
1495 int num_commits_;
1498 MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures);
1500 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
1501 public:
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)
1514 return;
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 {
1524 num_draw_layers_++;
1525 if (num_draw_layers_ == 2)
1526 EndTest();
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_);
1534 private:
1535 int num_commit_complete_;
1536 int num_draw_layers_;
1539 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
1541 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1542 public:
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)
1562 return;
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 {
1572 num_draw_layers_++;
1573 if (num_draw_layers_ == 2)
1574 EndTest();
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_);
1582 private:
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 {
1592 public:
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_) {
1606 case 1:
1607 EXPECT_EQ(0, num_commits_deferred_);
1608 layer_tree_host()->SetDeferCommits(true);
1609 PostSetNeedsCommitToMainThread();
1610 break;
1611 case 2:
1612 EndTest();
1613 break;
1614 default:
1615 NOTREACHED();
1616 break;
1620 virtual void AfterTest() OVERRIDE {
1621 EXPECT_EQ(1, num_commits_deferred_);
1622 EXPECT_EQ(2, num_complete_commits_);
1625 private:
1626 int num_commits_deferred_;
1627 int num_complete_commits_;
1630 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1632 class LayerTreeHostWithProxy : public LayerTreeHost {
1633 public:
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 {
1750 public:
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 {
1760 public:
1761 virtual void PaintContents(SkCanvas* canvas,
1762 gfx::Rect clip,
1763 gfx::RectF* opaque) OVERRIDE {
1764 SkPaint paint;
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();
1789 EndTest();
1792 virtual void AfterTest() OVERRIDE {
1793 EXPECT_EQ(bounds_, gfx::Size(picture_->width(), picture_->height()));
1795 SkBitmap bitmap;
1796 bitmap.setConfig(
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();
1810 private:
1811 gfx::Size bounds_;
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 {
1820 public:
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());
1837 } else {
1838 EXPECT_EQ(FrameRateController::DEFAULT_MAX_FRAMES_PENDING,
1839 proxy->MaxFramesPendingForTesting());
1841 EndTest();
1844 virtual void AfterTest() OVERRIDE {}
1846 protected:
1847 bool delegating_renderer_;
1850 TEST_F(LayerTreeHostTestMaxPendingFrames, DelegatingRenderer) {
1851 delegating_renderer_ = true;
1852 RunTest(true);
1855 TEST_F(LayerTreeHostTestMaxPendingFrames, GLRenderer) {
1856 delegating_renderer_ = false;
1857 RunTest(true);
1860 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
1861 : public LayerTreeHostTest {
1862 public:
1863 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
1864 : root_layer_(FakeContentLayer::Create(&client_)),
1865 child_layer1_(FakeContentLayer::Create(&client_)),
1866 child_layer2_(FakeContentLayer::Create(&client_)),
1867 num_commits_(0) {}
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
1886 // purged.
1887 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
1888 // End the test in this state.
1889 EndTest();
1892 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1893 ++num_commits_;
1894 switch (num_commits_) {
1895 case 1:
1896 // All three backings should have memory.
1897 EXPECT_EQ(
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,
1905 100 * 100 * 4 * 1,
1906 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING));
1907 break;
1908 case 2:
1909 // Only two backings should have memory.
1910 EXPECT_EQ(
1911 100u * 100u * 4u * 2u,
1912 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1913 // Become backgrounded, which will cause 1 more resource to be
1914 // evicted.
1915 PostSetVisibleToMainThread(false);
1916 break;
1917 default:
1918 // No further commits should happen because this is not visible
1919 // anymore.
1920 NOTREACHED();
1921 break;
1925 virtual void AfterTest() OVERRIDE {}
1927 private:
1928 FakeContentLayerClient client_;
1929 scoped_refptr<FakeContentLayer> root_layer_;
1930 scoped_refptr<FakeContentLayer> child_layer1_;
1931 scoped_refptr<FakeContentLayer> child_layer2_;
1932 int num_commits_;
1935 SINGLE_AND_MULTI_THREAD_TEST_F(
1936 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
1938 class LayerTreeHostTestPinchZoomScrollbarCreation : public LayerTreeHostTest {
1939 public:
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());
1975 EndTest();
1978 virtual void AfterTest() OVERRIDE {}
1980 private:
1981 FakeContentLayerClient client_;
1982 scoped_refptr<ContentLayer> root_layer_;
1985 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarCreation);
1987 class LayerTreeHostTestPinchZoomScrollbarResize : public LayerTreeHostTest {
1988 public:
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 {
2005 num_commits_++;
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_) {
2023 case 1:
2024 // Resizing the viewport should also resize the pinch-zoom scrollbars.
2025 layer_tree_host()->SetViewportSize(gfx::Size(120, 150));
2026 break;
2027 default:
2028 EndTest();
2032 virtual void AfterTest() OVERRIDE {}
2034 private:
2035 FakeContentLayerClient client_;
2036 scoped_refptr<ContentLayer> root_layer_;
2037 int num_commits_;
2040 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarResize);
2042 class LayerTreeHostTestPinchZoomScrollbarNewRootLayer
2043 : public LayerTreeHostTest {
2044 public:
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 {
2060 num_commits_++;
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();
2088 } else {
2089 EndTest();
2093 virtual void AfterTest() OVERRIDE {}
2095 private:
2096 FakeContentLayerClient client_;
2097 scoped_refptr<ContentLayer> root_layer_;
2098 int num_commits_;
2101 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarNewRootLayer);
2103 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2104 public:
2105 class NotificationClient : public ContentLayerClient {
2106 public:
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,
2115 gfx::Rect clip,
2116 gfx::RectF* opaque) OVERRIDE {
2117 ++paint_count_;
2119 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2120 ++lcd_notification_count_;
2121 layer_->SetNeedsDisplay();
2124 private:
2125 Layer* layer_;
2126 int paint_count_;
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()) {
2151 case 1:
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();
2158 break;
2159 case 2:
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.
2169 break;
2170 default:
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());
2180 EndTest();
2181 break;
2185 private:
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 {
2193 public:
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 {
2229 EndTest();
2230 return true;
2233 virtual void AfterTest() OVERRIDE {
2236 private:
2237 base::TimeTicks frame_time_;
2240 MULTI_THREAD_TEST_F(LayerTreeHostTestVSyncNotification);
2242 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2243 : public LayerTreeHostTest {
2244 protected:
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) {
2263 EndTest();
2266 virtual void AfterTest() OVERRIDE {
2269 FakeContentLayerClient client_;
2272 MULTI_THREAD_TEST_F(
2273 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2275 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2276 : public LayerTreeHostTest {
2277 public:
2278 class SetBoundsClient : public ContentLayerClient {
2279 public:
2280 SetBoundsClient() : layer_(0) {}
2282 void set_layer(Layer* layer) { layer_ = layer; }
2284 virtual void PaintContents(SkCanvas* canvas,
2285 gfx::Rect clip,
2286 gfx::RectF* opaque) OVERRIDE {
2287 layer_->SetBounds(gfx::Size(2, 2));
2290 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2292 private:
2293 Layer* layer_;
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 {
2313 num_commits_++;
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());
2317 } else {
2318 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2319 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2320 EndTest();
2324 private:
2325 SetBoundsClient client_;
2326 int num_commits_;
2329 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2331 } // namespace
2332 } // namespace cc