Fix revert "[chromeos] Remove dependencies of StatisticsProvider on chrome."
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest.cc
blob323bd30a428e813d53361710b086ad596c15b9d2
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/debug/frame_rate_counter.h"
12 #include "cc/layers/content_layer.h"
13 #include "cc/layers/content_layer_client.h"
14 #include "cc/layers/io_surface_layer.h"
15 #include "cc/layers/layer_impl.h"
16 #include "cc/layers/picture_layer.h"
17 #include "cc/layers/scrollbar_layer.h"
18 #include "cc/output/output_surface.h"
19 #include "cc/resources/prioritized_resource.h"
20 #include "cc/resources/prioritized_resource_manager.h"
21 #include "cc/resources/resource_update_queue.h"
22 #include "cc/scheduler/frame_rate_controller.h"
23 #include "cc/test/fake_content_layer.h"
24 #include "cc/test/fake_content_layer_client.h"
25 #include "cc/test/fake_layer_tree_host_client.h"
26 #include "cc/test/fake_output_surface.h"
27 #include "cc/test/fake_proxy.h"
28 #include "cc/test/fake_scrollbar_layer.h"
29 #include "cc/test/geometry_test_utils.h"
30 #include "cc/test/layer_tree_test.h"
31 #include "cc/test/occlusion_tracker_test_common.h"
32 #include "cc/trees/layer_tree_host_impl.h"
33 #include "cc/trees/layer_tree_impl.h"
34 #include "cc/trees/single_thread_proxy.h"
35 #include "cc/trees/thread_proxy.h"
36 #include "gpu/GLES2/gl2extchromium.h"
37 #include "skia/ext/refptr.h"
38 #include "testing/gmock/include/gmock/gmock.h"
39 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
40 #include "third_party/khronos/GLES2/gl2.h"
41 #include "third_party/khronos/GLES2/gl2ext.h"
42 #include "third_party/skia/include/core/SkPicture.h"
43 #include "ui/gfx/point_conversions.h"
44 #include "ui/gfx/size_conversions.h"
45 #include "ui/gfx/vector2d_conversions.h"
47 using testing::_;
48 using testing::AnyNumber;
49 using testing::AtLeast;
50 using testing::Mock;
52 namespace cc {
53 namespace {
55 class LayerTreeHostTest : public LayerTreeTest {
58 // Test interleaving of redraws and commits
59 class LayerTreeHostTestCommitingWithContinuousRedraw
60 : public LayerTreeHostTest {
61 public:
62 LayerTreeHostTestCommitingWithContinuousRedraw()
63 : num_complete_commits_(0), num_draws_(0) {}
65 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
67 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
68 num_complete_commits_++;
69 if (num_complete_commits_ == 2)
70 EndTest();
73 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
74 if (num_draws_ == 1)
75 PostSetNeedsCommitToMainThread();
76 num_draws_++;
77 PostSetNeedsRedrawToMainThread();
80 virtual void AfterTest() OVERRIDE {}
82 private:
83 int num_complete_commits_;
84 int num_draws_;
87 MULTI_THREAD_TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw);
89 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
90 // draw with frame 0.
91 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
92 public:
93 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
95 virtual void BeginTest() OVERRIDE {
96 PostSetNeedsCommitToMainThread();
97 PostSetNeedsCommitToMainThread();
100 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
101 num_draws_++;
102 if (!impl->active_tree()->source_frame_number())
103 EndTest();
106 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
107 num_commits_++;
110 virtual void AfterTest() OVERRIDE {
111 EXPECT_GE(1, num_commits_);
112 EXPECT_GE(1, num_draws_);
115 private:
116 int num_commits_;
117 int num_draws_;
120 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
122 // A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
123 // first committed frame draws should lead to another commit.
124 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
125 public:
126 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
128 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
130 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
131 ++num_draws_;
134 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
135 ++num_commits_;
136 if (impl->active_tree()->source_frame_number() == 0)
137 PostSetNeedsCommitToMainThread();
138 else if (impl->active_tree()->source_frame_number() == 1)
139 EndTest();
142 virtual void AfterTest() OVERRIDE {
143 EXPECT_EQ(2, num_commits_);
144 EXPECT_LE(1, num_draws_);
147 private:
148 int num_commits_;
149 int num_draws_;
152 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
154 // 1 setNeedsRedraw after the first commit has completed should lead to 1
155 // additional draw.
156 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
157 public:
158 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
160 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
162 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
163 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
164 if (!num_draws_) {
165 // Redraw again to verify that the second redraw doesn't commit.
166 PostSetNeedsRedrawToMainThread();
167 } else {
168 EndTest();
170 num_draws_++;
173 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
174 EXPECT_EQ(0, num_draws_);
175 num_commits_++;
178 virtual void AfterTest() OVERRIDE {
179 EXPECT_GE(2, num_draws_);
180 EXPECT_EQ(1, num_commits_);
183 private:
184 int num_commits_;
185 int num_draws_;
188 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
190 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
191 // must contain invalid_rect.
192 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
193 public:
194 LayerTreeHostTestSetNeedsRedrawRect()
195 : num_draws_(0),
196 bounds_(50, 50),
197 invalid_rect_(10, 10, 20, 20),
198 root_layer_(ContentLayer::Create(&client_)) {
201 virtual void BeginTest() OVERRIDE {
202 root_layer_->SetIsDrawable(true);
203 root_layer_->SetBounds(bounds_);
204 layer_tree_host()->SetRootLayer(root_layer_);
205 layer_tree_host()->SetViewportSize(bounds_);
206 PostSetNeedsCommitToMainThread();
209 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
210 LayerTreeHostImpl::FrameData* frame_data,
211 bool result) OVERRIDE {
212 EXPECT_TRUE(result);
214 gfx::RectF root_damage_rect;
215 if (!frame_data->render_passes.empty())
216 root_damage_rect = frame_data->render_passes.back()->damage_rect;
218 if (!num_draws_) {
219 // If this is the first frame, expect full frame damage.
220 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
221 } else {
222 // Check that invalid_rect_ is indeed repainted.
223 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
226 return result;
229 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
230 if (!num_draws_) {
231 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
232 } else {
233 EndTest();
235 num_draws_++;
238 virtual void AfterTest() OVERRIDE {
239 EXPECT_EQ(2, num_draws_);
242 private:
243 int num_draws_;
244 const gfx::Size bounds_;
245 const gfx::Rect invalid_rect_;
246 FakeContentLayerClient client_;
247 scoped_refptr<ContentLayer> root_layer_;
250 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
252 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
253 public:
254 LayerTreeHostTestNoExtraCommitFromInvalidate()
255 : root_layer_(ContentLayer::Create(&client_)) {}
257 virtual void BeginTest() OVERRIDE {
258 root_layer_->SetAutomaticallyComputeRasterScale(false);
259 root_layer_->SetIsDrawable(true);
260 root_layer_->SetBounds(gfx::Size(1, 1));
261 layer_tree_host()->SetRootLayer(root_layer_);
262 PostSetNeedsCommitToMainThread();
265 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
266 if (host_impl->active_tree()->source_frame_number() == 1)
267 EndTest();
270 virtual void DidCommit() OVERRIDE {
271 switch (layer_tree_host()->commit_number()) {
272 case 1:
273 // Changing the content bounds will cause a single commit!
274 root_layer_->SetRasterScale(4.f);
275 break;
276 default:
277 // No extra commits.
278 EXPECT_EQ(2, layer_tree_host()->commit_number());
282 virtual void AfterTest() OVERRIDE {}
284 private:
285 FakeContentLayerClient client_;
286 scoped_refptr<ContentLayer> root_layer_;
289 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
291 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
292 : public LayerTreeHostTest {
293 public:
294 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate()
295 : root_layer_(FakeContentLayer::Create(&client_)) {}
297 virtual void SetupTree() OVERRIDE {
298 root_layer_->SetBounds(gfx::Size(10, 20));
300 bool paint_scrollbar = true;
301 bool has_thumb = false;
302 scrollbar_ = FakeScrollbarLayer::Create(paint_scrollbar,
303 has_thumb,
304 root_layer_->id());
305 scrollbar_->SetPosition(gfx::Point(0, 10));
306 scrollbar_->SetBounds(gfx::Size(10, 10));
308 root_layer_->AddChild(scrollbar_);
310 layer_tree_host()->SetRootLayer(root_layer_);
311 LayerTreeHostTest::SetupTree();
314 virtual void BeginTest() OVERRIDE {
315 PostSetNeedsCommitToMainThread();
318 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
319 if (host_impl->active_tree()->source_frame_number() == 1)
320 EndTest();
323 virtual void DidCommit() OVERRIDE {
324 switch (layer_tree_host()->commit_number()) {
325 case 1:
326 // This should cause a single commit.
327 scrollbar_->SetRasterScale(4.0f);
328 break;
329 default:
330 // No extra commits.
331 EXPECT_EQ(2, layer_tree_host()->commit_number());
335 virtual void AfterTest() OVERRIDE {}
337 private:
338 FakeContentLayerClient client_;
339 scoped_refptr<FakeContentLayer> root_layer_;
340 scoped_refptr<FakeScrollbarLayer> scrollbar_;
343 SINGLE_AND_MULTI_THREAD_TEST_F(
344 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
346 class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
347 public:
348 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
350 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
352 virtual void DidCommit() OVERRIDE {
353 num_commits_++;
354 if (num_commits_ == 1) {
355 char pixels[4];
356 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
357 } else if (num_commits_ == 2) {
358 // This is inside the readback. We should get another commit after it.
359 } else if (num_commits_ == 3) {
360 EndTest();
361 } else {
362 NOTREACHED();
366 virtual void AfterTest() OVERRIDE {}
368 private:
369 int num_commits_;
372 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
374 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
375 : public LayerTreeHostTest {
376 public:
377 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
378 : num_commits_(0) {}
380 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
382 virtual void DidCommit() OVERRIDE {
383 num_commits_++;
384 if (num_commits_ == 1) {
385 layer_tree_host()->SetNeedsCommit();
386 } else if (num_commits_ == 2) {
387 char pixels[4];
388 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
389 } else if (num_commits_ == 3) {
390 // This is inside the readback. We should get another commit after it.
391 } else if (num_commits_ == 4) {
392 EndTest();
393 } else {
394 NOTREACHED();
398 virtual void AfterTest() OVERRIDE {}
400 private:
401 int num_commits_;
404 MULTI_THREAD_TEST_F(
405 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
407 // If the layerTreeHost says it can't draw, Then we should not try to draw.
408 class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
409 public:
410 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
412 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
414 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
415 if (done_)
416 return;
417 // Only the initial draw should bring us here.
418 EXPECT_TRUE(impl->CanDraw());
419 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
422 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
423 if (done_)
424 return;
425 if (num_commits_ >= 1) {
426 // After the first commit, we should not be able to draw.
427 EXPECT_FALSE(impl->CanDraw());
431 virtual void DidCommit() OVERRIDE {
432 num_commits_++;
433 if (num_commits_ == 1) {
434 // Make the viewport empty so the host says it can't draw.
435 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
436 } else if (num_commits_ == 2) {
437 char pixels[4];
438 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
439 } else if (num_commits_ == 3) {
440 // Let it draw so we go idle and end the test.
441 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
442 done_ = true;
443 EndTest();
447 virtual void AfterTest() OVERRIDE {}
449 private:
450 int num_commits_;
451 bool done_;
454 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
456 // beginLayerWrite should prevent draws from executing until a commit occurs
457 class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
458 public:
459 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
461 virtual void BeginTest() OVERRIDE {
462 PostAcquireLayerTextures();
463 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
464 PostSetNeedsCommitToMainThread();
467 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
468 num_draws_++;
469 EXPECT_EQ(num_draws_, num_commits_);
472 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
473 num_commits_++;
474 EndTest();
477 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
479 private:
480 int num_commits_;
481 int num_draws_;
484 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
486 // Verify that when resuming visibility, Requesting layer write permission
487 // will not deadlock the main thread even though there are not yet any
488 // scheduled redraws. This behavior is critical for reliably surviving tab
489 // switching. There are no failure conditions to this test, it just passes
490 // by not timing out.
491 class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
492 public:
493 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
495 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
497 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
498 num_commits_++;
499 if (num_commits_ == 2)
500 EndTest();
501 else if (num_commits_ < 2) {
502 PostSetVisibleToMainThread(false);
503 PostSetVisibleToMainThread(true);
504 PostAcquireLayerTextures();
505 PostSetNeedsCommitToMainThread();
509 virtual void AfterTest() OVERRIDE {}
511 private:
512 int num_commits_;
515 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
517 // A compositeAndReadback while invisible should force a normal commit without
518 // assertion.
519 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
520 : public LayerTreeHostTest {
521 public:
522 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
524 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
526 virtual void DidCommitAndDrawFrame() OVERRIDE {
527 num_commits_++;
528 if (num_commits_ == 1) {
529 layer_tree_host()->SetVisible(false);
530 layer_tree_host()->SetNeedsCommit();
531 layer_tree_host()->SetNeedsCommit();
532 char pixels[4];
533 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
534 } else {
535 EndTest();
539 virtual void AfterTest() OVERRIDE {}
541 private:
542 int num_commits_;
545 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
547 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
548 public:
549 LayerTreeHostTestAbortFrameWhenInvisible() {}
551 virtual void BeginTest() OVERRIDE {
552 // Request a commit (from the main thread), Which will trigger the commit
553 // flow from the impl side.
554 layer_tree_host()->SetNeedsCommit();
555 // Then mark ourselves as not visible before processing any more messages
556 // on the main thread.
557 layer_tree_host()->SetVisible(false);
558 // If we make it without kicking a frame, we pass!
559 EndTestAfterDelay(1);
562 virtual void Layout() OVERRIDE {
563 ASSERT_FALSE(true);
564 EndTest();
567 virtual void AfterTest() OVERRIDE {}
569 private:
572 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
574 // This test verifies that properties on the layer tree host are commited
575 // to the impl side.
576 class LayerTreeHostTestCommit : public LayerTreeHostTest {
577 public:
578 LayerTreeHostTestCommit() {}
580 virtual void BeginTest() OVERRIDE {
581 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
582 layer_tree_host()->set_background_color(SK_ColorGRAY);
583 layer_tree_host()->SetPageScaleFactorAndLimits(5.f, 5.f, 5.f);
585 PostSetNeedsCommitToMainThread();
588 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
589 EXPECT_EQ(gfx::Size(20, 20), impl->device_viewport_size());
590 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
591 EXPECT_EQ(5.f, impl->active_tree()->page_scale_factor());
593 EndTest();
596 virtual void AfterTest() OVERRIDE {}
599 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
601 // Verifies that StartPageScaleAnimation events propagate correctly
602 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
603 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
604 public:
605 LayerTreeHostTestStartPageScaleAnimation() {}
607 virtual void BeginTest() OVERRIDE {
608 layer_tree_host()->root_layer()->SetScrollable(true);
609 layer_tree_host()->root_layer()->SetScrollOffset(gfx::Vector2d());
610 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
611 layer_tree_host()->StartPageScaleAnimation(
612 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
613 PostSetNeedsCommitToMainThread();
614 PostSetNeedsRedrawToMainThread();
617 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
618 OVERRIDE {
619 gfx::Vector2d offset = layer_tree_host()->root_layer()->scroll_offset();
620 layer_tree_host()->root_layer()->SetScrollOffset(offset + scroll_delta);
621 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
624 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
625 impl->ProcessScrollDeltas();
626 // We get one commit before the first draw, and the animation doesn't happen
627 // until the second draw.
628 if (impl->active_tree()->source_frame_number() == 1) {
629 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
630 EndTest();
631 } else {
632 PostSetNeedsRedrawToMainThread();
636 virtual void AfterTest() OVERRIDE {}
639 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
641 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
642 public:
643 LayerTreeHostTestSetVisible() : num_draws_(0) {}
645 virtual void BeginTest() OVERRIDE {
646 PostSetNeedsCommitToMainThread();
647 PostSetVisibleToMainThread(false);
648 // This is suppressed while we're invisible.
649 PostSetNeedsRedrawToMainThread();
650 // Triggers the redraw.
651 PostSetVisibleToMainThread(true);
654 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
655 EXPECT_TRUE(impl->visible());
656 ++num_draws_;
657 EndTest();
660 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
662 private:
663 int num_draws_;
666 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
668 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
669 public:
670 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
672 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
674 virtual void PaintContents(SkCanvas*, gfx::Rect, gfx::RectF*) OVERRIDE {
675 // Set layer opacity to 0.
676 if (test_layer_)
677 test_layer_->SetOpacity(0.f);
679 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
681 private:
682 Layer* test_layer_;
685 class ContentLayerWithUpdateTracking : public ContentLayer {
686 public:
687 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
688 ContentLayerClient* client) {
689 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
692 int PaintContentsCount() { return paint_contents_count_; }
693 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
695 virtual void Update(ResourceUpdateQueue* queue,
696 const OcclusionTracker* occlusion,
697 RenderingStats* stats) OVERRIDE {
698 ContentLayer::Update(queue, occlusion, stats);
699 paint_contents_count_++;
702 private:
703 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
704 : ContentLayer(client), paint_contents_count_(0) {
705 SetAnchorPoint(gfx::PointF(0.f, 0.f));
706 SetBounds(gfx::Size(10, 10));
707 SetIsDrawable(true);
709 virtual ~ContentLayerWithUpdateTracking() {}
711 int paint_contents_count_;
714 // Layer opacity change during paint should not prevent compositor resources
715 // from being updated during commit.
716 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
717 public:
718 LayerTreeHostTestOpacityChange()
719 : test_opacity_change_delegate_(),
720 update_check_layer_(ContentLayerWithUpdateTracking::Create(
721 &test_opacity_change_delegate_)) {
722 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
725 virtual void BeginTest() OVERRIDE {
726 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
727 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
729 PostSetNeedsCommitToMainThread();
732 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
733 EndTest();
736 virtual void AfterTest() OVERRIDE {
737 // Update() should have been called once.
738 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
741 private:
742 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
743 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
746 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
748 class NoScaleContentLayer : public ContentLayer {
749 public:
750 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
751 return make_scoped_refptr(new NoScaleContentLayer(client));
754 virtual void CalculateContentsScale(float ideal_contents_scale,
755 bool animating_transform_to_screen,
756 float* contents_scale_x,
757 float* contents_scale_y,
758 gfx::Size* contentBounds) OVERRIDE {
759 // Skip over the ContentLayer's method to the base Layer class.
760 Layer::CalculateContentsScale(ideal_contents_scale,
761 animating_transform_to_screen,
762 contents_scale_x,
763 contents_scale_y,
764 contentBounds);
767 private:
768 explicit NoScaleContentLayer(ContentLayerClient* client)
769 : ContentLayer(client) {}
770 virtual ~NoScaleContentLayer() {}
773 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
774 : public LayerTreeHostTest {
775 public:
776 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
777 : root_layer_(NoScaleContentLayer::Create(&client_)),
778 child_layer_(ContentLayer::Create(&client_)) {}
780 virtual void BeginTest() OVERRIDE {
781 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
782 layer_tree_host()->SetDeviceScaleFactor(1.5);
783 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
785 root_layer_->AddChild(child_layer_);
787 root_layer_->SetIsDrawable(true);
788 root_layer_->SetBounds(gfx::Size(30, 30));
789 root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
791 child_layer_->SetIsDrawable(true);
792 child_layer_->SetPosition(gfx::Point(2, 2));
793 child_layer_->SetBounds(gfx::Size(10, 10));
794 child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
796 layer_tree_host()->SetRootLayer(root_layer_);
798 PostSetNeedsCommitToMainThread();
801 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
802 // Should only do one commit.
803 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
804 // Device scale factor should come over to impl.
805 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
807 // Both layers are on impl.
808 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
810 // Device viewport is scaled.
811 EXPECT_EQ(gfx::Size(60, 60), impl->device_viewport_size());
813 LayerImpl* root = impl->active_tree()->root_layer();
814 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
816 // Positions remain in layout pixels.
817 EXPECT_EQ(gfx::Point(0, 0), root->position());
818 EXPECT_EQ(gfx::Point(2, 2), child->position());
820 // Compute all the layer transforms for the frame.
821 LayerTreeHostImpl::FrameData frame_data;
822 impl->PrepareToDraw(&frame_data, gfx::Rect());
823 impl->DidDrawAllLayers(frame_data);
825 const LayerImplList& render_surface_layer_list =
826 *frame_data.render_surface_layer_list;
828 // Both layers should be drawing into the root render surface.
829 ASSERT_EQ(1u, render_surface_layer_list.size());
830 ASSERT_EQ(root->render_surface(),
831 render_surface_layer_list[0]->render_surface());
832 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
834 // The root render surface is the size of the viewport.
835 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
836 root->render_surface()->content_rect());
838 // The content bounds of the child should be scaled.
839 gfx::Size child_bounds_scaled =
840 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
841 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
843 gfx::Transform scale_transform;
844 scale_transform.Scale(impl->device_scale_factor(),
845 impl->device_scale_factor());
847 // The root layer is scaled by 2x.
848 gfx::Transform root_screen_space_transform = scale_transform;
849 gfx::Transform root_draw_transform = scale_transform;
851 EXPECT_EQ(root_draw_transform, root->draw_transform());
852 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
854 // The child is at position 2,2, which is transformed to 3,3 after the scale
855 gfx::Transform child_screen_space_transform;
856 child_screen_space_transform.Translate(3.f, 3.f);
857 gfx::Transform child_draw_transform = child_screen_space_transform;
859 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
860 child->draw_transform());
861 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
862 child->screen_space_transform());
864 EndTest();
867 virtual void AfterTest() OVERRIDE {}
869 private:
870 FakeContentLayerClient client_;
871 scoped_refptr<NoScaleContentLayer> root_layer_;
872 scoped_refptr<ContentLayer> child_layer_;
875 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
877 // Verify atomicity of commits and reuse of textures.
878 class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest {
879 public:
880 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
881 // Make sure partial texture updates are turned off.
882 settings->max_partial_texture_updates = 0;
883 // Linear fade animator prevents scrollbars from drawing immediately.
884 settings->use_linear_fade_scrollbar_animator = false;
887 virtual void SetupTree() OVERRIDE {
888 layer_ = FakeContentLayer::Create(&client_);
889 layer_->SetBounds(gfx::Size(10, 20));
891 bool paint_scrollbar = true;
892 bool has_thumb = false;
893 scrollbar_ =
894 FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, layer_->id());
895 scrollbar_->SetPosition(gfx::Point(0, 10));
896 scrollbar_->SetBounds(gfx::Size(10, 10));
898 layer_->AddChild(scrollbar_);
900 layer_tree_host()->SetRootLayer(layer_);
901 LayerTreeHostTest::SetupTree();
904 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
906 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
907 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
909 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
910 impl->output_surface()->context3d());
912 switch (impl->active_tree()->source_frame_number()) {
913 case 0:
914 // Number of textures should be one for each layer
915 ASSERT_EQ(2u, context->NumTextures());
916 // Number of textures used for commit should be one for each layer.
917 EXPECT_EQ(2u, context->NumUsedTextures());
918 // Verify that used texture is correct.
919 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
920 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
922 context->ResetUsedTextures();
923 PostSetNeedsCommitToMainThread();
924 break;
925 case 1:
926 // Number of textures should be doubled as the first textures
927 // are used by impl thread and cannot by used for update.
928 ASSERT_EQ(4u, context->NumTextures());
929 // Number of textures used for commit should still be
930 // one for each layer.
931 EXPECT_EQ(2u, context->NumUsedTextures());
932 // First textures should not have been used.
933 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
934 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
935 // New textures should have been used.
936 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
937 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
939 context->ResetUsedTextures();
940 PostSetNeedsCommitToMainThread();
941 break;
942 case 2:
943 EndTest();
944 break;
945 default:
946 NOTREACHED();
947 break;
951 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
952 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
953 impl->output_surface()->context3d());
955 // Number of textures used for draw should always be one for each layer.
956 EXPECT_EQ(2u, context->NumUsedTextures());
957 context->ResetUsedTextures();
960 virtual void Layout() OVERRIDE {
961 layer_->SetNeedsDisplay();
962 scrollbar_->SetNeedsDisplay();
965 virtual void AfterTest() OVERRIDE {}
967 private:
968 FakeContentLayerClient client_;
969 scoped_refptr<FakeContentLayer> layer_;
970 scoped_refptr<FakeScrollbarLayer> scrollbar_;
973 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit);
975 static void SetLayerPropertiesForTesting(Layer* layer,
976 Layer* parent,
977 const gfx::Transform& transform,
978 gfx::PointF anchor,
979 gfx::PointF position,
980 gfx::Size bounds,
981 bool opaque) {
982 layer->RemoveAllChildren();
983 if (parent)
984 parent->AddChild(layer);
985 layer->SetTransform(transform);
986 layer->SetAnchorPoint(anchor);
987 layer->SetPosition(position);
988 layer->SetBounds(bounds);
989 layer->SetContentsOpaque(opaque);
992 class LayerTreeHostTestAtomicCommitWithPartialUpdate
993 : public LayerTreeHostTest {
994 public:
995 LayerTreeHostTestAtomicCommitWithPartialUpdate() : num_commits_(0) {}
997 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
998 // Allow one partial texture update.
999 settings->max_partial_texture_updates = 1;
1000 // Linear fade animator prevents scrollbars from drawing immediately.
1001 settings->use_linear_fade_scrollbar_animator = false;
1004 virtual void SetupTree() OVERRIDE {
1005 parent_ = FakeContentLayer::Create(&client_);
1006 parent_->SetBounds(gfx::Size(10, 20));
1008 child_ = FakeContentLayer::Create(&client_);
1009 child_->SetPosition(gfx::Point(0, 10));
1010 child_->SetBounds(gfx::Size(3, 10));
1012 bool paint_scrollbar = true;
1013 bool has_thumb = false;
1014 scrollbar_with_paints_ =
1015 FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, parent_->id());
1016 scrollbar_with_paints_->SetPosition(gfx::Point(3, 10));
1017 scrollbar_with_paints_->SetBounds(gfx::Size(3, 10));
1019 paint_scrollbar = false;
1020 scrollbar_without_paints_ =
1021 FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, parent_->id());
1022 scrollbar_without_paints_->SetPosition(gfx::Point(6, 10));
1023 scrollbar_without_paints_->SetBounds(gfx::Size(3, 10));
1025 parent_->AddChild(child_);
1026 parent_->AddChild(scrollbar_with_paints_);
1027 parent_->AddChild(scrollbar_without_paints_);
1029 layer_tree_host()->SetRootLayer(parent_);
1030 LayerTreeHostTest::SetupTree();
1033 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1035 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1036 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1038 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1039 impl->output_surface()->context3d());
1041 switch (impl->active_tree()->source_frame_number()) {
1042 case 0:
1043 // Number of textures should be one for each layer.
1044 ASSERT_EQ(4u, context->NumTextures());
1045 // Number of textures used for commit should be one for each layer.
1046 EXPECT_EQ(4u, context->NumUsedTextures());
1047 // Verify that used textures are correct.
1048 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1049 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1050 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1051 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1053 context->ResetUsedTextures();
1054 PostSetNeedsCommitToMainThread();
1055 break;
1056 case 1:
1057 // Number of textures should be two for each content layer and one
1058 // for each scrollbar, since they always do a partial update.
1059 ASSERT_EQ(6u, context->NumTextures());
1060 // Number of textures used for commit should be one for each content
1061 // layer, and one for the scrollbar layer that paints.
1062 EXPECT_EQ(3u, context->NumUsedTextures());
1064 // First content textures should not have been used.
1065 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1066 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1067 // The non-painting scrollbar's texture wasn't updated.
1068 EXPECT_FALSE(context->UsedTexture(context->TextureAt(2)));
1069 // The painting scrollbar's partial update texture was used.
1070 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1071 // New textures should have been used.
1072 EXPECT_TRUE(context->UsedTexture(context->TextureAt(4)));
1073 EXPECT_TRUE(context->UsedTexture(context->TextureAt(5)));
1075 context->ResetUsedTextures();
1076 PostSetNeedsCommitToMainThread();
1077 break;
1078 case 2:
1079 // Number of textures should be two for each content layer and one
1080 // for each scrollbar, since they always do a partial update.
1081 ASSERT_EQ(6u, context->NumTextures());
1082 // Number of textures used for commit should be one for each content
1083 // layer, and one for the scrollbar layer that paints.
1084 EXPECT_EQ(3u, context->NumUsedTextures());
1086 // The non-painting scrollbar's texture wasn't updated.
1087 EXPECT_FALSE(context->UsedTexture(context->TextureAt(2)));
1088 // The painting scrollbar does a partial update.
1089 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1090 // One content layer does a partial update also.
1091 EXPECT_TRUE(context->UsedTexture(context->TextureAt(4)));
1092 EXPECT_FALSE(context->UsedTexture(context->TextureAt(5)));
1094 context->ResetUsedTextures();
1095 PostSetNeedsCommitToMainThread();
1096 break;
1097 case 3:
1098 // No textures should be used for commit.
1099 EXPECT_EQ(0u, context->NumUsedTextures());
1101 context->ResetUsedTextures();
1102 PostSetNeedsCommitToMainThread();
1103 break;
1104 case 4:
1105 // Number of textures used for commit should be two. One for the
1106 // content layer, and one for the painting scrollbar. The
1107 // non-painting scrollbar doesn't update its texture.
1108 EXPECT_EQ(2u, context->NumUsedTextures());
1110 context->ResetUsedTextures();
1111 PostSetNeedsCommitToMainThread();
1112 break;
1113 case 5:
1114 EndTest();
1115 break;
1116 default:
1117 NOTREACHED();
1118 break;
1122 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1123 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1124 impl->output_surface()->context3d());
1126 // Number of textures used for drawing should one per layer except for
1127 // frame 3 where the viewport only contains one layer.
1128 if (impl->active_tree()->source_frame_number() == 3)
1129 EXPECT_EQ(1u, context->NumUsedTextures());
1130 else
1131 EXPECT_EQ(4u, context->NumUsedTextures());
1133 context->ResetUsedTextures();
1136 virtual void Layout() OVERRIDE {
1137 switch (num_commits_++) {
1138 case 0:
1139 case 1:
1140 parent_->SetNeedsDisplay();
1141 child_->SetNeedsDisplay();
1142 scrollbar_with_paints_->SetNeedsDisplay();
1143 scrollbar_without_paints_->SetNeedsDisplay();
1144 break;
1145 case 2:
1146 // Damage part of layers.
1147 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1148 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1149 scrollbar_with_paints_->SetNeedsDisplayRect(
1150 gfx::RectF(0.f, 0.f, 5.f, 5.f));
1151 scrollbar_without_paints_->SetNeedsDisplayRect(
1152 gfx::RectF(0.f, 0.f, 5.f, 5.f));
1153 break;
1154 case 3:
1155 child_->SetNeedsDisplay();
1156 scrollbar_with_paints_->SetNeedsDisplay();
1157 scrollbar_without_paints_->SetNeedsDisplay();
1158 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1159 break;
1160 case 4:
1161 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1162 break;
1163 case 5:
1164 break;
1165 default:
1166 NOTREACHED();
1167 break;
1171 virtual void AfterTest() OVERRIDE {}
1173 private:
1174 FakeContentLayerClient client_;
1175 scoped_refptr<FakeContentLayer> parent_;
1176 scoped_refptr<FakeContentLayer> child_;
1177 scoped_refptr<FakeScrollbarLayer> scrollbar_with_paints_;
1178 scoped_refptr<FakeScrollbarLayer> scrollbar_without_paints_;
1179 int num_commits_;
1182 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate);
1184 class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1185 public:
1186 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1188 virtual void BeginTest() OVERRIDE {
1189 layer_tree_host()->SetNeedsRedraw();
1190 PostSetNeedsCommitToMainThread();
1193 virtual void DidCommitAndDrawFrame() OVERRIDE {
1194 if (once_)
1195 return;
1196 once_ = true;
1197 layer_tree_host()->SetNeedsRedraw();
1198 layer_tree_host()->AcquireLayerTextures();
1200 base::AutoLock lock(lock_);
1201 draw_count_ = 0;
1203 layer_tree_host()->FinishAllRendering();
1205 base::AutoLock lock(lock_);
1206 EXPECT_EQ(0, draw_count_);
1208 EndTest();
1211 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1212 base::AutoLock lock(lock_);
1213 ++draw_count_;
1216 virtual void AfterTest() OVERRIDE {}
1218 private:
1219 bool once_;
1220 base::Lock lock_;
1221 int draw_count_;
1224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
1226 class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1227 public:
1228 virtual void BeginTest() OVERRIDE {
1229 Layer* root_layer = layer_tree_host()->root_layer();
1231 char pixels[4];
1232 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1233 gfx::Rect(0, 0, 1, 1));
1234 EXPECT_FALSE(root_layer->render_surface());
1236 EndTest();
1239 virtual void AfterTest() OVERRIDE {}
1242 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1244 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1245 : public LayerTreeHostTest {
1246 public:
1247 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
1248 : root_layer_(FakeContentLayer::Create(&client_)),
1249 surface_layer1_(
1250 FakeContentLayer::Create(&client_)),
1251 replica_layer1_(
1252 FakeContentLayer::Create(&client_)),
1253 surface_layer2_(
1254 FakeContentLayer::Create(&client_)),
1255 replica_layer2_(
1256 FakeContentLayer::Create(&client_)) {}
1258 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1259 settings->cache_render_pass_contents = true;
1262 virtual void BeginTest() OVERRIDE {
1263 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
1265 root_layer_->SetBounds(gfx::Size(100, 100));
1266 surface_layer1_->SetBounds(gfx::Size(100, 100));
1267 surface_layer1_->SetForceRenderSurface(true);
1268 surface_layer1_->SetOpacity(0.5f);
1269 surface_layer2_->SetBounds(gfx::Size(100, 100));
1270 surface_layer2_->SetForceRenderSurface(true);
1271 surface_layer2_->SetOpacity(0.5f);
1273 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1274 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1276 root_layer_->AddChild(surface_layer1_);
1277 surface_layer1_->AddChild(surface_layer2_);
1278 layer_tree_host()->SetRootLayer(root_layer_);
1280 PostSetNeedsCommitToMainThread();
1283 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1284 Renderer* renderer = host_impl->renderer();
1285 RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1286 ->root_layer()->children()[0]->render_surface()->RenderPassId();
1287 RenderPass::Id surface2_render_pass_id =
1288 host_impl->active_tree()->root_layer()->children()[0]->children()[0]
1289 ->render_surface()->RenderPassId();
1291 switch (host_impl->active_tree()->source_frame_number()) {
1292 case 0:
1293 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1294 surface1_render_pass_id));
1295 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1296 surface2_render_pass_id));
1298 // Reduce the memory limit to only fit the root layer and one render
1299 // surface. This prevents any contents drawing into surfaces
1300 // from being allocated.
1301 host_impl->SetManagedMemoryPolicy(
1302 ManagedMemoryPolicy(100 * 100 * 4 * 2));
1303 break;
1304 case 1:
1305 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1306 surface1_render_pass_id));
1307 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1308 surface2_render_pass_id));
1310 EndTest();
1311 break;
1315 virtual void DidCommitAndDrawFrame() OVERRIDE {
1316 if (!TestEnded())
1317 root_layer_->SetNeedsDisplay();
1320 virtual void AfterTest() OVERRIDE {
1321 EXPECT_EQ(3u, root_layer_->update_count());
1322 EXPECT_EQ(3u, surface_layer1_->update_count());
1323 EXPECT_EQ(3u, surface_layer2_->update_count());
1326 private:
1327 FakeContentLayerClient client_;
1328 scoped_refptr<FakeContentLayer> root_layer_;
1329 scoped_refptr<FakeContentLayer> surface_layer1_;
1330 scoped_refptr<FakeContentLayer> replica_layer1_;
1331 scoped_refptr<FakeContentLayer> surface_layer2_;
1332 scoped_refptr<FakeContentLayer> replica_layer2_;
1335 SINGLE_AND_MULTI_THREAD_TEST_F(
1336 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1338 class EvictionTestLayer : public Layer {
1339 public:
1340 static scoped_refptr<EvictionTestLayer> Create() {
1341 return make_scoped_refptr(new EvictionTestLayer());
1344 virtual void Update(ResourceUpdateQueue*,
1345 const OcclusionTracker*,
1346 RenderingStats*) OVERRIDE;
1347 virtual bool DrawsContent() const OVERRIDE { return true; }
1349 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1350 OVERRIDE;
1351 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1352 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1354 bool HaveBackingTexture() const {
1355 return texture_.get() ? texture_->have_backing_texture() : false;
1358 private:
1359 EvictionTestLayer() : Layer() {}
1360 virtual ~EvictionTestLayer() {}
1362 void CreateTextureIfNeeded() {
1363 if (texture_)
1364 return;
1365 texture_ = PrioritizedResource::Create(
1366 layer_tree_host()->contents_texture_manager());
1367 texture_->SetDimensions(gfx::Size(10, 10), GL_RGBA);
1368 bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
1371 scoped_ptr<PrioritizedResource> texture_;
1372 SkBitmap bitmap_;
1375 class EvictionTestLayerImpl : public LayerImpl {
1376 public:
1377 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1378 int id) {
1379 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1381 virtual ~EvictionTestLayerImpl() {}
1383 virtual void AppendQuads(QuadSink* quad_sink,
1384 AppendQuadsData* append_quads_data) OVERRIDE {
1385 ASSERT_TRUE(has_texture_);
1386 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1389 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1391 private:
1392 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1393 : LayerImpl(tree_impl, id), has_texture_(false) {}
1395 bool has_texture_;
1398 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1399 CreateTextureIfNeeded();
1400 if (!texture_)
1401 return;
1402 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1405 void EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1406 const OcclusionTracker*,
1407 RenderingStats*) {
1408 CreateTextureIfNeeded();
1409 if (!texture_)
1410 return;
1412 gfx::Rect full_rect(0, 0, 10, 10);
1413 ResourceUpdate upload = ResourceUpdate::Create(
1414 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1415 queue->AppendFullUpload(upload);
1418 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1419 LayerTreeImpl* tree_impl) {
1420 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
1421 .PassAs<LayerImpl>();
1424 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1425 Layer::PushPropertiesTo(layer_impl);
1427 EvictionTestLayerImpl* test_layer_impl =
1428 static_cast<EvictionTestLayerImpl*>(layer_impl);
1429 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1432 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1433 public:
1434 LayerTreeHostTestEvictTextures()
1435 : layer_(EvictionTestLayer::Create()),
1436 impl_for_evict_textures_(0),
1437 num_commits_(0) {}
1439 virtual void BeginTest() OVERRIDE {
1440 layer_tree_host()->SetRootLayer(layer_);
1441 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1443 gfx::Transform identity_matrix;
1444 SetLayerPropertiesForTesting(layer_.get(),
1446 identity_matrix,
1447 gfx::PointF(0.f, 0.f),
1448 gfx::PointF(0.f, 0.f),
1449 gfx::Size(10, 20),
1450 true);
1452 PostSetNeedsCommitToMainThread();
1455 void PostEvictTextures() {
1456 DCHECK(ImplThread());
1457 ImplThread()->PostTask(
1458 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1459 base::Unretained(this)));
1462 void EvictTexturesOnImplThread() {
1463 DCHECK(impl_for_evict_textures_);
1464 impl_for_evict_textures_->EnforceManagedMemoryPolicy(
1465 ManagedMemoryPolicy(0));
1468 // Commit 1: Just commit and draw normally, then post an eviction at the end
1469 // that will trigger a commit.
1470 // Commit 2: Triggered by the eviction, let it go through and then set
1471 // needsCommit.
1472 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1473 // task, which will be handled before the commit. Don't set needsCommit, it
1474 // should have been posted. A frame should not be drawn (note,
1475 // didCommitAndDrawFrame may be called anyway).
1476 // Commit 4: Triggered by the eviction, let it go through and then set
1477 // needsCommit.
1478 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1479 // Layout(), a frame should not be drawn but a commit will be posted.
1480 // Commit 6: Triggered by the eviction, post an eviction task in
1481 // Layout(), which will be a noop, letting the commit (which recreates the
1482 // textures) go through and draw a frame, then end the test.
1484 // Commits 1+2 test the eviction recovery path where eviction happens outside
1485 // of the beginFrame/commit pair.
1486 // Commits 3+4 test the eviction recovery path where eviction happens inside
1487 // the beginFrame/commit pair.
1488 // Commits 5+6 test the path where an eviction happens during the eviction
1489 // recovery path.
1490 virtual void DidCommit() OVERRIDE {
1491 switch (num_commits_) {
1492 case 1:
1493 EXPECT_TRUE(layer_->HaveBackingTexture());
1494 PostEvictTextures();
1495 break;
1496 case 2:
1497 EXPECT_TRUE(layer_->HaveBackingTexture());
1498 layer_tree_host()->SetNeedsCommit();
1499 break;
1500 case 3:
1501 break;
1502 case 4:
1503 EXPECT_TRUE(layer_->HaveBackingTexture());
1504 layer_tree_host()->SetNeedsCommit();
1505 break;
1506 case 5:
1507 break;
1508 case 6:
1509 EXPECT_TRUE(layer_->HaveBackingTexture());
1510 EndTest();
1511 break;
1512 default:
1513 NOTREACHED();
1514 break;
1518 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1519 impl_for_evict_textures_ = impl;
1522 virtual void Layout() OVERRIDE {
1523 ++num_commits_;
1524 switch (num_commits_) {
1525 case 1:
1526 case 2:
1527 break;
1528 case 3:
1529 PostEvictTextures();
1530 break;
1531 case 4:
1532 // We couldn't check in didCommitAndDrawFrame on commit 3,
1533 // so check here.
1534 EXPECT_FALSE(layer_->HaveBackingTexture());
1535 break;
1536 case 5:
1537 PostEvictTextures();
1538 break;
1539 case 6:
1540 // We couldn't check in didCommitAndDrawFrame on commit 5,
1541 // so check here.
1542 EXPECT_FALSE(layer_->HaveBackingTexture());
1543 PostEvictTextures();
1544 break;
1545 default:
1546 NOTREACHED();
1547 break;
1551 virtual void AfterTest() OVERRIDE {}
1553 private:
1554 FakeContentLayerClient client_;
1555 scoped_refptr<EvictionTestLayer> layer_;
1556 LayerTreeHostImpl* impl_for_evict_textures_;
1557 int num_commits_;
1560 MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures);
1562 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
1563 public:
1564 LayerTreeHostTestContinuousCommit()
1565 : num_commit_complete_(0), num_draw_layers_(0) {}
1567 virtual void BeginTest() OVERRIDE {
1568 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1569 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1571 PostSetNeedsCommitToMainThread();
1574 virtual void DidCommit() OVERRIDE {
1575 if (num_draw_layers_ == 2)
1576 return;
1577 layer_tree_host()->root_layer()->SetNeedsDisplay();
1580 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1581 if (num_draw_layers_ == 1)
1582 num_commit_complete_++;
1585 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1586 num_draw_layers_++;
1587 if (num_draw_layers_ == 2)
1588 EndTest();
1591 virtual void AfterTest() OVERRIDE {
1592 // Check that we didn't commit twice between first and second draw.
1593 EXPECT_EQ(1, num_commit_complete_);
1596 private:
1597 int num_commit_complete_;
1598 int num_draw_layers_;
1601 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
1603 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1604 public:
1605 LayerTreeHostTestContinuousInvalidate()
1606 : num_commit_complete_(0), num_draw_layers_(0) {}
1608 virtual void BeginTest() OVERRIDE {
1609 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1610 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1612 content_layer_ = ContentLayer::Create(&client_);
1613 content_layer_->SetBounds(gfx::Size(10, 10));
1614 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1615 content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1616 content_layer_->SetIsDrawable(true);
1617 layer_tree_host()->root_layer()->AddChild(content_layer_);
1619 PostSetNeedsCommitToMainThread();
1622 virtual void DidCommit() OVERRIDE {
1623 if (num_draw_layers_ == 2)
1624 return;
1625 content_layer_->SetNeedsDisplay();
1628 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1629 if (num_draw_layers_ == 1)
1630 num_commit_complete_++;
1633 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1634 num_draw_layers_++;
1635 if (num_draw_layers_ == 2)
1636 EndTest();
1639 virtual void AfterTest() OVERRIDE {
1640 // Check that we didn't commit twice between first and second draw.
1641 EXPECT_EQ(1, num_commit_complete_);
1644 private:
1645 FakeContentLayerClient client_;
1646 scoped_refptr<Layer> content_layer_;
1647 int num_commit_complete_;
1648 int num_draw_layers_;
1651 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
1653 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1654 public:
1655 LayerTreeHostTestDeferCommits()
1656 : num_commits_deferred_(0), num_complete_commits_(0) {}
1658 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1660 virtual void DidDeferCommit() OVERRIDE {
1661 num_commits_deferred_++;
1662 layer_tree_host()->SetDeferCommits(false);
1665 virtual void DidCommit() OVERRIDE {
1666 num_complete_commits_++;
1667 switch (num_complete_commits_) {
1668 case 1:
1669 EXPECT_EQ(0, num_commits_deferred_);
1670 layer_tree_host()->SetDeferCommits(true);
1671 PostSetNeedsCommitToMainThread();
1672 break;
1673 case 2:
1674 EndTest();
1675 break;
1676 default:
1677 NOTREACHED();
1678 break;
1682 virtual void AfterTest() OVERRIDE {
1683 EXPECT_EQ(1, num_commits_deferred_);
1684 EXPECT_EQ(2, num_complete_commits_);
1687 private:
1688 int num_commits_deferred_;
1689 int num_complete_commits_;
1692 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1694 class LayerTreeHostWithProxy : public LayerTreeHost {
1695 public:
1696 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
1697 const LayerTreeSettings& settings,
1698 scoped_ptr<FakeProxy> proxy)
1699 : LayerTreeHost(client, settings) {
1700 proxy->SetLayerTreeHost(this);
1701 EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
1705 TEST(LayerTreeHostTest, LimitPartialUpdates) {
1706 // When partial updates are not allowed, max updates should be 0.
1708 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1710 scoped_ptr<FakeProxy> proxy =
1711 make_scoped_ptr(new FakeProxy(scoped_ptr<Thread>()));
1712 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
1713 proxy->SetMaxPartialTextureUpdates(5);
1715 LayerTreeSettings settings;
1716 settings.max_partial_texture_updates = 10;
1718 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1719 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1721 EXPECT_EQ(0u, host.settings().max_partial_texture_updates);
1724 // When partial updates are allowed,
1725 // max updates should be limited by the proxy.
1727 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1729 scoped_ptr<FakeProxy> proxy =
1730 make_scoped_ptr(new FakeProxy(scoped_ptr<Thread>()));
1731 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1732 proxy->SetMaxPartialTextureUpdates(5);
1734 LayerTreeSettings settings;
1735 settings.max_partial_texture_updates = 10;
1737 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1738 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1740 EXPECT_EQ(5u, host.settings().max_partial_texture_updates);
1743 // When partial updates are allowed,
1744 // max updates should also be limited by the settings.
1746 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1748 scoped_ptr<FakeProxy> proxy =
1749 make_scoped_ptr(new FakeProxy(scoped_ptr<Thread>()));
1750 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1751 proxy->SetMaxPartialTextureUpdates(20);
1753 LayerTreeSettings settings;
1754 settings.max_partial_texture_updates = 10;
1756 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1757 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1759 EXPECT_EQ(10u, host.settings().max_partial_texture_updates);
1763 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
1764 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1766 LayerTreeSettings settings;
1767 settings.max_partial_texture_updates = 4;
1769 scoped_ptr<LayerTreeHost> host =
1770 LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>());
1771 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
1772 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
1775 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
1776 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
1778 LayerTreeSettings settings;
1779 settings.max_partial_texture_updates = 4;
1781 scoped_ptr<LayerTreeHost> host =
1782 LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>());
1783 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
1784 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
1787 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
1788 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
1790 LayerTreeSettings settings;
1791 settings.max_partial_texture_updates = 4;
1793 scoped_ptr<LayerTreeHost> host =
1794 LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>());
1795 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
1796 EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
1799 TEST(LayerTreeHostTest,
1800 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
1801 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
1803 LayerTreeSettings settings;
1804 settings.max_partial_texture_updates = 4;
1806 scoped_ptr<LayerTreeHost> host =
1807 LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>());
1808 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
1809 EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
1812 class LayerTreeHostTestCapturePicture : public LayerTreeHostTest {
1813 public:
1814 LayerTreeHostTestCapturePicture()
1815 : bounds_(gfx::Size(100, 100)),
1816 layer_(PictureLayer::Create(&content_client_)) {}
1818 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1819 settings->impl_side_painting = true;
1822 class FillRectContentLayerClient : public ContentLayerClient {
1823 public:
1824 virtual void PaintContents(SkCanvas* canvas,
1825 gfx::Rect clip,
1826 gfx::RectF* opaque) OVERRIDE {
1827 SkPaint paint;
1828 paint.setColor(SK_ColorGREEN);
1830 SkRect rect = SkRect::MakeWH(canvas->getDeviceSize().width(),
1831 canvas->getDeviceSize().height());
1832 *opaque = gfx::RectF(rect.width(), rect.height());
1833 canvas->drawRect(rect, paint);
1835 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
1838 virtual void BeginTest() OVERRIDE {
1839 layer_->SetIsDrawable(true);
1840 layer_->SetBounds(bounds_);
1841 // Outside viewport so tiles don't have to be initialized for commit.
1842 layer_->SetPosition(gfx::Point(100, 100));
1843 layer_tree_host()->SetViewportSize(bounds_);
1844 layer_tree_host()->SetRootLayer(layer_);
1846 PostSetNeedsCommitToMainThread();
1849 virtual void DidCommitAndDrawFrame() OVERRIDE {
1850 picture_ = layer_tree_host()->CapturePicture();
1851 EndTest();
1854 virtual void AfterTest() OVERRIDE {
1855 EXPECT_EQ(bounds_, gfx::Size(picture_->width(), picture_->height()));
1857 SkBitmap bitmap;
1858 bitmap.setConfig(
1859 SkBitmap::kARGB_8888_Config, bounds_.width(), bounds_.height());
1860 bitmap.allocPixels();
1861 bitmap.eraseARGB(0, 0, 0, 0);
1862 SkCanvas canvas(bitmap);
1864 picture_->draw(&canvas);
1866 bitmap.lockPixels();
1867 SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
1868 EXPECT_EQ(SK_ColorGREEN, pixels[0]);
1869 bitmap.unlockPixels();
1872 private:
1873 gfx::Size bounds_;
1874 FillRectContentLayerClient content_client_;
1875 scoped_refptr<PictureLayer> layer_;
1876 skia::RefPtr<SkPicture> picture_;
1879 MULTI_THREAD_TEST_F(LayerTreeHostTestCapturePicture);
1881 class LayerTreeHostTestMaxPendingFrames : public LayerTreeHostTest {
1882 public:
1883 LayerTreeHostTestMaxPendingFrames() : LayerTreeHostTest() {}
1885 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
1886 if (delegating_renderer_)
1887 return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>();
1888 return FakeOutputSurface::Create3d().PassAs<OutputSurface>();
1891 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1893 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1894 DCHECK(host_impl->proxy()->HasImplThread());
1896 const ThreadProxy* proxy = static_cast<ThreadProxy*>(host_impl->proxy());
1897 if (delegating_renderer_) {
1898 EXPECT_EQ(1, proxy->MaxFramesPendingForTesting());
1899 } else {
1900 EXPECT_EQ(FrameRateController::DEFAULT_MAX_FRAMES_PENDING,
1901 proxy->MaxFramesPendingForTesting());
1903 EndTest();
1906 virtual void AfterTest() OVERRIDE {}
1908 protected:
1909 bool delegating_renderer_;
1912 TEST_F(LayerTreeHostTestMaxPendingFrames, DelegatingRenderer) {
1913 delegating_renderer_ = true;
1914 RunTest(true);
1917 TEST_F(LayerTreeHostTestMaxPendingFrames, GLRenderer) {
1918 delegating_renderer_ = false;
1919 RunTest(true);
1922 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
1923 : public LayerTreeHostTest {
1924 public:
1925 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
1926 : root_layer_(FakeContentLayer::Create(&client_)),
1927 child_layer1_(FakeContentLayer::Create(&client_)),
1928 child_layer2_(FakeContentLayer::Create(&client_)),
1929 num_commits_(0) {}
1931 virtual void BeginTest() OVERRIDE {
1932 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
1933 root_layer_->SetBounds(gfx::Size(100, 100));
1934 child_layer1_->SetBounds(gfx::Size(100, 100));
1935 child_layer2_->SetBounds(gfx::Size(100, 100));
1936 root_layer_->AddChild(child_layer1_);
1937 root_layer_->AddChild(child_layer2_);
1938 layer_tree_host()->SetRootLayer(root_layer_);
1939 PostSetNeedsCommitToMainThread();
1942 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
1943 bool visible) OVERRIDE {
1944 // One backing should remain unevicted.
1945 EXPECT_EQ(100u * 100u * 4u * 1u,
1946 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1947 // Make sure that contents textures are marked as having been
1948 // purged.
1949 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
1950 // End the test in this state.
1951 EndTest();
1954 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1955 ++num_commits_;
1956 switch (num_commits_) {
1957 case 1:
1958 // All three backings should have memory.
1959 EXPECT_EQ(
1960 100u * 100u * 4u * 3u,
1961 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1962 // Set a new policy that will kick out 1 of the 3 resources.
1963 // Because a resource was evicted, a commit will be kicked off.
1964 host_impl->SetManagedMemoryPolicy(
1965 ManagedMemoryPolicy(100 * 100 * 4 * 2,
1966 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
1967 100 * 100 * 4 * 1,
1968 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING));
1969 break;
1970 case 2:
1971 // Only two backings should have memory.
1972 EXPECT_EQ(
1973 100u * 100u * 4u * 2u,
1974 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1975 // Become backgrounded, which will cause 1 more resource to be
1976 // evicted.
1977 PostSetVisibleToMainThread(false);
1978 break;
1979 default:
1980 // No further commits should happen because this is not visible
1981 // anymore.
1982 NOTREACHED();
1983 break;
1987 virtual void AfterTest() OVERRIDE {}
1989 private:
1990 FakeContentLayerClient client_;
1991 scoped_refptr<FakeContentLayer> root_layer_;
1992 scoped_refptr<FakeContentLayer> child_layer1_;
1993 scoped_refptr<FakeContentLayer> child_layer2_;
1994 int num_commits_;
1997 SINGLE_AND_MULTI_THREAD_TEST_F(
1998 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2000 class LayerTreeHostTestPinchZoomScrollbarCreation : public LayerTreeHostTest {
2001 public:
2002 LayerTreeHostTestPinchZoomScrollbarCreation()
2003 : root_layer_(ContentLayer::Create(&client_)) {}
2005 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2006 settings->use_pinch_zoom_scrollbars = true;
2009 virtual void BeginTest() OVERRIDE {
2010 root_layer_->SetIsDrawable(true);
2011 root_layer_->SetBounds(gfx::Size(100, 100));
2012 layer_tree_host()->SetRootLayer(root_layer_);
2013 PostSetNeedsCommitToMainThread();
2016 virtual void DidCommit() OVERRIDE {
2017 // We always expect two pinch-zoom scrollbar layers.
2018 ASSERT_EQ(2u, root_layer_->children().size());
2020 // Pinch-zoom scrollbar layers always have invalid scrollLayerIds.
2021 ScrollbarLayer* layer1 = root_layer_->children()[0]->ToScrollbarLayer();
2022 ASSERT_TRUE(layer1);
2023 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID,
2024 layer1->scroll_layer_id());
2025 EXPECT_EQ(0.f, layer1->opacity());
2026 EXPECT_TRUE(layer1->OpacityCanAnimateOnImplThread());
2027 EXPECT_TRUE(layer1->DrawsContent());
2029 ScrollbarLayer* layer2 = root_layer_->children()[1]->ToScrollbarLayer();
2030 ASSERT_TRUE(layer2);
2031 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID,
2032 layer2->scroll_layer_id());
2033 EXPECT_EQ(0.f, layer2->opacity());
2034 EXPECT_TRUE(layer2->OpacityCanAnimateOnImplThread());
2035 EXPECT_TRUE(layer2->DrawsContent());
2037 EndTest();
2040 virtual void AfterTest() OVERRIDE {}
2042 private:
2043 FakeContentLayerClient client_;
2044 scoped_refptr<ContentLayer> root_layer_;
2047 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarCreation);
2049 class LayerTreeHostTestPinchZoomScrollbarResize : public LayerTreeHostTest {
2050 public:
2051 LayerTreeHostTestPinchZoomScrollbarResize()
2052 : root_layer_(ContentLayer::Create(&client_)), num_commits_(0) {}
2054 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2055 settings->use_pinch_zoom_scrollbars = true;
2058 virtual void BeginTest() OVERRIDE {
2059 root_layer_->SetIsDrawable(true);
2060 root_layer_->SetBounds(gfx::Size(100, 100));
2061 layer_tree_host()->SetRootLayer(root_layer_);
2062 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2063 PostSetNeedsCommitToMainThread();
2066 virtual void DidCommit() OVERRIDE {
2067 num_commits_++;
2069 ScrollbarLayer* layer1 = root_layer_->children()[0]->ToScrollbarLayer();
2070 ASSERT_TRUE(layer1);
2071 ScrollbarLayer* layer2 = root_layer_->children()[1]->ToScrollbarLayer();
2072 ASSERT_TRUE(layer2);
2074 // Get scrollbar thickness from horizontal scrollbar's height.
2075 int thickness = layer1->bounds().height();
2077 if (!layer1->Orientation() == WebKit::WebScrollbar::Horizontal)
2078 std::swap(layer1, layer2);
2080 gfx::Size viewport_size = layer_tree_host()->device_viewport_size();
2081 EXPECT_EQ(viewport_size.width() - thickness, layer1->bounds().width());
2082 EXPECT_EQ(viewport_size.height() - thickness, layer2->bounds().height());
2084 switch (num_commits_) {
2085 case 1:
2086 // Resizing the viewport should also resize the pinch-zoom scrollbars.
2087 layer_tree_host()->SetViewportSize(gfx::Size(120, 150));
2088 break;
2089 default:
2090 EndTest();
2094 virtual void AfterTest() OVERRIDE {}
2096 private:
2097 FakeContentLayerClient client_;
2098 scoped_refptr<ContentLayer> root_layer_;
2099 int num_commits_;
2102 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarResize);
2104 class LayerTreeHostTestPinchZoomScrollbarNewRootLayer
2105 : public LayerTreeHostTest {
2106 public:
2107 LayerTreeHostTestPinchZoomScrollbarNewRootLayer()
2108 : root_layer_(ContentLayer::Create(&client_)), num_commits_(0) {}
2110 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2111 settings->use_pinch_zoom_scrollbars = true;
2114 virtual void BeginTest() OVERRIDE {
2115 root_layer_->SetIsDrawable(true);
2116 root_layer_->SetBounds(gfx::Size(100, 100));
2117 layer_tree_host()->SetRootLayer(root_layer_);
2118 PostSetNeedsCommitToMainThread();
2121 virtual void DidCommit() OVERRIDE {
2122 num_commits_++;
2124 // We always expect two pinch-zoom scrollbar layers.
2125 ASSERT_EQ(2u, root_layer_->children().size());
2127 // Pinch-zoom scrollbar layers always have invalid scrollLayerIds.
2128 ScrollbarLayer* layer1 = root_layer_->children()[0]->ToScrollbarLayer();
2129 ASSERT_TRUE(layer1);
2130 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID,
2131 layer1->scroll_layer_id());
2132 EXPECT_EQ(0.f, layer1->opacity());
2133 EXPECT_TRUE(layer1->DrawsContent());
2135 ScrollbarLayer* layer2 = root_layer_->children()[1]->ToScrollbarLayer();
2136 ASSERT_TRUE(layer2);
2137 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID,
2138 layer2->scroll_layer_id());
2139 EXPECT_EQ(0.f, layer2->opacity());
2140 EXPECT_TRUE(layer2->DrawsContent());
2142 if (num_commits_ == 1) {
2143 // Create a new root layer and attach to tree to verify the pinch
2144 // zoom scrollbars get correctly re-attached.
2145 root_layer_ = ContentLayer::Create(&client_);
2146 root_layer_->SetIsDrawable(true);
2147 root_layer_->SetBounds(gfx::Size(100, 100));
2148 layer_tree_host()->SetRootLayer(root_layer_);
2149 PostSetNeedsCommitToMainThread();
2150 } else {
2151 EndTest();
2155 virtual void AfterTest() OVERRIDE {}
2157 private:
2158 FakeContentLayerClient client_;
2159 scoped_refptr<ContentLayer> root_layer_;
2160 int num_commits_;
2163 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarNewRootLayer);
2165 class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2166 public:
2167 class NotificationClient : public ContentLayerClient {
2168 public:
2169 NotificationClient()
2170 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2172 void set_layer(Layer* layer) { layer_ = layer; }
2173 int paint_count() const { return paint_count_; }
2174 int lcd_notification_count() const { return lcd_notification_count_; }
2176 virtual void PaintContents(SkCanvas* canvas,
2177 gfx::Rect clip,
2178 gfx::RectF* opaque) OVERRIDE {
2179 ++paint_count_;
2181 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2182 ++lcd_notification_count_;
2183 layer_->SetNeedsDisplay();
2186 private:
2187 Layer* layer_;
2188 int paint_count_;
2189 int lcd_notification_count_;
2192 virtual void SetupTree() OVERRIDE {
2193 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2194 root_layer->SetIsDrawable(true);
2195 root_layer->SetBounds(gfx::Size(1, 1));
2197 layer_tree_host()->SetRootLayer(root_layer);
2198 client_.set_layer(root_layer.get());
2200 // The expecations are based on the assumption that the default
2201 // LCD settings are:
2202 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2203 EXPECT_FALSE(root_layer->can_use_lcd_text());
2205 LayerTreeHostTest::SetupTree();
2208 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2209 virtual void AfterTest() OVERRIDE {}
2211 virtual void DidCommit() OVERRIDE {
2212 switch (layer_tree_host()->commit_number()) {
2213 case 1:
2214 // The first update consists one LCD notification and one paint.
2215 EXPECT_EQ(1, client_.lcd_notification_count());
2216 EXPECT_EQ(1, client_.paint_count());
2217 // LCD text must have been enabled on the layer.
2218 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2219 PostSetNeedsCommitToMainThread();
2220 break;
2221 case 2:
2222 // Since nothing changed on layer, there should be no notification
2223 // or paint on the second update.
2224 EXPECT_EQ(1, client_.lcd_notification_count());
2225 EXPECT_EQ(1, client_.paint_count());
2226 // LCD text must not have changed.
2227 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2228 // Change layer opacity that should trigger lcd notification.
2229 layer_tree_host()->root_layer()->SetOpacity(.5f);
2230 // No need to request a commit - setting opacity will do it.
2231 break;
2232 default:
2233 // Verify that there is not extra commit due to layer invalidation.
2234 EXPECT_EQ(3, layer_tree_host()->commit_number());
2235 // LCD notification count should have incremented due to
2236 // change in layer opacity.
2237 EXPECT_EQ(2, client_.lcd_notification_count());
2238 // Paint count should be incremented due to invalidation.
2239 EXPECT_EQ(2, client_.paint_count());
2240 // LCD text must have been disabled on the layer due to opacity.
2241 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2242 EndTest();
2243 break;
2247 private:
2248 NotificationClient client_;
2251 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2253 // Verify that the vsync notification is used to initiate rendering.
2254 class LayerTreeHostTestVSyncNotification : public LayerTreeHostTest {
2255 public:
2256 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2257 settings->render_vsync_notification_enabled = true;
2260 virtual void BeginTest() OVERRIDE {
2261 PostSetNeedsCommitToMainThread();
2264 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2265 FakeOutputSurface* fake_output_surface =
2266 reinterpret_cast<FakeOutputSurface*>(host_impl->output_surface());
2268 // The vsync notification is turned off now but will get enabled once we
2269 // return, so post a task to trigger it.
2270 ASSERT_FALSE(fake_output_surface->vsync_notification_enabled());
2271 PostVSyncOnImplThread(fake_output_surface);
2274 void PostVSyncOnImplThread(FakeOutputSurface* fake_output_surface) {
2275 DCHECK(ImplThread());
2276 ImplThread()->PostTask(
2277 base::Bind(&LayerTreeHostTestVSyncNotification::DidVSync,
2278 base::Unretained(this),
2279 base::Unretained(fake_output_surface)));
2282 void DidVSync(FakeOutputSurface* fake_output_surface) {
2283 ASSERT_TRUE(fake_output_surface->vsync_notification_enabled());
2284 fake_output_surface->DidVSync(frame_time_);
2287 virtual bool PrepareToDrawOnThread(
2288 LayerTreeHostImpl* host_impl,
2289 LayerTreeHostImpl::FrameData* frame,
2290 bool result) OVERRIDE {
2291 EndTest();
2292 return true;
2295 virtual void AfterTest() OVERRIDE {}
2297 private:
2298 base::TimeTicks frame_time_;
2301 MULTI_THREAD_TEST_F(LayerTreeHostTestVSyncNotification);
2303 class LayerTreeHostTestInputDrivenRendering : public LayerTreeHostTest {
2304 public:
2305 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2306 settings->render_vsync_notification_enabled = true;
2309 virtual void BeginTest() OVERRIDE {
2310 frame_time_ = base::TimeTicks::Now();
2311 PostSetNeedsCommitToMainThread();
2314 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2315 // Post a task to send the final input event for the current vsync; it
2316 // should trigger rendering.
2317 ImplThread()->PostTask(
2318 base::Bind(&LayerTreeHostTestInputDrivenRendering::SendFinalInputEvent,
2319 base::Unretained(this),
2320 base::Unretained(host_impl)));
2323 void SendFinalInputEvent(LayerTreeHostImpl* host_impl) {
2324 host_impl->DidReceiveLastInputEventForVSync(frame_time_);
2327 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2328 EXPECT_EQ(frame_time_, **host_impl->fps_counter()->begin());
2329 EndTest();
2332 virtual void AfterTest() OVERRIDE {}
2334 private:
2335 base::TimeTicks frame_time_;
2338 MULTI_THREAD_TEST_F(LayerTreeHostTestInputDrivenRendering);
2340 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2341 : public LayerTreeHostTest {
2342 protected:
2343 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2344 settings->impl_side_painting = true;
2347 virtual void SetupTree() OVERRIDE {
2348 LayerTreeHostTest::SetupTree();
2350 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2351 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2352 layer->SetBounds(gfx::Size(10, 10));
2353 layer_tree_host()->root_layer()->AddChild(layer);
2356 virtual void BeginTest() OVERRIDE {
2357 PostSetNeedsCommitToMainThread();
2360 virtual void TreeActivatedOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2361 EndTest();
2364 virtual void AfterTest() OVERRIDE {
2367 FakeContentLayerClient client_;
2370 MULTI_THREAD_TEST_F(
2371 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2373 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2374 : public LayerTreeHostTest {
2375 public:
2376 class SetBoundsClient : public ContentLayerClient {
2377 public:
2378 SetBoundsClient() : layer_(0) {}
2380 void set_layer(Layer* layer) { layer_ = layer; }
2382 virtual void PaintContents(SkCanvas* canvas,
2383 gfx::Rect clip,
2384 gfx::RectF* opaque) OVERRIDE {
2385 layer_->SetBounds(gfx::Size(2, 2));
2388 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2390 private:
2391 Layer* layer_;
2394 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2396 virtual void SetupTree() OVERRIDE {
2397 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2398 root_layer->SetIsDrawable(true);
2399 root_layer->SetBounds(gfx::Size(1, 1));
2401 layer_tree_host()->SetRootLayer(root_layer);
2402 client_.set_layer(root_layer.get());
2404 LayerTreeHostTest::SetupTree();
2407 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2408 virtual void AfterTest() OVERRIDE {}
2410 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2411 num_commits_++;
2412 if (num_commits_ == 1) {
2413 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2414 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2415 } else {
2416 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2417 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2418 EndTest();
2422 private:
2423 SetBoundsClient client_;
2424 int num_commits_;
2427 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2429 class MockIOSurfaceWebGraphicsContext3D : public FakeWebGraphicsContext3D {
2430 public:
2431 MockIOSurfaceWebGraphicsContext3D()
2432 : FakeWebGraphicsContext3D() {}
2434 virtual WebKit::WebGLId createTexture() OVERRIDE {
2435 return 1;
2438 virtual WebKit::WebString getString(WebKit::WGC3Denum name) OVERRIDE {
2439 if (name == GL_EXTENSIONS) {
2440 return WebKit::WebString(
2441 "GL_CHROMIUM_iosurface GL_ARB_texture_rectangle");
2443 return WebKit::WebString();
2446 MOCK_METHOD1(activeTexture, void(WebKit::WGC3Denum texture));
2447 MOCK_METHOD2(bindTexture, void(WebKit::WGC3Denum target,
2448 WebKit::WebGLId texture_id));
2449 MOCK_METHOD3(texParameteri, void(WebKit::WGC3Denum target,
2450 WebKit::WGC3Denum pname,
2451 WebKit::WGC3Dint param));
2452 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(WebKit::WGC3Denum target,
2453 WebKit::WGC3Dint width,
2454 WebKit::WGC3Dint height,
2455 WebKit::WGC3Duint ioSurfaceId,
2456 WebKit::WGC3Duint plane));
2457 MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
2458 WebKit::WGC3Dsizei count,
2459 WebKit::WGC3Denum type,
2460 WebKit::WGC3Dintptr offset));
2464 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2465 protected:
2466 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
2467 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> context(
2468 new MockIOSurfaceWebGraphicsContext3D);
2469 mock_context_ = context.get();
2470 scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(
2471 context.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>();
2472 return output_surface.Pass();
2475 virtual void SetupTree() OVERRIDE {
2476 LayerTreeHostTest::SetupTree();
2478 layer_tree_host()->root_layer()->SetIsDrawable(false);
2480 io_surface_id_ = 9;
2481 io_surface_size_ = gfx::Size(6, 7);
2483 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2484 io_surface_layer->SetBounds(gfx::Size(10, 10));
2485 io_surface_layer->SetAnchorPoint(gfx::PointF());
2486 io_surface_layer->SetIsDrawable(true);
2487 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2488 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2491 virtual void BeginTest() OVERRIDE {
2492 PostSetNeedsCommitToMainThread();
2495 virtual void TreeActivatedOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2496 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2498 EXPECT_CALL(*mock_context_, activeTexture(_))
2499 .Times(0);
2500 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2501 .Times(AtLeast(1));
2502 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2503 GL_TEXTURE_MIN_FILTER,
2504 GL_LINEAR))
2505 .Times(1);
2506 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2507 GL_TEXTURE_MAG_FILTER,
2508 GL_LINEAR))
2509 .Times(1);
2510 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2511 GL_TEXTURE_WRAP_S,
2512 GL_CLAMP_TO_EDGE))
2513 .Times(1);
2514 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2515 GL_TEXTURE_WRAP_T,
2516 GL_CLAMP_TO_EDGE))
2517 .Times(1);
2519 EXPECT_CALL(*mock_context_, texImageIOSurface2DCHROMIUM(
2520 GL_TEXTURE_RECTANGLE_ARB,
2521 io_surface_size_.width(),
2522 io_surface_size_.height(),
2523 io_surface_id_,
2525 .Times(1);
2527 EXPECT_CALL(*mock_context_, bindTexture(_, 0))
2528 .Times(AnyNumber());
2531 virtual bool PrepareToDrawOnThread(
2532 LayerTreeHostImpl* host_impl,
2533 LayerTreeHostImpl::FrameData* frame,
2534 bool result) OVERRIDE {
2535 Mock::VerifyAndClearExpectations(&mock_context_);
2537 // The io surface layer's texture is drawn.
2538 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0))
2539 .Times(AtLeast(1));
2540 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2541 .Times(1);
2542 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2543 .Times(AtLeast(1));
2545 return result;
2548 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2549 Mock::VerifyAndClearExpectations(&mock_context_);
2550 EndTest();
2553 virtual void AfterTest() OVERRIDE {}
2555 int io_surface_id_;
2556 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2557 gfx::Size io_surface_size_;
2560 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
2562 class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
2563 protected:
2564 virtual void SetupTree() OVERRIDE {
2565 root = FakeContentLayer::Create(&client_);
2566 root->SetBounds(gfx::Size(20, 20));
2568 child = FakeContentLayer::Create(&client_);
2569 child->SetBounds(gfx::Size(10, 10));
2570 root->AddChild(child);
2572 layer_tree_host()->SetRootLayer(root);
2573 LayerTreeHostTest::SetupTree();
2576 virtual void BeginTest() OVERRIDE {
2577 PostSetNeedsCommitToMainThread();
2580 virtual void DidCommitAndDrawFrame() OVERRIDE {
2581 WaitForCallback();
2584 void WaitForCallback() {
2585 base::MessageLoop::current()->PostTask(
2586 FROM_HERE,
2587 base::Bind(
2588 &LayerTreeHostTestAsyncReadback::NextStep,
2589 base::Unretained(this)));
2592 void NextStep() {
2593 int frame = layer_tree_host()->commit_number();
2594 switch (frame) {
2595 case 1:
2596 child->RequestCopyAsBitmap(base::Bind(
2597 &LayerTreeHostTestAsyncReadback::BitmapCallback,
2598 base::Unretained(this)));
2599 EXPECT_EQ(0u, callbacks_.size());
2600 break;
2601 case 2:
2602 if (callbacks_.size() < 1u) {
2603 WaitForCallback();
2604 return;
2606 EXPECT_EQ(1u, callbacks_.size());
2607 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
2609 child->RequestCopyAsBitmap(base::Bind(
2610 &LayerTreeHostTestAsyncReadback::BitmapCallback,
2611 base::Unretained(this)));
2612 root->RequestCopyAsBitmap(base::Bind(
2613 &LayerTreeHostTestAsyncReadback::BitmapCallback,
2614 base::Unretained(this)));
2615 child->RequestCopyAsBitmap(base::Bind(
2616 &LayerTreeHostTestAsyncReadback::BitmapCallback,
2617 base::Unretained(this)));
2618 EXPECT_EQ(1u, callbacks_.size());
2619 break;
2620 case 3:
2621 if (callbacks_.size() < 4u) {
2622 WaitForCallback();
2623 return;
2625 EXPECT_EQ(4u, callbacks_.size());
2626 // The child was copied to a bitmap and passed back twice.
2627 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
2628 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
2629 // The root was copied to a bitmap and passed back also.
2630 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
2631 EndTest();
2632 break;
2636 void BitmapCallback(scoped_ptr<SkBitmap> bitmap) {
2637 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2638 EXPECT_TRUE(bitmap);
2639 callbacks_.push_back(gfx::Size(bitmap->width(), bitmap->height()));
2642 virtual void AfterTest() OVERRIDE {
2643 EXPECT_EQ(4u, callbacks_.size());
2646 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
2647 if (use_gl_renderer_)
2648 return FakeOutputSurface::Create3d().PassAs<OutputSurface>();
2649 return FakeOutputSurface::CreateSoftware(
2650 make_scoped_ptr(new SoftwareOutputDevice)).PassAs<OutputSurface>();
2653 bool use_gl_renderer_;
2654 std::vector<gfx::Size> callbacks_;
2655 FakeContentLayerClient client_;
2656 scoped_refptr<FakeContentLayer> root;
2657 scoped_refptr<FakeContentLayer> child;
2660 TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
2661 use_gl_renderer_ = true;
2662 RunTest(false);
2665 TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunMultiThread) {
2666 use_gl_renderer_ = true;
2667 RunTest(true);
2670 TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
2671 use_gl_renderer_ = false;
2672 RunTest(false);
2675 TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunMultiThread) {
2676 use_gl_renderer_ = false;
2677 RunTest(true);
2680 class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
2681 protected:
2682 virtual void SetupTree() OVERRIDE {
2683 root_ = FakeContentLayer::Create(&client_);
2684 root_->SetBounds(gfx::Size(20, 20));
2686 main_destroyed_ = FakeContentLayer::Create(&client_);
2687 main_destroyed_->SetBounds(gfx::Size(15, 15));
2688 root_->AddChild(main_destroyed_);
2690 impl_destroyed_ = FakeContentLayer::Create(&client_);
2691 impl_destroyed_->SetBounds(gfx::Size(10, 10));
2692 root_->AddChild(impl_destroyed_);
2694 layer_tree_host()->SetRootLayer(root_);
2695 LayerTreeHostTest::SetupTree();
2698 virtual void BeginTest() OVERRIDE {
2699 callback_count_ = 0;
2700 PostSetNeedsCommitToMainThread();
2703 virtual void DidCommit() OVERRIDE {
2704 int frame = layer_tree_host()->commit_number();
2705 switch (frame) {
2706 case 1:
2707 main_destroyed_->RequestCopyAsBitmap(base::Bind(
2708 &LayerTreeHostTestAsyncReadbackLayerDestroyed::BitmapCallback,
2709 base::Unretained(this)));
2710 impl_destroyed_->RequestCopyAsBitmap(base::Bind(
2711 &LayerTreeHostTestAsyncReadbackLayerDestroyed::BitmapCallback,
2712 base::Unretained(this)));
2713 EXPECT_EQ(0, callback_count_);
2715 // Destroy the main thread layer right away.
2716 main_destroyed_->RemoveFromParent();
2717 main_destroyed_ = NULL;
2719 // Should callback with a NULL bitmap.
2720 EXPECT_EQ(1, callback_count_);
2722 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
2723 layer_tree_host()->SetViewportSize(gfx::Size());
2724 break;
2725 case 2:
2726 // Flush the message loops and make sure the callbacks run.
2727 layer_tree_host()->SetNeedsCommit();
2728 break;
2729 case 3:
2730 // No drawing means no readback yet.
2731 EXPECT_EQ(1, callback_count_);
2733 // Destroy the impl thread layer.
2734 impl_destroyed_->RemoveFromParent();
2735 impl_destroyed_ = NULL;
2737 // No callback yet because it's on the impl side.
2738 EXPECT_EQ(1, callback_count_);
2739 break;
2740 case 4:
2741 // Flush the message loops and make sure the callbacks run.
2742 layer_tree_host()->SetNeedsCommit();
2743 break;
2744 case 5:
2745 // We should get another callback with a NULL bitmap.
2746 EXPECT_EQ(2, callback_count_);
2747 EndTest();
2748 break;
2752 void BitmapCallback(scoped_ptr<SkBitmap> bitmap) {
2753 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2754 EXPECT_FALSE(bitmap);
2755 ++callback_count_;
2758 virtual void AfterTest() OVERRIDE {}
2760 int callback_count_;
2761 FakeContentLayerClient client_;
2762 scoped_refptr<FakeContentLayer> root_;
2763 scoped_refptr<FakeContentLayer> main_destroyed_;
2764 scoped_refptr<FakeContentLayer> impl_destroyed_;
2767 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
2769 } // namespace
2770 } // namespace cc