Make |track_| in MediaStreamTrack const. and a couple of other cosmetic changes.
[chromium-blink-merge.git] / ui / compositor / layer_unittest.cc
blob6ebe72b4529c26ea3e045ec739a4de9d5461f195
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/debug/trace_event.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/json/json_reader.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.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 virtual ~ColoredLayer() { }
64 // Overridden from LayerDelegate:
65 virtual void OnPaintLayer(gfx::Canvas* canvas) override {
66 canvas->DrawColor(color_);
69 virtual void OnDelegatedFrameDamage(
70 const gfx::Rect& damage_rect_in_dip) override {}
72 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) override {
75 virtual base::Closure PrepareForLayerBoundsChange() override {
76 return base::Closure();
79 private:
80 SkColor color_;
83 class LayerWithRealCompositorTest : public testing::Test {
84 public:
85 LayerWithRealCompositorTest() {
86 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
87 test_data_directory_ = test_data_directory_.AppendASCII("compositor");
88 } else {
89 LOG(ERROR) << "Could not open test data directory.";
92 virtual ~LayerWithRealCompositorTest() {}
94 // Overridden from testing::Test:
95 virtual void SetUp() override {
96 bool enable_pixel_output = true;
97 ui::ContextFactory* context_factory =
98 InitializeContextFactoryForTests(enable_pixel_output);
100 const gfx::Rect host_bounds(10, 10, 500, 500);
101 compositor_host_.reset(
102 TestCompositorHost::Create(host_bounds, context_factory));
103 compositor_host_->Show();
106 virtual void TearDown() override {
107 compositor_host_.reset();
108 TerminateContextFactoryForTests();
111 Compositor* GetCompositor() { return compositor_host_->GetCompositor(); }
113 Layer* CreateLayer(LayerType type) {
114 return new Layer(type);
117 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
118 Layer* layer = new ColoredLayer(color);
119 layer->SetBounds(bounds);
120 return layer;
123 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
124 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
125 layer->SetBounds(bounds);
126 return layer;
129 void DrawTree(Layer* root) {
130 GetCompositor()->SetRootLayer(root);
131 GetCompositor()->ScheduleDraw();
132 WaitForDraw();
135 void ReadPixels(SkBitmap* bitmap) {
136 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
139 void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) {
140 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder);
141 scoped_ptr<cc::CopyOutputRequest> request =
142 cc::CopyOutputRequest::CreateBitmapRequest(
143 base::Bind(&ReadbackHolder::OutputRequestCallback, holder));
144 request->set_area(source_rect);
146 GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass());
148 // Wait for copy response. This needs to wait as the compositor could
149 // be in the middle of a draw right now, and the commit with the
150 // copy output request may not be done on the first draw.
151 for (int i = 0; i < 2; i++) {
152 GetCompositor()->ScheduleDraw();
153 WaitForDraw();
156 // Waits for the callback to finish run and return result.
157 holder->WaitForReadback();
159 *bitmap = holder->result();
162 void WaitForDraw() { ui::DrawWaiterForTest::Wait(GetCompositor()); }
164 void WaitForCommit() {
165 ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
168 // Invalidates the entire contents of the layer.
169 void SchedulePaintForLayer(Layer* layer) {
170 layer->SchedulePaint(
171 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
174 const base::FilePath& test_data_directory() const {
175 return test_data_directory_;
178 private:
179 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> {
180 public:
181 ReadbackHolder() : run_loop_(new base::RunLoop) {}
183 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) {
184 result_ = result->TakeBitmap();
185 run_loop_->Quit();
188 void WaitForReadback() { run_loop_->Run(); }
190 const SkBitmap& result() const { return *result_; }
192 private:
193 friend class base::RefCountedThreadSafe<ReadbackHolder>;
195 virtual ~ReadbackHolder() {}
197 scoped_ptr<SkBitmap> result_;
198 scoped_ptr<base::RunLoop> run_loop_;
201 scoped_ptr<TestCompositorHost> compositor_host_;
203 // The root directory for test files.
204 base::FilePath test_data_directory_;
206 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
209 // LayerDelegate that paints colors to the layer.
210 class TestLayerDelegate : public LayerDelegate {
211 public:
212 explicit TestLayerDelegate() { reset(); }
213 virtual ~TestLayerDelegate() {}
215 void AddColor(SkColor color) {
216 colors_.push_back(color);
219 const gfx::Size& paint_size() const { return paint_size_; }
220 int color_index() const { return color_index_; }
222 std::string ToScaleString() const {
223 return base::StringPrintf("%.1f %.1f", scale_x_, scale_y_);
226 float device_scale_factor() const {
227 return device_scale_factor_;
230 // Overridden from LayerDelegate:
231 virtual void OnPaintLayer(gfx::Canvas* canvas) override {
232 SkISize size = canvas->sk_canvas()->getBaseLayerSize();
233 paint_size_ = gfx::Size(size.width(), size.height());
234 canvas->DrawColor(colors_[color_index_]);
235 color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
236 const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
237 scale_x_ = matrix.getScaleX();
238 scale_y_ = matrix.getScaleY();
241 virtual void OnDelegatedFrameDamage(
242 const gfx::Rect& damage_rect_in_dip) override {}
244 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) override {
245 device_scale_factor_ = device_scale_factor;
248 virtual base::Closure PrepareForLayerBoundsChange() override {
249 return base::Closure();
252 void reset() {
253 color_index_ = 0;
254 paint_size_.SetSize(0, 0);
255 scale_x_ = scale_y_ = 0.0f;
256 device_scale_factor_ = 0.0f;
259 private:
260 std::vector<SkColor> colors_;
261 int color_index_;
262 gfx::Size paint_size_;
263 float scale_x_;
264 float scale_y_;
265 float device_scale_factor_;
267 DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
270 // LayerDelegate that verifies that a layer was asked to update its canvas.
271 class DrawTreeLayerDelegate : public LayerDelegate {
272 public:
273 DrawTreeLayerDelegate() : painted_(false) {}
274 virtual ~DrawTreeLayerDelegate() {}
276 void Reset() {
277 painted_ = false;
280 bool painted() const { return painted_; }
282 private:
283 // Overridden from LayerDelegate:
284 virtual void OnPaintLayer(gfx::Canvas* canvas) override {
285 painted_ = true;
286 canvas->DrawColor(SK_ColorWHITE);
288 virtual void OnDelegatedFrameDamage(
289 const gfx::Rect& damage_rect_in_dip) override {}
290 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) override {
292 virtual base::Closure PrepareForLayerBoundsChange() override {
293 return base::Closure();
296 bool painted_;
298 DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
301 // The simplest possible layer delegate. Does nothing.
302 class NullLayerDelegate : public LayerDelegate {
303 public:
304 NullLayerDelegate() {}
305 virtual ~NullLayerDelegate() {}
307 private:
308 // Overridden from LayerDelegate:
309 virtual void OnPaintLayer(gfx::Canvas* canvas) override {}
310 virtual void OnDelegatedFrameDamage(
311 const gfx::Rect& damage_rect_in_dip) override {}
312 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
313 virtual base::Closure PrepareForLayerBoundsChange() override {
314 return base::Closure();
317 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
320 // Remembers if it has been notified.
321 class TestCompositorObserver : public CompositorObserver {
322 public:
323 TestCompositorObserver()
324 : committed_(false), started_(false), ended_(false), aborted_(false) {}
326 bool committed() const { return committed_; }
327 bool notified() const { return started_ && ended_; }
328 bool aborted() const { return aborted_; }
330 void Reset() {
331 committed_ = false;
332 started_ = false;
333 ended_ = false;
334 aborted_ = false;
337 private:
338 virtual void OnCompositingDidCommit(Compositor* compositor) override {
339 committed_ = true;
342 virtual void OnCompositingStarted(Compositor* compositor,
343 base::TimeTicks start_time) override {
344 started_ = true;
347 virtual void OnCompositingEnded(Compositor* compositor) override {
348 ended_ = true;
351 virtual void OnCompositingAborted(Compositor* compositor) override {
352 aborted_ = true;
355 virtual void OnCompositingLockStateChanged(Compositor* compositor) override {
358 bool committed_;
359 bool started_;
360 bool ended_;
361 bool aborted_;
363 DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
366 } // namespace
368 TEST_F(LayerWithRealCompositorTest, Draw) {
369 scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED,
370 gfx::Rect(20, 20, 50, 50)));
371 DrawTree(layer.get());
374 // Create this hierarchy:
375 // L1 - red
376 // +-- L2 - blue
377 // | +-- L3 - yellow
378 // +-- L4 - magenta
380 TEST_F(LayerWithRealCompositorTest, Hierarchy) {
381 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
382 gfx::Rect(20, 20, 400, 400)));
383 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
384 gfx::Rect(10, 10, 350, 350)));
385 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
386 gfx::Rect(5, 5, 25, 25)));
387 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
388 gfx::Rect(300, 300, 100, 100)));
390 l1->Add(l2.get());
391 l1->Add(l4.get());
392 l2->Add(l3.get());
394 DrawTree(l1.get());
397 class LayerWithDelegateTest : public testing::Test {
398 public:
399 LayerWithDelegateTest() {}
400 virtual ~LayerWithDelegateTest() {}
402 // Overridden from testing::Test:
403 virtual void SetUp() override {
404 bool enable_pixel_output = false;
405 ui::ContextFactory* context_factory =
406 InitializeContextFactoryForTests(enable_pixel_output);
408 const gfx::Rect host_bounds(1000, 1000);
409 compositor_host_.reset(TestCompositorHost::Create(host_bounds,
410 context_factory));
411 compositor_host_->Show();
414 virtual void TearDown() override {
415 compositor_host_.reset();
416 TerminateContextFactoryForTests();
419 Compositor* compositor() { return compositor_host_->GetCompositor(); }
421 virtual Layer* CreateLayer(LayerType type) {
422 return new Layer(type);
425 Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
426 Layer* layer = new ColoredLayer(color);
427 layer->SetBounds(bounds);
428 return layer;
431 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
432 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
433 layer->SetBounds(bounds);
434 return layer;
437 void DrawTree(Layer* root) {
438 compositor()->SetRootLayer(root);
439 Draw();
442 // Invalidates the entire contents of the layer.
443 void SchedulePaintForLayer(Layer* layer) {
444 layer->SchedulePaint(
445 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
448 // Invokes DrawTree on the compositor.
449 void Draw() {
450 compositor()->ScheduleDraw();
451 WaitForDraw();
454 void WaitForDraw() { DrawWaiterForTest::Wait(compositor()); }
456 void WaitForCommit() {
457 DrawWaiterForTest::WaitForCommit(compositor());
460 private:
461 scoped_ptr<TestCompositorHost> compositor_host_;
463 DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
466 // L1
467 // +-- L2
468 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
469 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
470 gfx::Rect(20, 20, 400, 400)));
471 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
472 gfx::Rect(10, 10, 350, 350)));
473 l1->Add(l2.get());
474 DrawTree(l1.get());
476 gfx::Point point1_in_l2_coords(5, 5);
477 Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
478 gfx::Point point1_in_l1_coords(15, 15);
479 EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
481 gfx::Point point2_in_l1_coords(5, 5);
482 Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
483 gfx::Point point2_in_l2_coords(-5, -5);
484 EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
487 // L1
488 // +-- L2
489 // +-- L3
490 TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
491 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
492 gfx::Rect(20, 20, 400, 400)));
493 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
494 gfx::Rect(10, 10, 350, 350)));
495 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
496 gfx::Rect(10, 10, 100, 100)));
497 l1->Add(l2.get());
498 l2->Add(l3.get());
499 DrawTree(l1.get());
501 gfx::Point point1_in_l3_coords(5, 5);
502 Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
503 gfx::Point point1_in_l1_coords(25, 25);
504 EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
506 gfx::Point point2_in_l1_coords(5, 5);
507 Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
508 gfx::Point point2_in_l3_coords(-15, -15);
509 EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
512 TEST_F(LayerWithRealCompositorTest, Delegate) {
513 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorBLACK,
514 gfx::Rect(20, 20, 400, 400)));
515 GetCompositor()->SetRootLayer(l1.get());
516 WaitForDraw();
518 TestLayerDelegate delegate;
519 l1->set_delegate(&delegate);
520 delegate.AddColor(SK_ColorWHITE);
521 delegate.AddColor(SK_ColorYELLOW);
522 delegate.AddColor(SK_ColorGREEN);
524 l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
525 WaitForDraw();
527 EXPECT_EQ(delegate.color_index(), 1);
528 EXPECT_EQ(delegate.paint_size(), l1->bounds().size());
530 l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
531 WaitForDraw();
532 EXPECT_EQ(delegate.color_index(), 2);
533 EXPECT_EQ(delegate.paint_size(), gfx::Size(200, 200));
535 l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
536 WaitForDraw();
537 EXPECT_EQ(delegate.color_index(), 0);
538 EXPECT_EQ(delegate.paint_size(), gfx::Size(50, 50));
541 TEST_F(LayerWithRealCompositorTest, DrawTree) {
542 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
543 gfx::Rect(20, 20, 400, 400)));
544 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
545 gfx::Rect(10, 10, 350, 350)));
546 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
547 gfx::Rect(10, 10, 100, 100)));
548 l1->Add(l2.get());
549 l2->Add(l3.get());
551 GetCompositor()->SetRootLayer(l1.get());
552 WaitForDraw();
554 DrawTreeLayerDelegate d1;
555 l1->set_delegate(&d1);
556 DrawTreeLayerDelegate d2;
557 l2->set_delegate(&d2);
558 DrawTreeLayerDelegate d3;
559 l3->set_delegate(&d3);
561 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
562 WaitForDraw();
563 EXPECT_FALSE(d1.painted());
564 EXPECT_TRUE(d2.painted());
565 EXPECT_FALSE(d3.painted());
568 // Tests no-texture Layers.
569 // Create this hierarchy:
570 // L1 - red
571 // +-- L2 - NO TEXTURE
572 // | +-- L3 - yellow
573 // +-- L4 - magenta
575 TEST_F(LayerWithRealCompositorTest, HierarchyNoTexture) {
576 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
577 gfx::Rect(20, 20, 400, 400)));
578 scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
579 scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
580 gfx::Rect(5, 5, 25, 25)));
581 scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
582 gfx::Rect(300, 300, 100, 100)));
584 l1->Add(l2.get());
585 l1->Add(l4.get());
586 l2->Add(l3.get());
588 GetCompositor()->SetRootLayer(l1.get());
589 WaitForDraw();
591 DrawTreeLayerDelegate d2;
592 l2->set_delegate(&d2);
593 DrawTreeLayerDelegate d3;
594 l3->set_delegate(&d3);
596 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
597 l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
598 WaitForDraw();
600 // |d2| should not have received a paint notification since it has no texture.
601 EXPECT_FALSE(d2.painted());
602 // |d3| should have received a paint notification.
603 EXPECT_TRUE(d3.painted());
606 class LayerWithNullDelegateTest : public LayerWithDelegateTest {
607 public:
608 LayerWithNullDelegateTest() {}
609 virtual ~LayerWithNullDelegateTest() {}
611 virtual void SetUp() override {
612 LayerWithDelegateTest::SetUp();
613 default_layer_delegate_.reset(new NullLayerDelegate());
616 virtual Layer* CreateLayer(LayerType type) override {
617 Layer* layer = new Layer(type);
618 layer->set_delegate(default_layer_delegate_.get());
619 return layer;
622 Layer* CreateTextureRootLayer(const gfx::Rect& bounds) {
623 Layer* layer = CreateTextureLayer(bounds);
624 compositor()->SetRootLayer(layer);
625 return layer;
628 Layer* CreateTextureLayer(const gfx::Rect& bounds) {
629 Layer* layer = CreateLayer(LAYER_TEXTURED);
630 layer->SetBounds(bounds);
631 return layer;
634 virtual Layer* CreateNoTextureLayer(const gfx::Rect& bounds) override {
635 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
636 layer->SetBounds(bounds);
637 return layer;
640 private:
641 scoped_ptr<NullLayerDelegate> default_layer_delegate_;
643 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
646 TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) {
647 scoped_ptr<Layer> layer(CreateLayer(LAYER_NOT_DRAWN));
648 std::string name = "\"\'\\/\b\f\n\r\t\n";
649 layer->set_name(name);
650 scoped_refptr<base::debug::ConvertableToTraceFormat> debug_info =
651 layer->TakeDebugInfo();
652 EXPECT_TRUE(!!debug_info.get());
653 std::string json;
654 debug_info->AppendAsTraceFormat(&json);
655 base::JSONReader json_reader;
656 scoped_ptr<base::Value> debug_info_value(json_reader.ReadToValue(json));
657 EXPECT_TRUE(!!debug_info_value);
658 EXPECT_TRUE(debug_info_value->IsType(base::Value::TYPE_DICTIONARY));
659 base::DictionaryValue* dictionary = 0;
660 EXPECT_TRUE(debug_info_value->GetAsDictionary(&dictionary));
661 std::string roundtrip;
662 EXPECT_TRUE(dictionary->GetString("layer_name", &roundtrip));
663 EXPECT_EQ(name, roundtrip);
666 void ReturnMailbox(bool* run, uint32 sync_point, bool is_lost) {
667 *run = true;
670 TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
671 scoped_ptr<Layer> l1(CreateLayer(LAYER_SOLID_COLOR));
672 l1->SetFillsBoundsOpaquely(true);
673 l1->SetForceRenderSurface(true);
674 l1->SetVisible(false);
676 EXPECT_EQ(gfx::Point3F(), l1->cc_layer()->transform_origin());
677 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
678 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
679 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
680 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
682 cc::Layer* before_layer = l1->cc_layer();
684 bool callback1_run = false;
685 cc::TextureMailbox mailbox(gpu::Mailbox::Generate(), 0, 0);
686 l1->SetTextureMailbox(mailbox,
687 cc::SingleReleaseCallback::Create(
688 base::Bind(ReturnMailbox, &callback1_run)),
689 gfx::Size(1, 1));
691 EXPECT_NE(before_layer, l1->cc_layer());
693 EXPECT_EQ(gfx::Point3F(), l1->cc_layer()->transform_origin());
694 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
695 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
696 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
697 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
698 EXPECT_FALSE(callback1_run);
700 bool callback2_run = false;
701 mailbox = cc::TextureMailbox(gpu::Mailbox::Generate(), 0, 0);
702 l1->SetTextureMailbox(mailbox,
703 cc::SingleReleaseCallback::Create(
704 base::Bind(ReturnMailbox, &callback2_run)),
705 gfx::Size(1, 1));
706 EXPECT_TRUE(callback1_run);
707 EXPECT_FALSE(callback2_run);
709 l1->SetShowSolidColorContent();
710 EXPECT_EQ(gfx::Point3F(), l1->cc_layer()->transform_origin());
711 EXPECT_TRUE(l1->cc_layer()->DrawsContent());
712 EXPECT_TRUE(l1->cc_layer()->contents_opaque());
713 EXPECT_TRUE(l1->cc_layer()->force_render_surface());
714 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
715 EXPECT_TRUE(callback2_run);
718 // Various visibile/drawn assertions.
719 TEST_F(LayerWithNullDelegateTest, Visibility) {
720 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
721 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
722 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
723 l1->Add(l2.get());
724 l2->Add(l3.get());
726 NullLayerDelegate delegate;
727 l1->set_delegate(&delegate);
728 l2->set_delegate(&delegate);
729 l3->set_delegate(&delegate);
731 // Layers should initially be drawn.
732 EXPECT_TRUE(l1->IsDrawn());
733 EXPECT_TRUE(l2->IsDrawn());
734 EXPECT_TRUE(l3->IsDrawn());
735 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
736 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
737 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
739 compositor()->SetRootLayer(l1.get());
741 Draw();
743 l1->SetVisible(false);
744 EXPECT_FALSE(l1->IsDrawn());
745 EXPECT_FALSE(l2->IsDrawn());
746 EXPECT_FALSE(l3->IsDrawn());
747 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
748 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
749 EXPECT_FALSE(l3->cc_layer()->hide_layer_and_subtree());
751 l3->SetVisible(false);
752 EXPECT_FALSE(l1->IsDrawn());
753 EXPECT_FALSE(l2->IsDrawn());
754 EXPECT_FALSE(l3->IsDrawn());
755 EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree());
756 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
757 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
759 l1->SetVisible(true);
760 EXPECT_TRUE(l1->IsDrawn());
761 EXPECT_TRUE(l2->IsDrawn());
762 EXPECT_FALSE(l3->IsDrawn());
763 EXPECT_FALSE(l1->cc_layer()->hide_layer_and_subtree());
764 EXPECT_FALSE(l2->cc_layer()->hide_layer_and_subtree());
765 EXPECT_TRUE(l3->cc_layer()->hide_layer_and_subtree());
768 // Checks that stacking-related methods behave as advertised.
769 TEST_F(LayerWithNullDelegateTest, Stacking) {
770 scoped_ptr<Layer> root(new Layer(LAYER_NOT_DRAWN));
771 scoped_ptr<Layer> l1(new Layer(LAYER_TEXTURED));
772 scoped_ptr<Layer> l2(new Layer(LAYER_TEXTURED));
773 scoped_ptr<Layer> l3(new Layer(LAYER_TEXTURED));
774 l1->set_name("1");
775 l2->set_name("2");
776 l3->set_name("3");
777 root->Add(l3.get());
778 root->Add(l2.get());
779 root->Add(l1.get());
781 // Layers' children are stored in bottom-to-top order.
782 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
784 root->StackAtTop(l3.get());
785 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
787 root->StackAtTop(l1.get());
788 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
790 root->StackAtTop(l1.get());
791 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
793 root->StackAbove(l2.get(), l3.get());
794 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
796 root->StackAbove(l1.get(), l3.get());
797 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
799 root->StackAbove(l2.get(), l1.get());
800 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
802 root->StackAtBottom(l2.get());
803 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
805 root->StackAtBottom(l3.get());
806 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
808 root->StackAtBottom(l3.get());
809 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
811 root->StackBelow(l2.get(), l3.get());
812 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
814 root->StackBelow(l1.get(), l3.get());
815 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
817 root->StackBelow(l3.get(), l2.get());
818 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
820 root->StackBelow(l3.get(), l2.get());
821 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
823 root->StackBelow(l3.get(), l1.get());
824 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
827 // Verifies SetBounds triggers the appropriate painting/drawing.
828 TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
829 scoped_ptr<Layer> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
830 compositor()->SetRootLayer(l1.get());
832 Draw();
834 l1->SetBounds(gfx::Rect(5, 5, 200, 200));
836 // The CompositorDelegate (us) should have been told to draw for a move.
837 WaitForDraw();
839 l1->SetBounds(gfx::Rect(5, 5, 100, 100));
841 // The CompositorDelegate (us) should have been told to draw for a resize.
842 WaitForDraw();
845 void ExpectRgba(int x, int y, SkColor expected_color, SkColor actual_color) {
846 EXPECT_EQ(expected_color, actual_color)
847 << "Pixel error at x=" << x << " y=" << y << "; "
848 << "actual RGBA=("
849 << SkColorGetR(actual_color) << ","
850 << SkColorGetG(actual_color) << ","
851 << SkColorGetB(actual_color) << ","
852 << SkColorGetA(actual_color) << "); "
853 << "expected RGBA=("
854 << SkColorGetR(expected_color) << ","
855 << SkColorGetG(expected_color) << ","
856 << SkColorGetB(expected_color) << ","
857 << SkColorGetA(expected_color) << ")";
860 // Checks that pixels are actually drawn to the screen with a read back.
861 TEST_F(LayerWithRealCompositorTest, DrawPixels) {
862 gfx::Size viewport_size = GetCompositor()->size();
864 // The window should be some non-trivial size but may not be exactly
865 // 500x500 on all platforms/bots.
866 EXPECT_GE(viewport_size.width(), 200);
867 EXPECT_GE(viewport_size.height(), 200);
869 int blue_height = 10;
871 scoped_ptr<Layer> layer(
872 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
873 scoped_ptr<Layer> layer2(
874 CreateColorLayer(SK_ColorBLUE,
875 gfx::Rect(0, 0, viewport_size.width(), blue_height)));
877 layer->Add(layer2.get());
879 DrawTree(layer.get());
881 SkBitmap bitmap;
882 ReadPixels(&bitmap, gfx::Rect(viewport_size));
883 ASSERT_FALSE(bitmap.empty());
885 SkAutoLockPixels lock(bitmap);
886 for (int x = 0; x < viewport_size.width(); x++) {
887 for (int y = 0; y < viewport_size.height(); y++) {
888 SkColor actual_color = bitmap.getColor(x, y);
889 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
890 ExpectRgba(x, y, expected_color, actual_color);
895 // Checks that drawing a layer with transparent pixels is blended correctly
896 // with the lower layer.
897 TEST_F(LayerWithRealCompositorTest, DrawAlphaBlendedPixels) {
898 gfx::Size viewport_size = GetCompositor()->size();
900 int test_size = 200;
901 EXPECT_GE(viewport_size.width(), test_size);
902 EXPECT_GE(viewport_size.height(), test_size);
904 // Blue with a wee bit of transparency.
905 SkColor blue_with_alpha = SkColorSetARGBInline(40, 10, 20, 200);
906 SkColor blend_color = SkColorSetARGBInline(255, 216, 3, 32);
908 scoped_ptr<Layer> background_layer(
909 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
910 scoped_ptr<Layer> foreground_layer(
911 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size)));
913 // This must be set to false for layers with alpha to be blended correctly.
914 foreground_layer->SetFillsBoundsOpaquely(false);
916 background_layer->Add(foreground_layer.get());
917 DrawTree(background_layer.get());
919 SkBitmap bitmap;
920 ReadPixels(&bitmap, gfx::Rect(viewport_size));
921 ASSERT_FALSE(bitmap.empty());
923 SkAutoLockPixels lock(bitmap);
924 for (int x = 0; x < test_size; x++) {
925 for (int y = 0; y < test_size; y++) {
926 SkColor actual_color = bitmap.getColor(x, y);
927 ExpectRgba(x, y, blend_color, actual_color);
932 // Checks that using the AlphaShape filter applied to a layer with
933 // transparency, alpha-blends properly with the layer below.
934 TEST_F(LayerWithRealCompositorTest, DrawAlphaThresholdFilterPixels) {
935 gfx::Size viewport_size = GetCompositor()->size();
937 int test_size = 200;
938 EXPECT_GE(viewport_size.width(), test_size);
939 EXPECT_GE(viewport_size.height(), test_size);
941 int blue_height = 10;
942 SkColor blue_with_alpha = SkColorSetARGBInline(40, 0, 0, 255);
943 SkColor blend_color = SkColorSetARGBInline(255, 215, 0, 40);
945 scoped_ptr<Layer> background_layer(
946 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
947 scoped_ptr<Layer> foreground_layer(
948 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size)));
950 // Add a shape to restrict the visible part of the layer.
951 SkRegion shape;
952 shape.setRect(0, 0, viewport_size.width(), blue_height);
953 foreground_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(shape)));
955 foreground_layer->SetFillsBoundsOpaquely(false);
957 background_layer->Add(foreground_layer.get());
958 DrawTree(background_layer.get());
960 SkBitmap bitmap;
961 ReadPixels(&bitmap, gfx::Rect(viewport_size));
962 ASSERT_FALSE(bitmap.empty());
964 SkAutoLockPixels lock(bitmap);
965 for (int x = 0; x < test_size; x++) {
966 for (int y = 0; y < test_size; y++) {
967 SkColor actual_color = bitmap.getColor(x, y);
968 ExpectRgba(x, y, actual_color,
969 y < blue_height ? blend_color : SK_ColorRED);
974 // Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
975 TEST_F(LayerWithRealCompositorTest, SetRootLayer) {
976 Compositor* compositor = GetCompositor();
977 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
978 gfx::Rect(20, 20, 400, 400)));
979 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
980 gfx::Rect(10, 10, 350, 350)));
982 EXPECT_EQ(NULL, l1->GetCompositor());
983 EXPECT_EQ(NULL, l2->GetCompositor());
985 compositor->SetRootLayer(l1.get());
986 EXPECT_EQ(compositor, l1->GetCompositor());
988 l1->Add(l2.get());
989 EXPECT_EQ(compositor, l2->GetCompositor());
991 l1->Remove(l2.get());
992 EXPECT_EQ(NULL, l2->GetCompositor());
994 l1->Add(l2.get());
995 EXPECT_EQ(compositor, l2->GetCompositor());
997 compositor->SetRootLayer(NULL);
998 EXPECT_EQ(NULL, l1->GetCompositor());
999 EXPECT_EQ(NULL, l2->GetCompositor());
1002 // Checks that compositor observers are notified when:
1003 // - DrawTree is called,
1004 // - After ScheduleDraw is called, or
1005 // - Whenever SetBounds, SetOpacity or SetTransform are called.
1006 // TODO(vollick): could be reorganized into compositor_unittest.cc
1007 TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
1008 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
1009 gfx::Rect(20, 20, 400, 400)));
1010 scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
1011 gfx::Rect(10, 10, 350, 350)));
1012 l1->Add(l2.get());
1013 TestCompositorObserver observer;
1014 GetCompositor()->AddObserver(&observer);
1016 // Explicitly called DrawTree should cause the observers to be notified.
1017 // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
1018 DrawTree(l1.get());
1019 EXPECT_TRUE(observer.notified());
1021 // ScheduleDraw without any visible change should cause a commit.
1022 observer.Reset();
1023 l1->ScheduleDraw();
1024 WaitForCommit();
1025 EXPECT_TRUE(observer.committed());
1027 // Moving, but not resizing, a layer should alert the observers.
1028 observer.Reset();
1029 l2->SetBounds(gfx::Rect(0, 0, 350, 350));
1030 WaitForDraw();
1031 EXPECT_TRUE(observer.notified());
1033 // So should resizing a layer.
1034 observer.Reset();
1035 l2->SetBounds(gfx::Rect(0, 0, 400, 400));
1036 WaitForDraw();
1037 EXPECT_TRUE(observer.notified());
1039 // Opacity changes should alert the observers.
1040 observer.Reset();
1041 l2->SetOpacity(0.5f);
1042 WaitForDraw();
1043 EXPECT_TRUE(observer.notified());
1045 // So should setting the opacity back.
1046 observer.Reset();
1047 l2->SetOpacity(1.0f);
1048 WaitForDraw();
1049 EXPECT_TRUE(observer.notified());
1051 // Setting the transform of a layer should alert the observers.
1052 observer.Reset();
1053 gfx::Transform transform;
1054 transform.Translate(200.0, 200.0);
1055 transform.Rotate(90.0);
1056 transform.Translate(-200.0, -200.0);
1057 l2->SetTransform(transform);
1058 WaitForDraw();
1059 EXPECT_TRUE(observer.notified());
1061 // A change resulting in an aborted swap buffer should alert the observer
1062 // and also signal an abort.
1063 observer.Reset();
1064 l2->SetOpacity(0.1f);
1065 GetCompositor()->DidAbortSwapBuffers();
1066 WaitForDraw();
1067 EXPECT_TRUE(observer.notified());
1068 EXPECT_TRUE(observer.aborted());
1070 GetCompositor()->RemoveObserver(&observer);
1072 // Opacity changes should no longer alert the removed observer.
1073 observer.Reset();
1074 l2->SetOpacity(0.5f);
1075 WaitForDraw();
1077 EXPECT_FALSE(observer.notified());
1080 // Checks that modifying the hierarchy correctly affects final composite.
1081 TEST_F(LayerWithRealCompositorTest, ModifyHierarchy) {
1082 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1084 // l0
1085 // +-l11
1086 // | +-l21
1087 // +-l12
1088 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1089 gfx::Rect(0, 0, 50, 50)));
1090 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1091 gfx::Rect(0, 0, 25, 25)));
1092 scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA,
1093 gfx::Rect(0, 0, 15, 15)));
1094 scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE,
1095 gfx::Rect(10, 10, 25, 25)));
1097 base::FilePath ref_img1 =
1098 test_data_directory().AppendASCII("ModifyHierarchy1.png");
1099 base::FilePath ref_img2 =
1100 test_data_directory().AppendASCII("ModifyHierarchy2.png");
1101 SkBitmap bitmap;
1103 l0->Add(l11.get());
1104 l11->Add(l21.get());
1105 l0->Add(l12.get());
1106 DrawTree(l0.get());
1107 ReadPixels(&bitmap);
1108 ASSERT_FALSE(bitmap.empty());
1109 // WritePNGFile(bitmap, ref_img1);
1110 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1112 l0->StackAtTop(l11.get());
1113 DrawTree(l0.get());
1114 ReadPixels(&bitmap);
1115 ASSERT_FALSE(bitmap.empty());
1116 // WritePNGFile(bitmap, ref_img2);
1117 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1119 // should restore to original configuration
1120 l0->StackAbove(l12.get(), l11.get());
1121 DrawTree(l0.get());
1122 ReadPixels(&bitmap);
1123 ASSERT_FALSE(bitmap.empty());
1124 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1126 // l11 back to front
1127 l0->StackAtTop(l11.get());
1128 DrawTree(l0.get());
1129 ReadPixels(&bitmap);
1130 ASSERT_FALSE(bitmap.empty());
1131 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1133 // should restore to original configuration
1134 l0->StackAbove(l12.get(), l11.get());
1135 DrawTree(l0.get());
1136 ReadPixels(&bitmap);
1137 ASSERT_FALSE(bitmap.empty());
1138 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1140 // l11 back to front
1141 l0->StackAbove(l11.get(), l12.get());
1142 DrawTree(l0.get());
1143 ReadPixels(&bitmap);
1144 ASSERT_FALSE(bitmap.empty());
1145 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1148 // Opacity is rendered correctly.
1149 // Checks that modifying the hierarchy correctly affects final composite.
1150 TEST_F(LayerWithRealCompositorTest, Opacity) {
1151 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1153 // l0
1154 // +-l11
1155 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1156 gfx::Rect(0, 0, 50, 50)));
1157 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1158 gfx::Rect(0, 0, 25, 25)));
1160 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
1162 l11->SetOpacity(0.75);
1163 l0->Add(l11.get());
1164 DrawTree(l0.get());
1165 SkBitmap bitmap;
1166 ReadPixels(&bitmap);
1167 ASSERT_FALSE(bitmap.empty());
1168 // WritePNGFile(bitmap, ref_img);
1169 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
1172 namespace {
1174 class SchedulePaintLayerDelegate : public LayerDelegate {
1175 public:
1176 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
1178 virtual ~SchedulePaintLayerDelegate() {}
1180 void set_layer(Layer* layer) {
1181 layer_ = layer;
1182 layer_->set_delegate(this);
1185 void SetSchedulePaintRect(const gfx::Rect& rect) {
1186 schedule_paint_rect_ = rect;
1189 int GetPaintCountAndClear() {
1190 int value = paint_count_;
1191 paint_count_ = 0;
1192 return value;
1195 const gfx::RectF& last_clip_rect() const { return last_clip_rect_; }
1197 private:
1198 // Overridden from LayerDelegate:
1199 virtual void OnPaintLayer(gfx::Canvas* canvas) override {
1200 paint_count_++;
1201 if (!schedule_paint_rect_.IsEmpty()) {
1202 layer_->SchedulePaint(schedule_paint_rect_);
1203 schedule_paint_rect_ = gfx::Rect();
1205 SkRect sk_clip_rect;
1206 if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
1207 last_clip_rect_ = gfx::SkRectToRectF(sk_clip_rect);
1210 virtual void OnDelegatedFrameDamage(
1211 const gfx::Rect& damage_rect_in_dip) override {}
1213 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) override {
1216 virtual base::Closure PrepareForLayerBoundsChange() override {
1217 return base::Closure();
1220 int paint_count_;
1221 Layer* layer_;
1222 gfx::Rect schedule_paint_rect_;
1223 gfx::RectF last_clip_rect_;
1225 DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
1228 } // namespace
1230 // Verifies that if SchedulePaint is invoked during painting the layer is still
1231 // marked dirty.
1232 TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
1233 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorRED,
1234 gfx::Rect(0, 0, 500, 500)));
1235 SchedulePaintLayerDelegate child_delegate;
1236 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorBLUE,
1237 gfx::Rect(0, 0, 200, 200)));
1238 child_delegate.set_layer(child.get());
1240 root->Add(child.get());
1242 SchedulePaintForLayer(root.get());
1243 DrawTree(root.get());
1244 child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
1245 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1247 // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
1248 // again.
1249 child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
1250 WaitForCommit();
1251 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1253 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
1254 // still need to be painted.
1255 WaitForCommit();
1256 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
1257 EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
1258 gfx::Rect(10, 10, 30, 30)));
1261 TEST_F(LayerWithRealCompositorTest, ScaleUpDown) {
1262 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1263 gfx::Rect(10, 20, 200, 220)));
1264 TestLayerDelegate root_delegate;
1265 root_delegate.AddColor(SK_ColorWHITE);
1266 root->set_delegate(&root_delegate);
1268 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1269 gfx::Rect(10, 20, 140, 180)));
1270 TestLayerDelegate l1_delegate;
1271 l1_delegate.AddColor(SK_ColorWHITE);
1272 l1->set_delegate(&l1_delegate);
1274 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1275 GetCompositor()->SetRootLayer(root.get());
1276 root->Add(l1.get());
1277 WaitForDraw();
1279 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1280 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1281 gfx::Size cc_bounds_size = root->cc_layer()->bounds();
1282 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1283 cc_bounds_size = l1->cc_layer()->bounds();
1284 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1285 // No scale change, so no scale notification.
1286 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1287 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1289 EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1290 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1292 // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
1293 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1294 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1295 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1296 // CC layer should still match the UI layer bounds.
1297 cc_bounds_size = root->cc_layer()->bounds();
1298 EXPECT_EQ("200x220", cc_bounds_size.ToString());
1299 cc_bounds_size = l1->cc_layer()->bounds();
1300 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1301 // New scale factor must have been notified.
1302 EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
1303 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1305 // Canvas size must have been scaled down up.
1306 WaitForDraw();
1307 EXPECT_EQ("400x440", root_delegate.paint_size().ToString());
1308 EXPECT_EQ("2.0 2.0", root_delegate.ToScaleString());
1309 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1310 EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
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.
1322 EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
1323 EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
1325 // Canvas size must have been scaled down too.
1326 WaitForDraw();
1327 EXPECT_EQ("200x220", root_delegate.paint_size().ToString());
1328 EXPECT_EQ("1.0 1.0", root_delegate.ToScaleString());
1329 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1330 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1332 root_delegate.reset();
1333 l1_delegate.reset();
1334 // Just changing the size shouldn't notify the scale change nor
1335 // trigger repaint.
1336 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(1000, 1000));
1337 // No scale change, so no scale notification.
1338 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
1339 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1340 WaitForDraw();
1341 EXPECT_EQ("0x0", root_delegate.paint_size().ToString());
1342 EXPECT_EQ("0.0 0.0", root_delegate.ToScaleString());
1343 EXPECT_EQ("0x0", l1_delegate.paint_size().ToString());
1344 EXPECT_EQ("0.0 0.0", l1_delegate.ToScaleString());
1347 TEST_F(LayerWithRealCompositorTest, ScaleReparent) {
1348 scoped_ptr<Layer> root(CreateColorLayer(SK_ColorWHITE,
1349 gfx::Rect(10, 20, 200, 220)));
1350 scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorWHITE,
1351 gfx::Rect(10, 20, 140, 180)));
1352 TestLayerDelegate l1_delegate;
1353 l1_delegate.AddColor(SK_ColorWHITE);
1354 l1->set_delegate(&l1_delegate);
1356 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(500, 500));
1357 GetCompositor()->SetRootLayer(root.get());
1358 WaitForDraw();
1360 root->Add(l1.get());
1361 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1362 gfx::Size cc_bounds_size = l1->cc_layer()->bounds();
1363 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1364 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
1366 WaitForDraw();
1367 EXPECT_EQ("140x180", l1_delegate.paint_size().ToString());
1368 EXPECT_EQ("1.0 1.0", l1_delegate.ToScaleString());
1370 // Remove l1 from root and change the scale.
1371 root->Remove(l1.get());
1372 EXPECT_EQ(NULL, l1->parent());
1373 EXPECT_EQ(NULL, l1->GetCompositor());
1374 GetCompositor()->SetScaleAndSize(2.0f, gfx::Size(500, 500));
1375 // Sanity check on root and l1.
1376 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
1377 cc_bounds_size = l1->cc_layer()->bounds();
1378 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1380 root->Add(l1.get());
1381 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
1382 cc_bounds_size = l1->cc_layer()->bounds();
1383 EXPECT_EQ("140x180", cc_bounds_size.ToString());
1384 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
1385 WaitForDraw();
1386 EXPECT_EQ("280x360", l1_delegate.paint_size().ToString());
1387 EXPECT_EQ("2.0 2.0", l1_delegate.ToScaleString());
1390 // Verifies that when changing bounds on a layer that is invisible, and then
1391 // made visible, the right thing happens:
1392 // - if just a move, then no painting should happen.
1393 // - if a resize, the layer should be repainted.
1394 TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
1395 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1397 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1398 child->SetBounds(gfx::Rect(0, 0, 500, 500));
1399 DrawTreeLayerDelegate delegate;
1400 child->set_delegate(&delegate);
1401 root->Add(child.get());
1403 // Paint once for initial damage.
1404 child->SetVisible(true);
1405 DrawTree(root.get());
1407 // Reset into invisible state.
1408 child->SetVisible(false);
1409 DrawTree(root.get());
1410 delegate.Reset();
1412 // Move layer.
1413 child->SetBounds(gfx::Rect(200, 200, 500, 500));
1414 child->SetVisible(true);
1415 DrawTree(root.get());
1416 EXPECT_FALSE(delegate.painted());
1418 // Reset into invisible state.
1419 child->SetVisible(false);
1420 DrawTree(root.get());
1421 delegate.Reset();
1423 // Resize layer.
1424 child->SetBounds(gfx::Rect(200, 200, 400, 400));
1425 child->SetVisible(true);
1426 DrawTree(root.get());
1427 EXPECT_TRUE(delegate.painted());
1430 static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) {
1431 scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
1432 scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create());
1433 render_pass->SetNew(
1434 cc::RenderPassId(1, 1), gfx::Rect(size), gfx::Rect(), gfx::Transform());
1435 frame_data->render_pass_list.push_back(render_pass.Pass());
1436 return frame_data.Pass();
1439 TEST_F(LayerWithDelegateTest, DelegatedLayer) {
1440 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1442 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1444 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1445 child->SetVisible(true);
1446 root->Add(child.get());
1447 DrawTree(root.get());
1449 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1450 new cc::DelegatedFrameResourceCollection;
1451 scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
1453 // Content matches layer size.
1454 frame_provider = new cc::DelegatedFrameProvider(
1455 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
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 // Content larger than layer.
1461 child->SetBounds(gfx::Rect(0, 0, 5, 5));
1462 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1463 gfx::Size(5, 5).ToString());
1465 // Content smaller than layer.
1466 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1467 frame_provider = new cc::DelegatedFrameProvider(
1468 resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
1469 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(5, 5));
1470 EXPECT_EQ(child->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
1472 // Hi-DPI content on low-DPI layer.
1473 frame_provider = new cc::DelegatedFrameProvider(
1474 resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
1475 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1476 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1477 gfx::Size(10, 10).ToString());
1479 // Hi-DPI content on hi-DPI layer.
1480 compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000));
1481 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1482 gfx::Size(10, 10).ToString());
1484 // Low-DPI content on hi-DPI layer.
1485 frame_provider = new cc::DelegatedFrameProvider(
1486 resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
1487 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1488 EXPECT_EQ(child->cc_layer()->bounds().ToString(),
1489 gfx::Size(10, 10).ToString());
1492 TEST_F(LayerWithDelegateTest, ExternalContent) {
1493 scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1494 scoped_ptr<Layer> child(CreateLayer(LAYER_SOLID_COLOR));
1496 child->SetBounds(gfx::Rect(0, 0, 10, 10));
1497 child->SetVisible(true);
1498 root->Add(child.get());
1500 // The layer is already showing solid color content, so the cc layer won't
1501 // change.
1502 scoped_refptr<cc::Layer> before = child->cc_layer();
1503 child->SetShowSolidColorContent();
1504 EXPECT_TRUE(child->cc_layer());
1505 EXPECT_EQ(before.get(), child->cc_layer());
1507 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1508 new cc::DelegatedFrameResourceCollection;
1509 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1510 new cc::DelegatedFrameProvider(resource_collection.get(),
1511 MakeFrameData(gfx::Size(10, 10)));
1513 // Showing delegated content changes the underlying cc layer.
1514 before = child->cc_layer();
1515 child->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1516 EXPECT_TRUE(child->cc_layer());
1517 EXPECT_NE(before.get(), child->cc_layer());
1519 // Changing to painted content should change the underlying cc layer.
1520 before = child->cc_layer();
1521 child->SetShowSolidColorContent();
1522 EXPECT_TRUE(child->cc_layer());
1523 EXPECT_NE(before.get(), child->cc_layer());
1526 // Verifies that layer filters still attached after changing implementation
1527 // layer.
1528 TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
1529 scoped_ptr<Layer> layer(CreateLayer(LAYER_TEXTURED));
1530 layer->SetBounds(gfx::Rect(0, 0, 10, 10));
1531 EXPECT_TRUE(layer->cc_layer());
1532 EXPECT_EQ(0u, layer->cc_layer()->filters().size());
1534 layer->SetLayerGrayscale(0.5f);
1535 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
1536 EXPECT_EQ(1u, layer->cc_layer()->filters().size());
1538 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1539 new cc::DelegatedFrameResourceCollection;
1540 scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
1541 new cc::DelegatedFrameProvider(resource_collection.get(),
1542 MakeFrameData(gfx::Size(10, 10)));
1544 // Showing delegated content changes the underlying cc layer.
1545 scoped_refptr<cc::Layer> before = layer->cc_layer();
1546 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1547 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
1548 EXPECT_TRUE(layer->cc_layer());
1549 EXPECT_NE(before.get(), layer->cc_layer());
1550 EXPECT_EQ(1u, layer->cc_layer()->filters().size());
1553 // Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
1554 TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
1555 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1556 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1557 scoped_ptr<Layer> l2(CreateLayer(LAYER_TEXTURED));
1559 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1560 l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1562 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1564 // Trigger a threaded animation.
1565 l1->SetOpacity(0.5f);
1567 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1569 // Ensure we can remove a pending threaded animation.
1570 l1->GetAnimator()->StopAnimating();
1572 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1574 // Trigger another threaded animation.
1575 l1->SetOpacity(0.2f);
1577 EXPECT_TRUE(l1->HasPendingThreadedAnimations());
1579 root->Add(l1.get());
1580 GetCompositor()->SetRootLayer(root.get());
1582 // Now that l1 is part of a tree, it should have dispatched the pending
1583 // animation.
1584 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1586 // Ensure that l1 no longer holds on to animations.
1587 l1->SetOpacity(0.1f);
1588 EXPECT_FALSE(l1->HasPendingThreadedAnimations());
1590 // Ensure that adding a layer to an existing tree causes its pending
1591 // animations to get dispatched.
1592 l2->SetOpacity(0.5f);
1593 EXPECT_TRUE(l2->HasPendingThreadedAnimations());
1595 l1->Add(l2.get());
1596 EXPECT_FALSE(l2->HasPendingThreadedAnimations());
1599 // Tests that in-progress threaded animations complete when a Layer's
1600 // cc::Layer changes.
1601 TEST_F(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
1602 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1603 scoped_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
1604 GetCompositor()->SetRootLayer(root.get());
1605 root->Add(l1.get());
1607 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1609 EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
1611 // Trigger a threaded animation.
1612 l1->SetOpacity(0.5f);
1614 // Change l1's cc::Layer.
1615 l1->SwitchCCLayerForTest();
1617 // Ensure that the opacity animation completed.
1618 EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);
1621 // Tests that the animators in the layer tree is added to the
1622 // animator-collection when the root-layer is set to the compositor.
1623 TEST_F(LayerWithDelegateTest, RootLayerAnimatorsInCompositor) {
1624 scoped_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR));
1625 scoped_ptr<Layer> child(CreateColorLayer(SK_ColorRED, gfx::Rect(10, 10)));
1626 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1627 child->SetOpacity(0.5f);
1628 root->Add(child.get());
1630 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1631 compositor()->SetRootLayer(root.get());
1632 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1635 // Tests that adding/removing a layer adds/removes the animator from its entire
1636 // subtree from the compositor's animator-collection.
1637 TEST_F(LayerWithDelegateTest, AddRemoveLayerUpdatesAnimatorsFromSubtree) {
1638 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1639 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1640 scoped_ptr<Layer> grandchild(CreateColorLayer(SK_ColorRED,
1641 gfx::Rect(10, 10)));
1642 root->Add(child.get());
1643 child->Add(grandchild.get());
1644 compositor()->SetRootLayer(root.get());
1646 grandchild->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1647 grandchild->SetOpacity(0.5f);
1648 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1650 root->Remove(child.get());
1651 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1653 root->Add(child.get());
1654 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1657 TEST_F(LayerWithDelegateTest, DestroyingLayerRemovesTheAnimatorFromCollection) {
1658 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1659 scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
1660 root->Add(child.get());
1661 compositor()->SetRootLayer(root.get());
1663 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1664 child->SetOpacity(0.5f);
1665 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1667 child.reset();
1668 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1671 namespace {
1673 std::string Vector2dFTo100thPercisionString(const gfx::Vector2dF& vector) {
1674 return base::StringPrintf("%.2f %0.2f", vector.x(), vector.y());
1677 } // namespace
1679 TEST_F(LayerWithRealCompositorTest, SnapLayerToPixels) {
1680 scoped_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
1681 scoped_ptr<Layer> c1(CreateLayer(LAYER_TEXTURED));
1682 scoped_ptr<Layer> c11(CreateLayer(LAYER_TEXTURED));
1684 GetCompositor()->SetScaleAndSize(1.25f, gfx::Size(100, 100));
1685 GetCompositor()->SetRootLayer(root.get());
1686 root->Add(c1.get());
1687 c1->Add(c11.get());
1689 root->SetBounds(gfx::Rect(0, 0, 100, 100));
1690 c1->SetBounds(gfx::Rect(1, 1, 10, 10));
1691 c11->SetBounds(gfx::Rect(1, 1, 10, 10));
1692 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1693 // 0.5 at 1.25 scale : (1 - 0.25 + 0.25) / 1.25 = 0.4
1694 EXPECT_EQ("0.40 0.40",
1695 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1697 GetCompositor()->SetScaleAndSize(1.5f, gfx::Size(100, 100));
1698 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1699 // c11 must already be aligned at 1.5 scale.
1700 EXPECT_EQ("0.00 0.00",
1701 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1703 c11->SetBounds(gfx::Rect(2, 2, 10, 10));
1704 SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
1705 // c11 is now off the pixel.
1706 // 0.5 / 1.5 = 0.333...
1707 EXPECT_EQ("0.33 0.33",
1708 Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
1711 class FrameDamageCheckingDelegate : public TestLayerDelegate {
1712 public:
1713 FrameDamageCheckingDelegate() : delegated_frame_damage_called_(false) {}
1715 virtual void OnDelegatedFrameDamage(
1716 const gfx::Rect& damage_rect_in_dip) override {
1717 delegated_frame_damage_called_ = true;
1718 delegated_frame_damage_rect_ = damage_rect_in_dip;
1721 const gfx::Rect& delegated_frame_damage_rect() const {
1722 return delegated_frame_damage_rect_;
1724 bool delegated_frame_damage_called() const {
1725 return delegated_frame_damage_called_;
1728 private:
1729 gfx::Rect delegated_frame_damage_rect_;
1730 bool delegated_frame_damage_called_;
1732 DISALLOW_COPY_AND_ASSIGN(FrameDamageCheckingDelegate);
1735 TEST(LayerDelegateTest, DelegatedFrameDamage) {
1736 scoped_ptr<Layer> layer(new Layer(LAYER_TEXTURED));
1737 gfx::Rect damage_rect(2, 1, 5, 3);
1739 FrameDamageCheckingDelegate delegate;
1740 layer->set_delegate(&delegate);
1741 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
1742 new cc::DelegatedFrameResourceCollection;
1743 scoped_refptr<cc::DelegatedFrameProvider> frame_provider(
1744 new cc::DelegatedFrameProvider(resource_collection.get(),
1745 MakeFrameData(gfx::Size(10, 10))));
1746 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1748 EXPECT_FALSE(delegate.delegated_frame_damage_called());
1749 layer->OnDelegatedFrameDamage(damage_rect);
1750 EXPECT_TRUE(delegate.delegated_frame_damage_called());
1751 EXPECT_EQ(damage_rect, delegate.delegated_frame_damage_rect());
1754 } // namespace ui