Android Chromoting: Remove exit-fullscreen button.
[chromium-blink-merge.git] / ui / compositor / layer_unittest.cc
blob9ab5a14b14f46619fc9006f71a50f6370178705d
1 // Copyright (c) 2012 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 "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/compiler_specific.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/json/json_reader.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/trace_event/trace_event.h"
17 #include "cc/layers/delegated_frame_provider.h"
18 #include "cc/layers/delegated_frame_resource_collection.h"
19 #include "cc/layers/layer.h"
20 #include "cc/output/copy_output_request.h"
21 #include "cc/output/copy_output_result.h"
22 #include "cc/output/delegated_frame_data.h"
23 #include "cc/test/pixel_test_utils.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/compositor/compositor_observer.h"
26 #include "ui/compositor/dip_util.h"
27 #include "ui/compositor/layer.h"
28 #include "ui/compositor/layer_animation_sequence.h"
29 #include "ui/compositor/layer_animator.h"
30 #include "ui/compositor/test/context_factories_for_test.h"
31 #include "ui/compositor/test/draw_waiter_for_test.h"
32 #include "ui/compositor/test/test_compositor_host.h"
33 #include "ui/compositor/test/test_layers.h"
34 #include "ui/gfx/canvas.h"
35 #include "ui/gfx/codec/png_codec.h"
36 #include "ui/gfx/gfx_paths.h"
37 #include "ui/gfx/skia_util.h"
39 using cc::MatchesPNGFile;
41 namespace ui {
43 namespace {
45 // There are three test classes in here that configure the Compositor and
46 // Layer's slightly differently:
47 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
48 // is typically the base class you want to use.
49 // - LayerWithDelegateTest uses LayerDelegate on the delegates.
50 // - LayerWithRealCompositorTest when a real compositor is required for testing.
51 // - Slow because they bring up a window and run the real compositor. This
52 // is typically not what you want.
54 class ColoredLayer : public Layer, public LayerDelegate {
55 public:
56 explicit ColoredLayer(SkColor color)
57 : Layer(LAYER_TEXTURED),
58 color_(color) {
59 set_delegate(this);
62 ~ColoredLayer() override {}
64 // Overridden from LayerDelegate:
65 void OnPaintLayer(gfx::Canvas* canvas) override { canvas->DrawColor(color_); }
67 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
69 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
71 base::Closure PrepareForLayerBoundsChange() override {
72 return base::Closure();
75 private:
76 SkColor color_;
79 class LayerWithRealCompositorTest : public testing::Test {
80 public:
81 LayerWithRealCompositorTest() {
82 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
83 test_data_directory_ = test_data_directory_.AppendASCII("compositor");
84 } else {
85 LOG(ERROR) << "Could not open test data directory.";
88 ~LayerWithRealCompositorTest() override {}
90 // Overridden from testing::Test:
91 void SetUp() override {
92 bool enable_pixel_output = true;
93 ui::ContextFactory* context_factory =
94 InitializeContextFactoryForTests(enable_pixel_output);
96 const gfx::Rect host_bounds(10, 10, 500, 500);
97 compositor_host_.reset(
98 TestCompositorHost::Create(host_bounds, context_factory));
99 compositor_host_->Show();
102 void TearDown() override {
103 compositor_host_.reset();
104 TerminateContextFactoryForTests();
107 Compositor* GetCompositor() { return compositor_host_->GetCompositor(); }
109 Layer* CreateLayer(LayerType type) {
110 return new Layer(type);
113 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
114 Layer* layer = new ColoredLayer(color);
115 layer->SetBounds(bounds);
116 return layer;
119 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
120 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
121 layer->SetBounds(bounds);
122 return layer;
125 void DrawTree(Layer* root) {
126 GetCompositor()->SetRootLayer(root);
127 GetCompositor()->ScheduleDraw();
128 WaitForSwap();
131 void ReadPixels(SkBitmap* bitmap) {
132 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
135 void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) {
136 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder);
137 scoped_ptr<cc::CopyOutputRequest> request =
138 cc::CopyOutputRequest::CreateBitmapRequest(
139 base::Bind(&ReadbackHolder::OutputRequestCallback, holder));
140 request->set_area(source_rect);
142 GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass());
144 // Wait for copy response. This needs to wait as the compositor could
145 // be in the middle of a draw right now, and the commit with the
146 // copy output request may not be done on the first draw.
147 for (int i = 0; i < 2; i++) {
148 GetCompositor()->ScheduleFullRedraw();
149 WaitForDraw();
152 // Waits for the callback to finish run and return result.
153 holder->WaitForReadback();
155 *bitmap = holder->result();
158 void WaitForDraw() {
159 ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor());
162 void WaitForSwap() {
163 DrawWaiterForTest::WaitForCompositingEnded(GetCompositor());
166 void WaitForCommit() {
167 ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
170 // Invalidates the entire contents of the layer.
171 void SchedulePaintForLayer(Layer* layer) {
172 layer->SchedulePaint(
173 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
176 const base::FilePath& test_data_directory() const {
177 return test_data_directory_;
180 private:
181 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> {
182 public:
183 ReadbackHolder() : run_loop_(new base::RunLoop) {}
185 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) {
186 result_ = result->TakeBitmap();
187 run_loop_->Quit();
190 void WaitForReadback() { run_loop_->Run(); }
192 const SkBitmap& result() const { return *result_; }
194 private:
195 friend class base::RefCountedThreadSafe<ReadbackHolder>;
197 virtual ~ReadbackHolder() {}
199 scoped_ptr<SkBitmap> result_;
200 scoped_ptr<base::RunLoop> run_loop_;
203 scoped_ptr<TestCompositorHost> compositor_host_;
205 // The root directory for test files.
206 base::FilePath test_data_directory_;
208 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
211 // LayerDelegate that paints colors to the layer.
212 class TestLayerDelegate : public LayerDelegate {
213 public:
214 explicit TestLayerDelegate() { reset(); }
215 ~TestLayerDelegate() override {}
217 void AddColor(SkColor color) {
218 colors_.push_back(color);
221 int color_index() const { return color_index_; }
223 float device_scale_factor() const {
224 return device_scale_factor_;
227 // Overridden from LayerDelegate:
228 void OnPaintLayer(gfx::Canvas* canvas) override {
229 canvas->DrawColor(colors_[color_index_]);
230 color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
233 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
235 void OnDeviceScaleFactorChanged(float device_scale_factor) override {
236 device_scale_factor_ = device_scale_factor;
239 base::Closure PrepareForLayerBoundsChange() override {
240 return base::Closure();
243 void reset() {
244 color_index_ = 0;
245 device_scale_factor_ = 0.0f;
248 private:
249 std::vector<SkColor> colors_;
250 int color_index_;
251 float device_scale_factor_;
253 DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
256 // LayerDelegate that verifies that a layer was asked to update its canvas.
257 class DrawTreeLayerDelegate : public LayerDelegate {
258 public:
259 DrawTreeLayerDelegate() : painted_(false) {}
260 ~DrawTreeLayerDelegate() override {}
262 void Reset() {
263 painted_ = false;
266 bool painted() const { return painted_; }
268 private:
269 // Overridden from LayerDelegate:
270 void OnPaintLayer(gfx::Canvas* canvas) override {
271 painted_ = true;
272 canvas->DrawColor(SK_ColorWHITE);
274 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
275 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
276 base::Closure PrepareForLayerBoundsChange() override {
277 return base::Closure();
280 bool painted_;
282 DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
285 // The simplest possible layer delegate. Does nothing.
286 class NullLayerDelegate : public LayerDelegate {
287 public:
288 NullLayerDelegate() {}
289 ~NullLayerDelegate() override {}
291 private:
292 // Overridden from LayerDelegate:
293 void OnPaintLayer(gfx::Canvas* canvas) override {}
294 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
295 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
296 base::Closure PrepareForLayerBoundsChange() override {
297 return base::Closure();
300 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
303 // Remembers if it has been notified.
304 class TestCompositorObserver : public CompositorObserver {
305 public:
306 TestCompositorObserver()
307 : committed_(false), started_(false), ended_(false), aborted_(false) {}
309 bool committed() const { return committed_; }
310 bool notified() const { return started_ && ended_; }
311 bool aborted() const { return aborted_; }
313 void Reset() {
314 committed_ = false;
315 started_ = false;
316 ended_ = false;
317 aborted_ = false;
320 private:
321 void OnCompositingDidCommit(Compositor* compositor) override {
322 committed_ = true;
325 void OnCompositingStarted(Compositor* compositor,
326 base::TimeTicks start_time) override {
327 started_ = true;
330 void OnCompositingEnded(Compositor* compositor) override { ended_ = true; }
332 void OnCompositingAborted(Compositor* compositor) override {
333 aborted_ = true;
336 void OnCompositingLockStateChanged(Compositor* compositor) override {}
338 void OnCompositingShuttingDown(Compositor* compositor) override {}
340 bool committed_;
341 bool started_;
342 bool ended_;
343 bool aborted_;
345 DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
348 } // namespace
350 TEST_F(LayerWithRealCompositorTest, Draw) {
351 scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
352 gfx::Rect(20, 20, 50, 50)));
353 DrawTree(layer.get());
356 // Create this hierarchy:
357 // L1 - red
358 // +-- L2 - blue
359 // | +-- L3 - yellow
360 // +-- L4 - magenta
362 TEST_F(LayerWithRealCompositorTest, Hierarchy) {
363 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
364 gfx::Rect(20, 20, 400, 400)));
365 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
366 gfx::Rect(10, 10, 350, 350)));
367 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
368 gfx::Rect(5, 5, 25, 25)));
369 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
370 gfx::Rect(300, 300, 100, 100)));
372 l1->Add(l2.get());
373 l1->Add(l4.get());
374 l2->Add(l3.get());
376 DrawTree(l1.get());
379 class LayerWithDelegateTest : public testing::Test {
380 public:
381 LayerWithDelegateTest() {}
382 ~LayerWithDelegateTest() override {}
384 // Overridden from testing::Test:
385 void SetUp() override {
386 bool enable_pixel_output = false;
387 ui::ContextFactory* context_factory =
388 InitializeContextFactoryForTests(enable_pixel_output);
390 const gfx::Rect host_bounds(1000, 1000);
391 compositor_host_.reset(TestCompositorHost::Create(host_bounds,
392 context_factory));
393 compositor_host_->Show();
396 void TearDown() override {
397 compositor_host_.reset();
398 TerminateContextFactoryForTests();
401 Compositor* compositor() { return compositor_host_->GetCompositor(); }
403 virtual Layer* CreateLayer(LayerType type) {
404 return new Layer(type);
407 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
408 Layer* layer = new ColoredLayer(color);
409 layer->SetBounds(bounds);
410 return layer;
413 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
414 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
415 layer->SetBounds(bounds);
416 return layer;
419 void DrawTree(Layer* root) {
420 compositor()->SetRootLayer(root);
421 Draw();
424 // Invalidates the entire contents of the layer.
425 void SchedulePaintForLayer(Layer* layer) {
426 layer->SchedulePaint(
427 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
430 // Invokes DrawTree on the compositor.
431 void Draw() {
432 compositor()->ScheduleDraw();
433 WaitForDraw();
436 void WaitForDraw() {
437 DrawWaiterForTest::WaitForCompositingStarted(compositor());
440 void WaitForCommit() {
441 DrawWaiterForTest::WaitForCommit(compositor());
444 private:
445 scoped_ptr<TestCompositorHost> compositor_host_;
447 DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
450 // L1
451 // +-- L2
452 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
453 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
454 gfx::Rect(20, 20, 400, 400)));
455 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
456 gfx::Rect(10, 10, 350, 350)));
457 l1->Add(l2.get());
458 DrawTree(l1.get());
460 gfx::Point point1_in_l2_coords(5, 5);
461 Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
462 gfx::Point point1_in_l1_coords(15, 15);
463 EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
465 gfx::Point point2_in_l1_coords(5, 5);
466 Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
467 gfx::Point point2_in_l2_coords(-5, -5);
468 EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
471 // L1
472 // +-- L2
473 // +-- L3
474 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
475 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
476 gfx::Rect(20, 20, 400, 400)));
477 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
478 gfx::Rect(10, 10, 350, 350)));
479 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
480 gfx::Rect(10, 10, 100, 100)));
481 l1->Add(l2.get());
482 l2->Add(l3.get());
483 DrawTree(l1.get());
485 gfx::Point point1_in_l3_coords(5, 5);
486 Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
487 gfx::Point point1_in_l1_coords(25, 25);
488 EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
490 gfx::Point point2_in_l1_coords(5, 5);
491 Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
492 gfx::Point point2_in_l3_coords(-15, -15);
493 EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
496 TEST_F(LayerWithRealCompositorTest, Delegate) {
497 // This test makes sure that whenever paint happens at a layer, its layer
498 // delegate gets the paint, which in this test update its color and
499 // |color_index|.
500 scoped_ptr<Layer> l1(
501 CreateColorLayer(SK_ColorBLACK, gfx::Rect(20, 20, 400, 400)));
502 GetCompositor()->SetRootLayer(l1.get());
503 WaitForDraw();
505 TestLayerDelegate delegate;
506 l1->set_delegate(&delegate);
507 delegate.AddColor(SK_ColorWHITE);
508 delegate.AddColor(SK_ColorYELLOW);
509 delegate.AddColor(SK_ColorGREEN);
511 l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
512 WaitForDraw();
513 // Test that paint happened at layer delegate.
514 EXPECT_EQ(1, delegate.color_index());
516 l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
517 WaitForDraw();
518 // Test that paint happened at layer delegate.
519 EXPECT_EQ(2, delegate.color_index());
521 l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
522 WaitForDraw();
523 // Test that paint happened at layer delegate.
524 EXPECT_EQ(0, delegate.color_index());
527 TEST_F(LayerWithRealCompositorTest, DrawTree) {
528 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
529 gfx::Rect(20, 20, 400, 400)));
530 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
531 gfx::Rect(10, 10, 350, 350)));
532 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
533 gfx::Rect(10, 10, 100, 100)));
534 l1->Add(l2.get());
535 l2->Add(l3.get());
537 GetCompositor()->SetRootLayer(l1.get());
538 WaitForDraw();
540 DrawTreeLayerDelegate d1;
541 l1->set_delegate(&d1);
542 DrawTreeLayerDelegate d2;
543 l2->set_delegate(&d2);
544 DrawTreeLayerDelegate d3;
545 l3->set_delegate(&d3);
547 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
548 WaitForDraw();
549 EXPECT_FALSE(d1.painted());
550 EXPECT_TRUE(d2.painted());
551 EXPECT_FALSE(d3.painted());
554 // Tests no-texture Layers.
555 // Create this hierarchy:
556 // L1 - red
557 // +-- L2 - NO TEXTURE
558 // | +-- L3 - yellow
559 // +-- L4 - magenta
561 TEST_F(LayerWithRealCompositorTest, HierarchyNoTexture) {
562 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
563 gfx::Rect(20, 20, 400, 400)));
564 scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
565 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
566 gfx::Rect(5, 5, 25, 25)));
567 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
568 gfx::Rect(300, 300, 100, 100)));
570 l1->Add(l2.get());
571 l1->Add(l4.get());
572 l2->Add(l3.get());
574 GetCompositor()->SetRootLayer(l1.get());
575 WaitForDraw();
577 DrawTreeLayerDelegate d2;
578 l2->set_delegate(&d2);
579 DrawTreeLayerDelegate d3;
580 l3->set_delegate(&d3);
582 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
583 l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
584 WaitForDraw();
586 // |d2| should not have received a paint notification since it has no texture.
587 EXPECT_FALSE(d2.painted());
588 // |d3| should have received a paint notification.
589 EXPECT_TRUE(d3.painted());
592 class LayerWithNullDelegateTest : public LayerWithDelegateTest {
593 public:
594 LayerWithNullDelegateTest() {}
595 ~LayerWithNullDelegateTest() override {}
597 void SetUp() override {
598 LayerWithDelegateTest::SetUp();
599 default_layer_delegate_.reset(new NullLayerDelegate());
602 Layer* CreateLayer(LayerType type) override {
603 Layer* layer = new Layer(type);
604 layer->set_delegate(default_layer_delegate_.get());
605 return layer;
608 Layer* CreateTextureRootLayer(const gfx::Rect& bounds) {
609 Layer* layer = CreateTextureLayer(bounds);
610 compositor()->SetRootLayer(layer);
611 return layer;
614 Layer* CreateTextureLayer(const gfx::Rect& bounds) {
615 Layer* layer = CreateLayer(LAYER_TEXTURED);
616 layer->SetBounds(bounds);
617 return layer;
620 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) override {
621 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
622 layer->SetBounds(bounds);
623 return layer;
626 private:
627 scoped_ptr<NullLayerDelegate> default_layer_delegate_;
629 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
632 TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) {
633 scoped_ptr<Layer> layer(CreateLayer(LAYER_NOT_DRAWN));
634 std::string name = "\"\'\\/\b\f\n\r\t\n";
635 layer->set_name(name);
636 scoped_refptr<base::trace_event::ConvertableToTraceFormat> debug_info =
637 layer->TakeDebugInfo();
638 EXPECT_TRUE(!!debug_info.get());
639 std::string json;
640 debug_info->AppendAsTraceFormat(&json);
641 base::JSONReader json_reader;
642 scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(json));
643 EXPECT_TRUE(!!debug_info_value);
644 EXPECT_TRUE(debug_info_value->IsType(base::Value::TYPE_DICTIONARY));
645 base::DictionaryValue* dictionary = 0;
646 EXPECT_TRUE(debug_info_value->GetAsDictionary(&dictionary));
647 std::string roundtrip;
648 EXPECT_TRUE(dictionary->GetString("layer_name", &roundtrip));
649 EXPECT_EQ(name, roundtrip);
652 void ReturnMailbox(bool* run, uint32 sync_point, bool is_lost) {
653 *run = true;
656 TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
657 scoped_ptr<Layer> l1(CreateLayer(LAYER_SOLID_COLOR));
658 l1->SetFillsBoundsOpaquely(true);
659 l1->SetForceRenderSurface(true);
660 l1->SetVisible(false);
661 l1->SetBounds(gfx::Rect(4, 5));
663 EXPECT_EQ(gfx::Point3F(), l1->cc_layer()->transform_origin());
664 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
665 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
666 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
667 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
668 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer()->bounds());
670 cc::Layer* before_layer = l1->cc_layer();
672 bool callback1_run = false;
673 cc::TextureMailbox mailbox(gpu::Mailbox::Generate(), 0, 0);
674 l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(
675 base::Bind(ReturnMailbox, &callback1_run)),
676 gfx::Size(10, 10));
678 EXPECT_NE(before_layer, l1->cc_layer());
680 EXPECT_EQ(gfx::Point3F(), l1->cc_layer()->transform_origin());
681 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
682 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
683 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
684 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
685 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer()->bounds());
686 EXPECT_FALSE(callback1_run);
688 bool callback2_run = false;
689 mailbox = cc::TextureMailbox(gpu::Mailbox::Generate(), 0, 0);
690 l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(
691 base::Bind(ReturnMailbox, &callback2_run)),
692 gfx::Size(10, 10));
693 EXPECT_TRUE(callback1_run);
694 EXPECT_FALSE(callback2_run);
696 // Show solid color instead.
697 l1->SetShowSolidColorContent();
698 EXPECT_EQ(gfx::Point3F(), l1->cc_layer()->transform_origin());
699 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
700 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
701 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
702 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
703 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer()->bounds());
704 EXPECT_TRUE(callback2_run);
706 before_layer = l1->cc_layer();
708 // Back to a texture, without changing the bounds of the layer or the texture.
709 bool callback3_run = false;
710 mailbox = cc::TextureMailbox(gpu::Mailbox::Generate(), 0, 0);
711 l1->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(
712 base::Bind(ReturnMailbox, &callback3_run)),
713 gfx::Size(10, 10));
715 EXPECT_NE(before_layer, l1->cc_layer());
717 EXPECT_EQ(gfx::Point3F(), l1->cc_layer()->transform_origin());
718 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
719 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
720 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
721 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
722 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer()->bounds());
723 EXPECT_FALSE(callback3_run);
725 // Release the on |l1| mailbox to clean up the test.
726 l1->SetShowSolidColorContent();
729 // Various visibile/drawn assertions.
730 TEST_F(LayerWithNullDelegateTest, Visibility) {
731 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
732 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
733 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
734 l1->Add(l2.get());
735 l2->Add(l3.get());
737 NullLayerDelegate delegate;
738 l1->set_delegate(&delegate);
739 l2->set_delegate(&delegate);
740 l3->set_delegate(&delegate);
742 // Layers should initially be drawn.
743 EXPECT_TRUE(l1->IsDrawn());
744 EXPECT_TRUE(l2->IsDrawn());
745 EXPECT_TRUE(l3->IsDrawn());
746 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
747 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
748 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
750 compositor()->SetRootLayer(l1.get());
752 Draw();
754 l1->SetVisible(false);
755 EXPECT_FALSE(l1->IsDrawn());
756 EXPECT_FALSE(l2->IsDrawn());
757 EXPECT_FALSE(l3->IsDrawn());
758 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
759 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
760 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
762 l3->SetVisible(false);
763 EXPECT_FALSE(l1->IsDrawn());
764 EXPECT_FALSE(l2->IsDrawn());
765 EXPECT_FALSE(l3->IsDrawn());
766 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
767 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
768 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
770 l1->SetVisible(true);
771 EXPECT_TRUE(l1->IsDrawn());
772 EXPECT_TRUE(l2->IsDrawn());
773 EXPECT_FALSE(l3->IsDrawn());
774 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
775 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
776 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
779 // Checks that stacking-related methods behave as advertised.
780 TEST_F(LayerWithNullDelegateTest, Stacking) {
781 scoped_ptr<Layer> root(new Layer(LAYER_NOT_DRAWN));
782 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
783 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
784 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
785 l1->set_name("1");
786 l2->set_name("2");
787 l3->set_name("3");
788 root->Add(l3.get());
789 root->Add(l2.get());
790 root->Add(l1.get());
792 // Layers' children are stored in bottom-to-top order.
793 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
795 root->StackAtTop(l3.get());
796 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
798 root->StackAtTop(l1.get());
799 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
801 root->StackAtTop(l1.get());
802 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
804 root->StackAbove(l2.get(), l3.get());
805 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
807 root->StackAbove(l1.get(), l3.get());
808 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
810 root->StackAbove(l2.get(), l1.get());
811 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
813 root->StackAtBottom(l2.get());
814 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
816 root->StackAtBottom(l3.get());
817 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
819 root->StackAtBottom(l3.get());
820 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
822 root->StackBelow(l2.get(), l3.get());
823 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
825 root->StackBelow(l1.get(), l3.get());
826 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
828 root->StackBelow(l3.get(), l2.get());
829 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
831 root->StackBelow(l3.get(), l2.get());
832 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
834 root->StackBelow(l3.get(), l1.get());
835 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
838 // Verifies SetBounds triggers the appropriate painting/drawing.
839 TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
840 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
841 compositor()->SetRootLayer(l1.get());
843 Draw();
845 l1->SetBounds(gfx::Rect(5, 5, 200, 200));
847 // The CompositorDelegate (us) should have been told to draw for a move.
848 WaitForDraw();
850 l1->SetBounds(gfx::Rect(5, 5, 100, 100));
852 // The CompositorDelegate (us) should have been told to draw for a resize.
853 WaitForDraw();
856 void ExpectRgba(int x, int y, SkColor expected_color, SkColor actual_color) {
857 EXPECT_EQ(expected_color, actual_color)
858 << "Pixel error at x=" << x << " y=" << y << "; "
859 << "actual RGBA=("
860 << SkColorGetR(actual_color) << ","
861 << SkColorGetG(actual_color) << ","
862 << SkColorGetB(actual_color) << ","
863 << SkColorGetA(actual_color) << "); "
864 << "expected RGBA=("
865 << SkColorGetR(expected_color) << ","
866 << SkColorGetG(expected_color) << ","
867 << SkColorGetB(expected_color) << ","
868 << SkColorGetA(expected_color) << ")";
871 // Checks that pixels are actually drawn to the screen with a read back.
872 TEST_F(LayerWithRealCompositorTest, DrawPixels) {
873 gfx::Size viewport_size = GetCompositor()->size();
875 // The window should be some non-trivial size but may not be exactly
876 // 500x500 on all platforms/bots.
877 EXPECT_GE(viewport_size.width(), 200);
878 EXPECT_GE(viewport_size.height(), 200);
880 int blue_height = 10;
882 scoped_ptr<Layer> layer(
883 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
884 scoped_ptr<Layer> layer2(
885 CreateColorLayer(SK_ColorBLUE,
886 gfx::Rect(0, 0, viewport_size.width(), blue_height)));
888 layer->Add(layer2.get());
890 DrawTree(layer.get());
892 SkBitmap bitmap;
893 ReadPixels(&bitmap, gfx::Rect(viewport_size));
894 ASSERT_FALSE(bitmap.empty());
896 SkAutoLockPixels lock(bitmap);
897 for (int x = 0; x < viewport_size.width(); x++) {
898 for (int y = 0; y < viewport_size.height(); y++) {
899 SkColor actual_color = bitmap.getColor(x, y);
900 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
901 ExpectRgba(x, y, expected_color, actual_color);
906 // Checks that drawing a layer with transparent pixels is blended correctly
907 // with the lower layer.
908 TEST_F(LayerWithRealCompositorTest, DrawAlphaBlendedPixels) {
909 gfx::Size viewport_size = GetCompositor()->size();
911 int test_size = 200;
912 EXPECT_GE(viewport_size.width(), test_size);
913 EXPECT_GE(viewport_size.height(), test_size);
915 // Blue with a wee bit of transparency.
916 SkColor blue_with_alpha = SkColorSetARGBInline(40, 10, 20, 200);
917 SkColor blend_color = SkColorSetARGBInline(255, 216, 3, 32);
919 scoped_ptr<Layer> background_layer(
920 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
921 scoped_ptr<Layer> foreground_layer(
922 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size)));
924 // This must be set to false for layers with alpha to be blended correctly.
925 foreground_layer->SetFillsBoundsOpaquely(false);
927 background_layer->Add(foreground_layer.get());
928 DrawTree(background_layer.get());
930 SkBitmap bitmap;
931 ReadPixels(&bitmap, gfx::Rect(viewport_size));
932 ASSERT_FALSE(bitmap.empty());
934 SkAutoLockPixels lock(bitmap);
935 for (int x = 0; x < test_size; x++) {
936 for (int y = 0; y < test_size; y++) {
937 SkColor actual_color = bitmap.getColor(x, y);
938 ExpectRgba(x, y, blend_color, actual_color);
943 // Checks that using the AlphaShape filter applied to a layer with
944 // transparency, alpha-blends properly with the layer below.
945 TEST_F(LayerWithRealCompositorTest, DrawAlphaThresholdFilterPixels) {
946 gfx::Size viewport_size = GetCompositor()->size();
948 int test_size = 200;
949 EXPECT_GE(viewport_size.width(), test_size);
950 EXPECT_GE(viewport_size.height(), test_size);
952 int blue_height = 10;
953 SkColor blue_with_alpha = SkColorSetARGBInline(40, 0, 0, 255);
954 SkColor blend_color = SkColorSetARGBInline(255, 215, 0, 40);
956 scoped_ptr<Layer> background_layer(
957 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
958 scoped_ptr<Layer> foreground_layer(
959 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size)));
961 // Add a shape to restrict the visible part of the layer.
962 SkRegion shape;
963 shape.setRect(0, 0, viewport_size.width(), blue_height);
964 foreground_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(shape)));
966 foreground_layer->SetFillsBoundsOpaquely(false);
968 background_layer->Add(foreground_layer.get());
969 DrawTree(background_layer.get());
971 SkBitmap bitmap;
972 ReadPixels(&bitmap, gfx::Rect(viewport_size));
973 ASSERT_FALSE(bitmap.empty());
975 SkAutoLockPixels lock(bitmap);
976 for (int x = 0; x < test_size; x++) {
977 for (int y = 0; y < test_size; y++) {
978 SkColor actual_color = bitmap.getColor(x, y);
979 ExpectRgba(x, y, actual_color,
980 y < blue_height ? blend_color : SK_ColorRED);
985 // Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
986 TEST_F(LayerWithRealCompositorTest, SetRootLayer) {
987 Compositor* compositor = GetCompositor();
988 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
989 gfx::Rect(20, 20, 400, 400)));
990 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
991 gfx::Rect(10, 10, 350, 350)));
993 EXPECT_EQ(NULL, l1->GetCompositor());
994 EXPECT_EQ(NULL, l2->GetCompositor());
996 compositor->SetRootLayer(l1.get());
997 EXPECT_EQ(compositor, l1->GetCompositor());
999 l1->Add(l2.get());
1000 EXPECT_EQ(compositor, l2->GetCompositor());
1002 l1->Remove(l2.get());
1003 EXPECT_EQ(NULL, l2->GetCompositor());
1005 l1->Add(l2.get());
1006 EXPECT_EQ(compositor, l2->GetCompositor());
1008 compositor->SetRootLayer(NULL);
1009 EXPECT_EQ(NULL, l1->GetCompositor());
1010 EXPECT_EQ(NULL, l2->GetCompositor());
1013 // Checks that compositor observers are notified when:
1014 // - DrawTree is called,
1015 // - After ScheduleDraw is called, or
1016 // - Whenever SetBounds, SetOpacity or SetTransform are called.
1017 // TODO(vollick): could be reorganized into compositor_unittest.cc
1018 TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
1019 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
1020 gfx::Rect(20, 20, 400, 400)));
1021 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
1022 gfx::Rect(10, 10, 350, 350)));
1023 l1->Add(l2.get());
1024 TestCompositorObserver observer;
1025 GetCompositor()->AddObserver(&observer);
1027 // Explicitly called DrawTree should cause the observers to be notified.
1028 // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
1029 DrawTree(l1.get());
1030 EXPECT_TRUE(observer.notified());
1032 // ScheduleDraw without any visible change should cause a commit.
1033 observer.Reset();
1034 l1->ScheduleDraw();
1035 WaitForCommit();
1036 EXPECT_TRUE(observer.committed());
1038 // Moving, but not resizing, a layer should alert the observers.
1039 observer.Reset();
1040 l2->SetBounds(gfx::Rect(0, 0, 350, 350));
1041 WaitForSwap();
1042 EXPECT_TRUE(observer.notified());
1044 // So should resizing a layer.
1045 observer.Reset();
1046 l2->SetBounds(gfx::Rect(0, 0, 400, 400));
1047 WaitForSwap();
1048 EXPECT_TRUE(observer.notified());
1050 // Opacity changes should alert the observers.
1051 observer.Reset();
1052 l2->SetOpacity(0.5f);
1053 WaitForSwap();
1054 EXPECT_TRUE(observer.notified());
1056 // So should setting the opacity back.
1057 observer.Reset();
1058 l2->SetOpacity(1.0f);
1059 WaitForSwap();
1060 EXPECT_TRUE(observer.notified());
1062 // Setting the transform of a layer should alert the observers.
1063 observer.Reset();
1064 gfx::Transform transform;
1065 transform.Translate(200.0, 200.0);
1066 transform.Rotate(90.0);
1067 transform.Translate(-200.0, -200.0);
1068 l2->SetTransform(transform);
1069 WaitForSwap();
1070 EXPECT_TRUE(observer.notified());
1072 // A change resulting in an aborted swap buffer should alert the observer
1073 // and also signal an abort.
1074 observer.Reset();
1075 l2->SetOpacity(0.1f);
1076 GetCompositor()->DidAbortSwapBuffers();
1077 WaitForSwap();
1078 EXPECT_TRUE(observer.notified());
1079 EXPECT_TRUE(observer.aborted());
1081 GetCompositor()->RemoveObserver(&observer);
1083 // Opacity changes should no longer alert the removed observer.
1084 observer.Reset();
1085 l2->SetOpacity(0.5f);
1086 WaitForSwap();
1088 EXPECT_FALSE(observer.notified());
1091 // Checks that modifying the hierarchy correctly affects final composite.
1092 TEST_F(LayerWithRealCompositorTest, ModifyHierarchy) {
1093 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1095 // l0
1096 // +-l11
1097 // | +-l21
1098 // +-l12
1099 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1100 gfx::Rect(0, 0, 50, 50)));
1101 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1102 gfx::Rect(0, 0, 25, 25)));
1103 scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA,
1104 gfx::Rect(0, 0, 15, 15)));
1105 scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE,
1106 gfx::Rect(10, 10, 25, 25)));
1108 base::FilePath ref_img1 =
1109 test_data_directory().AppendASCII("ModifyHierarchy1.png");
1110 base::FilePath ref_img2 =
1111 test_data_directory().AppendASCII("ModifyHierarchy2.png");
1112 SkBitmap bitmap;
1114 l0->Add(l11.get());
1115 l11->Add(l21.get());
1116 l0->Add(l12.get());
1117 DrawTree(l0.get());
1118 ReadPixels(&bitmap);
1119 ASSERT_FALSE(bitmap.empty());
1120 // WritePNGFile(bitmap, ref_img1);
1121 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1123 l0->StackAtTop(l11.get());
1124 DrawTree(l0.get());
1125 ReadPixels(&bitmap);
1126 ASSERT_FALSE(bitmap.empty());
1127 // WritePNGFile(bitmap, ref_img2);
1128 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1130 // should restore to original configuration
1131 l0->StackAbove(l12.get(), l11.get());
1132 DrawTree(l0.get());
1133 ReadPixels(&bitmap);
1134 ASSERT_FALSE(bitmap.empty());
1135 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1137 // l11 back to front
1138 l0->StackAtTop(l11.get());
1139 DrawTree(l0.get());
1140 ReadPixels(&bitmap);
1141 ASSERT_FALSE(bitmap.empty());
1142 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1144 // should restore to original configuration
1145 l0->StackAbove(l12.get(), l11.get());
1146 DrawTree(l0.get());
1147 ReadPixels(&bitmap);
1148 ASSERT_FALSE(bitmap.empty());
1149 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1151 // l11 back to front
1152 l0->StackAbove(l11.get(), l12.get());
1153 DrawTree(l0.get());
1154 ReadPixels(&bitmap);
1155 ASSERT_FALSE(bitmap.empty());
1156 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1159 // Opacity is rendered correctly.
1160 // Checks that modifying the hierarchy correctly affects final composite.
1161 TEST_F(LayerWithRealCompositorTest, Opacity) {
1162 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1164 // l0
1165 // +-l11
1166 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1167 gfx::Rect(0, 0, 50, 50)));
1168 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1169 gfx::Rect(0, 0, 25, 25)));
1171 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
1173 l11->SetOpacity(0.75);
1174 l0->Add(l11.get());
1175 DrawTree(l0.get());
1176 SkBitmap bitmap;
1177 ReadPixels(&bitmap);
1178 ASSERT_FALSE(bitmap.empty());
1179 // WritePNGFile(bitmap, ref_img);
1180 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
1183 namespace {
1185 class SchedulePaintLayerDelegate : public LayerDelegate {
1186 public:
1187 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
1189 ~SchedulePaintLayerDelegate() override {}
1191 void set_layer(Layer* layer) {
1192 layer_ = layer;
1193 layer_->set_delegate(this);
1196 void SetSchedulePaintRect(const gfx::Rect& rect) {
1197 schedule_paint_rect_ = rect;
1200 int GetPaintCountAndClear() {
1201 int value = paint_count_;
1202 paint_count_ = 0;
1203 return value;
1206 const gfx::RectF& last_clip_rect() const { return last_clip_rect_; }
1208 private:
1209 // Overridden from LayerDelegate:
1210 void OnPaintLayer(gfx::Canvas* canvas) override {
1211 paint_count_++;
1212 if (!schedule_paint_rect_.IsEmpty()) {
1213 layer_->SchedulePaint(schedule_paint_rect_);
1214 schedule_paint_rect_ = gfx::Rect();
1216 SkRect sk_clip_rect;
1217 if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
1218 last_clip_rect_ = gfx::SkRectToRectF(sk_clip_rect);
1221 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
1223 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
1225 base::Closure PrepareForLayerBoundsChange() override {
1226 return base::Closure();
1229 int paint_count_;
1230 Layer* layer_;
1231 gfx::Rect schedule_paint_rect_;
1232 gfx::RectF last_clip_rect_;
1234 DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
1237 } // namespace
1239 // Verifies that if SchedulePaint is invoked during painting the layer is still
1240 // marked dirty.
1241 TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
1242 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorRED,
1243 gfx::Rect(0, 0, 500, 500)));
1244 SchedulePaintLayerDelegate child_delegate;
1245 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorBLUE,
1246 gfx::Rect(0, 0, 200, 200)));
1247 child_delegate.set_layer(child.get());
1249 root->Add(child.get());
1251 SchedulePaintForLayer(root.get());
1252 DrawTree(root.get());
1253 child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
1254 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1256 // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
1257 // again.
1258 child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
1259 WaitForCommit();
1260 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1262 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
1263 // still need to be painted.
1264 WaitForCommit();
1265 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1266 EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
1267 gfx::Rect(10, 10, 30, 30)));
1270 TEST_F(LayerWithRealCompositorTest, ScaleUpDown) {
1271 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1272 gfx::Rect(10, 20, 200, 220)));
1273 TestLayerDelegate root_delegate;
1274 root_delegate.AddColor(SK_ColorWHITE);
1275 root->set_delegate(&root_delegate);
1277 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1278 gfx::Rect(10, 20, 140, 180)));
1279 TestLayerDelegate l1_delegate;
1280 l1_delegate.AddColor(SK_ColorWHITE);
1281 l1->set_delegate(&l1_delegate);
1283 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1284 GetCompositor()->SetRootLayer(root.get());
1285 root->Add(l1.get());
1286 WaitForDraw();
1288 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1289 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1290 gfx::Size cc_bounds_size = root->cc_layer()->bounds();
1291 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1292 cc_bounds_size = l1->cc_layer()->bounds();
1293 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1294 // No scale change, so no scale notification.
1295 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1296 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1298 // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
1299 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1300 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1301 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1302 // CC layer should still match the UI layer bounds.
1303 cc_bounds_size = root->cc_layer()->bounds();
1304 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1305 cc_bounds_size = l1->cc_layer()->bounds();
1306 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1307 // New scale factor must have been notified. Make sure painting happens at
1308 // right scale.
1309 EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
1310 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1312 // Scale down back to 1.0f.
1313 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1314 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1315 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1316 // CC layer should still match the UI layer bounds.
1317 cc_bounds_size = root->cc_layer()->bounds();
1318 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1319 cc_bounds_size = l1->cc_layer()->bounds();
1320 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1321 // New scale factor must have been notified. Make sure painting happens at
1322 // right scale.
1323 EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
1324 EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
1326 root_delegate.reset();
1327 l1_delegate.reset();
1328 // Just changing the size shouldn't notify the scale change nor
1329 // trigger repaint.
1330 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
1331 // No scale change, so no scale notification.
1332 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1333 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1336 TEST_F(LayerWithRealCompositorTest, ScaleReparent) {
1337 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1338 gfx::Rect(10, 20, 200, 220)));
1339 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1340 gfx::Rect(10, 20, 140, 180)));
1341 TestLayerDelegate l1_delegate;
1342 l1_delegate.AddColor(SK_ColorWHITE);
1343 l1->set_delegate(&l1_delegate);
1345 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1346 GetCompositor()->SetRootLayer(root.get());
1348 root->Add(l1.get());
1349 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1350 gfx::Size cc_bounds_size = l1->cc_layer()->bounds();
1351 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1352 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1354 // Remove l1 from root and change the scale.
1355 root->Remove(l1.get());
1356 EXPECT_EQ(NULL, l1->parent());
1357 EXPECT_EQ(NULL, l1->GetCompositor());
1358 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1359 // Sanity check on root and l1.
1360 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1361 cc_bounds_size = l1->cc_layer()->bounds();
1362 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1364 root->Add(l1.get());
1365 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1366 cc_bounds_size = l1->cc_layer()->bounds();
1367 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1368 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1371 // Verifies that when changing bounds on a layer that is invisible, and then
1372 // made visible, the right thing happens:
1373 // - if just a move, then no painting should happen.
1374 // - if a resize, the layer should be repainted.
1375 TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
1376 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1378 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1379 child->SetBounds(gfx::Rect(0, 0, 500, 500));
1380 DrawTreeLayerDelegate delegate;
1381 child->set_delegate(&delegate);
1382 root->Add(child.get());
1384 // Paint once for initial damage.
1385 child->SetVisible(true);
1386 DrawTree(root.get());
1388 // Reset into invisible state.
1389 child->SetVisible(false);
1390 DrawTree(root.get());
1391 delegate.Reset();
1393 // Move layer.
1394 child->SetBounds(gfx::Rect(200, 200, 500, 500));
1395 child->SetVisible(true);
1396 DrawTree(root.get());
1397 EXPECT_FALSE(delegate.painted());
1399 // Reset into invisible state.
1400 child->SetVisible(false);
1401 DrawTree(root.get());
1402 delegate.Reset();
1404 // Resize layer.
1405 child->SetBounds(gfx::Rect(200, 200, 400, 400));
1406 child->SetVisible(true);
1407 DrawTree(root.get());
1408 EXPECT_TRUE(delegate.painted());
1411 static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) {
1412 scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
1413 scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create());
1414 render_pass->SetNew(
1415 cc::RenderPassId(1, 1), gfx::Rect(size), gfx::Rect(), gfx::Transform());
1416 frame_data->render_pass_list.push_back(render_pass.Pass());
1417 return frame_data.Pass();
1420 TEST_F(LayerWithDelegateTest, DelegatedLayer) {
1421 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1423 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1425 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1426 child->SetVisible(true);
1427 root->Add(child.get());
1428 DrawTree(root.get());
1430 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1431 new cc::DelegatedFrameResourceCollection;
1432 scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
1434 // Content matches layer size.
1435 frame_provider = new cc::DelegatedFrameProvider(
1436 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1437 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1438 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1439 gfx::Size(10, 10).ToString());
1441 // Content larger than layer.
1442 child->SetBounds(gfx::Rect(0, 0, 5, 5));
1443 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1444 gfx::Size(5, 5).ToString());
1446 // Content smaller than layer.
1447 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1448 frame_provider = new cc::DelegatedFrameProvider(
1449 resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
1450 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(5, 5));
1451 EXPECT_EQ(child->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
1453 // Hi-DPI content on low-DPI layer.
1454 frame_provider = new cc::DelegatedFrameProvider(
1455 resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
1456 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1457 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1458 gfx::Size(10, 10).ToString());
1460 // Hi-DPI content on hi-DPI layer.
1461 compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000));
1462 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1463 gfx::Size(10, 10).ToString());
1465 // Low-DPI content on hi-DPI layer.
1466 frame_provider = new cc::DelegatedFrameProvider(
1467 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1468 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1469 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1470 gfx::Size(10, 10).ToString());
1473 TEST_F(LayerWithDelegateTest, ExternalContent) {
1474 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1475 scoped_ptr<Layer> child(CreateLayer(LAYER_SOLID_COLOR));
1477 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1478 child->SetVisible(true);
1479 root->Add(child.get());
1481 // The layer is already showing solid color content, so the cc layer won't
1482 // change.
1483 scoped_refptr<cc::Layer> before = child->cc_layer();
1484 child->SetShowSolidColorContent();
1485 EXPECT_TRUE(child->cc_layer());
1486 EXPECT_EQ(before.get(), child->cc_layer());
1488 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1489 new cc::DelegatedFrameResourceCollection;
1490 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1491 new cc::DelegatedFrameProvider(resource_collection.get(),
1492 MakeFrameData(gfx::Size(10, 10)));
1494 // Showing delegated content changes the underlying cc layer.
1495 before = child->cc_layer();
1496 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1497 EXPECT_TRUE(child->cc_layer());
1498 EXPECT_NE(before.get(), child->cc_layer());
1500 // Changing to painted content should change the underlying cc layer.
1501 before = child->cc_layer();
1502 child->SetShowSolidColorContent();
1503 EXPECT_TRUE(child->cc_layer());
1504 EXPECT_NE(before.get(), child->cc_layer());
1507 // Verifies that layer filters still attached after changing implementation
1508 // layer.
1509 TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
1510 scoped_ptr<Layer> layer(CreateLayer(LAYER_TEXTURED));
1511 layer->SetBounds(gfx::Rect(0, 0, 10, 10));
1512 EXPECT_TRUE(layer->cc_layer());
1513 EXPECT_EQ(0u, layer->cc_layer()->filters().size());
1515 layer->SetLayerGrayscale(0.5f);
1516 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
1517 EXPECT_EQ(1u, layer->cc_layer()->filters().size());
1519 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1520 new cc::DelegatedFrameResourceCollection;
1521 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1522 new cc::DelegatedFrameProvider(resource_collection.get(),
1523 MakeFrameData(gfx::Size(10, 10)));
1525 // Showing delegated content changes the underlying cc layer.
1526 scoped_refptr<cc::Layer> before = layer->cc_layer();
1527 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1528 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
1529 EXPECT_TRUE(layer->cc_layer());
1530 EXPECT_NE(before.get(), layer->cc_layer());
1531 EXPECT_EQ(1u, layer->cc_layer()->filters().size());
1534 // Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
1535 TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
1536 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1537 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1538 scoped_ptr<Layer> l2(CreateLayer(LAYER_TEXTURED));
1540 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1541 l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1543 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1545 // Trigger a threaded animation.
1546 l1->SetOpacity(0.5f);
1548 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1550 // Ensure we can remove a pending threaded animation.
1551 l1->GetAnimator()->StopAnimating();
1553 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1555 // Trigger another threaded animation.
1556 l1->SetOpacity(0.2f);
1558 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1560 root->Add(l1.get());
1561 GetCompositor()->SetRootLayer(root.get());
1563 // Now that l1 is part of a tree, it should have dispatched the pending
1564 // animation.
1565 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1567 // Ensure that l1 no longer holds on to animations.
1568 l1->SetOpacity(0.1f);
1569 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1571 // Ensure that adding a layer to an existing tree causes its pending
1572 // animations to get dispatched.
1573 l2->SetOpacity(0.5f);
1574 EXPECT_TRUE(l2->HasPendingThreadedAnimations());
1576 l1->Add(l2.get());
1577 EXPECT_FALSE(l2->HasPendingThreadedAnimations());
1580 // Tests that in-progress threaded animations complete when a Layer's
1581 // cc::Layer changes.
1582 TEST_F(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
1583 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1584 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1585 GetCompositor()->SetRootLayer(root.get());
1586 root->Add(l1.get());
1588 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1590 EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
1592 // Trigger a threaded animation.
1593 l1->SetOpacity(0.5f);
1595 // Change l1's cc::Layer.
1596 l1->SwitchCCLayerForTest();
1598 // Ensure that the opacity animation completed.
1599 EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);
1602 // Tests that the animators in the layer tree is added to the
1603 // animator-collection when the root-layer is set to the compositor.
1604 TEST_F(LayerWithDelegateTest, RootLayerAnimatorsInCompositor) {
1605 scoped_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR));
1606 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorRED, gfx::Rect(10, 10)));
1607 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1608 child->SetOpacity(0.5f);
1609 root->Add(child.get());
1611 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1612 compositor()->SetRootLayer(root.get());
1613 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1616 // Tests that adding/removing a layer adds/removes the animator from its entire
1617 // subtree from the compositor's animator-collection.
1618 TEST_F(LayerWithDelegateTest, AddRemoveLayerUpdatesAnimatorsFromSubtree) {
1619 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1620 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1621 scoped_ptr<Layer> grandchild(CreateColorLayer(SK_ColorRED,
1622 gfx::Rect(10, 10)));
1623 root->Add(child.get());
1624 child->Add(grandchild.get());
1625 compositor()->SetRootLayer(root.get());
1627 grandchild->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1628 grandchild->SetOpacity(0.5f);
1629 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1631 root->Remove(child.get());
1632 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1634 root->Add(child.get());
1635 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1638 TEST_F(LayerWithDelegateTest, DestroyingLayerRemovesTheAnimatorFromCollection) {
1639 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1640 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1641 root->Add(child.get());
1642 compositor()->SetRootLayer(root.get());
1644 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1645 child->SetOpacity(0.5f);
1646 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1648 child.reset();
1649 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1652 namespace {
1654 std::string Vector2dFTo100thPercisionString(const gfx::Vector2dF& vector) {
1655 return base::StringPrintf("%.2f %0.2f", vector.x(), vector.y());
1658 } // namespace
1660 TEST_F(LayerWithRealCompositorTest, SnapLayerToPixels) {
1661 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1662 scoped_ptr<Layer> c1(CreateLayer(LAYER_TEXTURED));
1663 scoped_ptr<Layer> c11(CreateLayer(LAYER_TEXTURED));
1665 GetCompositor()->SetScaleAndSize(1.25f, gfx::Size(100, 100));
1666 GetCompositor()->SetRootLayer(root.get());
1667 root->Add(c1.get());
1668 c1->Add(c11.get());
1670 root->SetBounds(gfx::Rect(0, 0, 100, 100));
1671 c1->SetBounds(gfx::Rect(1, 1, 10, 10));
1672 c11->SetBounds(gfx::Rect(1, 1, 10, 10));
1673 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1674 // 0.5 at 1.25 scale : (1 - 0.25 + 0.25) / 1.25 = 0.4
1675 EXPECT_EQ("0.40 0.40",
1676 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1678 GetCompositor()->SetScaleAndSize(1.5f, gfx::Size(100, 100));
1679 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1680 // c11 must already be aligned at 1.5 scale.
1681 EXPECT_EQ("0.00 0.00",
1682 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1684 c11->SetBounds(gfx::Rect(2, 2, 10, 10));
1685 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1686 // c11 is now off the pixel.
1687 // 0.5 / 1.5 = 0.333...
1688 EXPECT_EQ("0.33 0.33",
1689 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1692 class FrameDamageCheckingDelegate : public TestLayerDelegate {
1693 public:
1694 FrameDamageCheckingDelegate() : delegated_frame_damage_called_(false) {}
1696 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {
1697 delegated_frame_damage_called_ = true;
1698 delegated_frame_damage_rect_ = damage_rect_in_dip;
1701 const gfx::Rect& delegated_frame_damage_rect() const {
1702 return delegated_frame_damage_rect_;
1704 bool delegated_frame_damage_called() const {
1705 return delegated_frame_damage_called_;
1708 private:
1709 gfx::Rect delegated_frame_damage_rect_;
1710 bool delegated_frame_damage_called_;
1712 DISALLOW_COPY_AND_ASSIGN(FrameDamageCheckingDelegate);
1715 TEST(LayerDelegateTest, DelegatedFrameDamage) {
1716 scoped_ptr<Layer> layer(new Layer(LAYER_TEXTURED));
1717 gfx::Rect damage_rect(2, 1, 5, 3);
1719 FrameDamageCheckingDelegate delegate;
1720 layer->set_delegate(&delegate);
1721 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1722 new cc::DelegatedFrameResourceCollection;
1723 scoped_refptr<cc::DelegatedFrameProvider> frame_provider(
1724 new cc::DelegatedFrameProvider(resource_collection.get(),
1725 MakeFrameData(gfx::Size(10, 10))));
1726 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1728 EXPECT_FALSE(delegate.delegated_frame_damage_called());
1729 layer->OnDelegatedFrameDamage(damage_rect);
1730 EXPECT_TRUE(delegate.delegated_frame_damage_called());
1731 EXPECT_EQ(damage_rect, delegate.delegated_frame_damage_rect());
1734 } // namespace ui