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"
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
;
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
{
56 explicit ColoredLayer(SkColor color
)
57 : Layer(LAYER_TEXTURED
),
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();
79 class LayerWithRealCompositorTest
: public testing::Test
{
81 LayerWithRealCompositorTest() {
82 if (PathService::Get(gfx::DIR_TEST_DATA
, &test_data_directory_
)) {
83 test_data_directory_
= test_data_directory_
.AppendASCII("compositor");
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
);
119 Layer
* CreateNoTextureLayer(const gfx::Rect
& bounds
) {
120 Layer
* layer
= CreateLayer(LAYER_NOT_DRAWN
);
121 layer
->SetBounds(bounds
);
125 void DrawTree(Layer
* root
) {
126 GetCompositor()->SetRootLayer(root
);
127 GetCompositor()->ScheduleDraw();
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();
152 // Waits for the callback to finish run and return result.
153 holder
->WaitForReadback();
155 *bitmap
= holder
->result();
159 ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor());
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_
;
181 class ReadbackHolder
: public base::RefCountedThreadSafe
<ReadbackHolder
> {
183 ReadbackHolder() : run_loop_(new base::RunLoop
) {}
185 void OutputRequestCallback(scoped_ptr
<cc::CopyOutputResult
> result
) {
186 result_
= result
->TakeBitmap();
190 void WaitForReadback() { run_loop_
->Run(); }
192 const SkBitmap
& result() const { return *result_
; }
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
{
214 explicit TestLayerDelegate() { reset(); }
215 ~TestLayerDelegate() override
{}
217 void AddColor(SkColor color
) {
218 colors_
.push_back(color
);
221 const gfx::Size
& paint_size() const { return paint_size_
; }
222 int color_index() const { return color_index_
; }
224 std::string
ToScaleString() const {
225 return base::StringPrintf("%.1f %.1f", scale_x_
, scale_y_
);
228 float device_scale_factor() const {
229 return device_scale_factor_
;
232 // Overridden from LayerDelegate:
233 void OnPaintLayer(gfx::Canvas
* canvas
) override
{
234 SkISize size
= canvas
->sk_canvas()->getBaseLayerSize();
235 paint_size_
= gfx::Size(size
.width(), size
.height());
236 canvas
->DrawColor(colors_
[color_index_
]);
237 color_index_
= (color_index_
+ 1) % static_cast<int>(colors_
.size());
238 const SkMatrix
& matrix
= canvas
->sk_canvas()->getTotalMatrix();
239 scale_x_
= matrix
.getScaleX();
240 scale_y_
= matrix
.getScaleY();
243 void OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) override
{}
245 void OnDeviceScaleFactorChanged(float device_scale_factor
) override
{
246 device_scale_factor_
= device_scale_factor
;
249 base::Closure
PrepareForLayerBoundsChange() override
{
250 return base::Closure();
255 paint_size_
.SetSize(0, 0);
256 scale_x_
= scale_y_
= 0.0f
;
257 device_scale_factor_
= 0.0f
;
261 std::vector
<SkColor
> colors_
;
263 gfx::Size paint_size_
;
266 float device_scale_factor_
;
268 DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate
);
271 // LayerDelegate that verifies that a layer was asked to update its canvas.
272 class DrawTreeLayerDelegate
: public LayerDelegate
{
274 DrawTreeLayerDelegate() : painted_(false) {}
275 ~DrawTreeLayerDelegate() override
{}
281 bool painted() const { return painted_
; }
284 // Overridden from LayerDelegate:
285 void OnPaintLayer(gfx::Canvas
* canvas
) override
{
287 canvas
->DrawColor(SK_ColorWHITE
);
289 void OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) override
{}
290 void OnDeviceScaleFactorChanged(float device_scale_factor
) override
{}
291 base::Closure
PrepareForLayerBoundsChange() override
{
292 return base::Closure();
297 DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate
);
300 // The simplest possible layer delegate. Does nothing.
301 class NullLayerDelegate
: public LayerDelegate
{
303 NullLayerDelegate() {}
304 ~NullLayerDelegate() override
{}
307 // Overridden from LayerDelegate:
308 void OnPaintLayer(gfx::Canvas
* canvas
) override
{}
309 void OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) override
{}
310 void OnDeviceScaleFactorChanged(float device_scale_factor
) override
{}
311 base::Closure
PrepareForLayerBoundsChange() override
{
312 return base::Closure();
315 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate
);
318 // Remembers if it has been notified.
319 class TestCompositorObserver
: public CompositorObserver
{
321 TestCompositorObserver()
322 : committed_(false), started_(false), ended_(false), aborted_(false) {}
324 bool committed() const { return committed_
; }
325 bool notified() const { return started_
&& ended_
; }
326 bool aborted() const { return aborted_
; }
336 void OnCompositingDidCommit(Compositor
* compositor
) override
{
340 void OnCompositingStarted(Compositor
* compositor
,
341 base::TimeTicks start_time
) override
{
345 void OnCompositingEnded(Compositor
* compositor
) override
{ ended_
= true; }
347 void OnCompositingAborted(Compositor
* compositor
) override
{
351 void OnCompositingLockStateChanged(Compositor
* compositor
) override
{}
353 void OnCompositingShuttingDown(Compositor
* compositor
) override
{}
360 DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver
);
365 TEST_F(LayerWithRealCompositorTest
, Draw
) {
366 scoped_ptr
<Layer
> layer(CreateColorLayer(SK_ColorRED
,
367 gfx::Rect(20, 20, 50, 50)));
368 DrawTree(layer
.get());
371 // Create this hierarchy:
377 TEST_F(LayerWithRealCompositorTest
, Hierarchy
) {
378 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorRED
,
379 gfx::Rect(20, 20, 400, 400)));
380 scoped_ptr
<Layer
> l2(CreateColorLayer(SK_ColorBLUE
,
381 gfx::Rect(10, 10, 350, 350)));
382 scoped_ptr
<Layer
> l3(CreateColorLayer(SK_ColorYELLOW
,
383 gfx::Rect(5, 5, 25, 25)));
384 scoped_ptr
<Layer
> l4(CreateColorLayer(SK_ColorMAGENTA
,
385 gfx::Rect(300, 300, 100, 100)));
394 class LayerWithDelegateTest
: public testing::Test
{
396 LayerWithDelegateTest() {}
397 ~LayerWithDelegateTest() override
{}
399 // Overridden from testing::Test:
400 void SetUp() override
{
401 bool enable_pixel_output
= false;
402 ui::ContextFactory
* context_factory
=
403 InitializeContextFactoryForTests(enable_pixel_output
);
405 const gfx::Rect
host_bounds(1000, 1000);
406 compositor_host_
.reset(TestCompositorHost::Create(host_bounds
,
408 compositor_host_
->Show();
411 void TearDown() override
{
412 compositor_host_
.reset();
413 TerminateContextFactoryForTests();
416 Compositor
* compositor() { return compositor_host_
->GetCompositor(); }
418 virtual Layer
* CreateLayer(LayerType type
) {
419 return new Layer(type
);
422 Layer
* CreateColorLayer(SkColor color
, const gfx::Rect
& bounds
) {
423 Layer
* layer
= new ColoredLayer(color
);
424 layer
->SetBounds(bounds
);
428 virtual Layer
* CreateNoTextureLayer(const gfx::Rect
& bounds
) {
429 Layer
* layer
= CreateLayer(LAYER_NOT_DRAWN
);
430 layer
->SetBounds(bounds
);
434 void DrawTree(Layer
* root
) {
435 compositor()->SetRootLayer(root
);
439 // Invalidates the entire contents of the layer.
440 void SchedulePaintForLayer(Layer
* layer
) {
441 layer
->SchedulePaint(
442 gfx::Rect(0, 0, layer
->bounds().width(), layer
->bounds().height()));
445 // Invokes DrawTree on the compositor.
447 compositor()->ScheduleDraw();
452 DrawWaiterForTest::WaitForCompositingStarted(compositor());
455 void WaitForCommit() {
456 DrawWaiterForTest::WaitForCommit(compositor());
460 scoped_ptr
<TestCompositorHost
> compositor_host_
;
462 DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest
);
467 TEST_F(LayerWithDelegateTest
, ConvertPointToLayer_Simple
) {
468 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorRED
,
469 gfx::Rect(20, 20, 400, 400)));
470 scoped_ptr
<Layer
> l2(CreateColorLayer(SK_ColorBLUE
,
471 gfx::Rect(10, 10, 350, 350)));
475 gfx::Point
point1_in_l2_coords(5, 5);
476 Layer::ConvertPointToLayer(l2
.get(), l1
.get(), &point1_in_l2_coords
);
477 gfx::Point
point1_in_l1_coords(15, 15);
478 EXPECT_EQ(point1_in_l1_coords
, point1_in_l2_coords
);
480 gfx::Point
point2_in_l1_coords(5, 5);
481 Layer::ConvertPointToLayer(l1
.get(), l2
.get(), &point2_in_l1_coords
);
482 gfx::Point
point2_in_l2_coords(-5, -5);
483 EXPECT_EQ(point2_in_l2_coords
, point2_in_l1_coords
);
489 TEST_F(LayerWithDelegateTest
, ConvertPointToLayer_Medium
) {
490 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorRED
,
491 gfx::Rect(20, 20, 400, 400)));
492 scoped_ptr
<Layer
> l2(CreateColorLayer(SK_ColorBLUE
,
493 gfx::Rect(10, 10, 350, 350)));
494 scoped_ptr
<Layer
> l3(CreateColorLayer(SK_ColorYELLOW
,
495 gfx::Rect(10, 10, 100, 100)));
500 gfx::Point
point1_in_l3_coords(5, 5);
501 Layer::ConvertPointToLayer(l3
.get(), l1
.get(), &point1_in_l3_coords
);
502 gfx::Point
point1_in_l1_coords(25, 25);
503 EXPECT_EQ(point1_in_l1_coords
, point1_in_l3_coords
);
505 gfx::Point
point2_in_l1_coords(5, 5);
506 Layer::ConvertPointToLayer(l1
.get(), l3
.get(), &point2_in_l1_coords
);
507 gfx::Point
point2_in_l3_coords(-15, -15);
508 EXPECT_EQ(point2_in_l3_coords
, point2_in_l1_coords
);
511 TEST_F(LayerWithRealCompositorTest
, Delegate
) {
512 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorBLACK
,
513 gfx::Rect(20, 20, 400, 400)));
514 GetCompositor()->SetRootLayer(l1
.get());
517 TestLayerDelegate delegate
;
518 l1
->set_delegate(&delegate
);
519 delegate
.AddColor(SK_ColorWHITE
);
520 delegate
.AddColor(SK_ColorYELLOW
);
521 delegate
.AddColor(SK_ColorGREEN
);
523 l1
->SchedulePaint(gfx::Rect(0, 0, 400, 400));
526 EXPECT_EQ(delegate
.color_index(), 1);
527 EXPECT_EQ(delegate
.paint_size(), l1
->bounds().size());
529 l1
->SchedulePaint(gfx::Rect(10, 10, 200, 200));
531 EXPECT_EQ(delegate
.color_index(), 2);
532 EXPECT_EQ(delegate
.paint_size(), gfx::Size(200, 200));
534 l1
->SchedulePaint(gfx::Rect(5, 5, 50, 50));
536 EXPECT_EQ(delegate
.color_index(), 0);
537 EXPECT_EQ(delegate
.paint_size(), gfx::Size(50, 50));
540 TEST_F(LayerWithRealCompositorTest
, DrawTree
) {
541 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorRED
,
542 gfx::Rect(20, 20, 400, 400)));
543 scoped_ptr
<Layer
> l2(CreateColorLayer(SK_ColorBLUE
,
544 gfx::Rect(10, 10, 350, 350)));
545 scoped_ptr
<Layer
> l3(CreateColorLayer(SK_ColorYELLOW
,
546 gfx::Rect(10, 10, 100, 100)));
550 GetCompositor()->SetRootLayer(l1
.get());
553 DrawTreeLayerDelegate d1
;
554 l1
->set_delegate(&d1
);
555 DrawTreeLayerDelegate d2
;
556 l2
->set_delegate(&d2
);
557 DrawTreeLayerDelegate d3
;
558 l3
->set_delegate(&d3
);
560 l2
->SchedulePaint(gfx::Rect(5, 5, 5, 5));
562 EXPECT_FALSE(d1
.painted());
563 EXPECT_TRUE(d2
.painted());
564 EXPECT_FALSE(d3
.painted());
567 // Tests no-texture Layers.
568 // Create this hierarchy:
570 // +-- L2 - NO TEXTURE
574 TEST_F(LayerWithRealCompositorTest
, HierarchyNoTexture
) {
575 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorRED
,
576 gfx::Rect(20, 20, 400, 400)));
577 scoped_ptr
<Layer
> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
578 scoped_ptr
<Layer
> l3(CreateColorLayer(SK_ColorYELLOW
,
579 gfx::Rect(5, 5, 25, 25)));
580 scoped_ptr
<Layer
> l4(CreateColorLayer(SK_ColorMAGENTA
,
581 gfx::Rect(300, 300, 100, 100)));
587 GetCompositor()->SetRootLayer(l1
.get());
590 DrawTreeLayerDelegate d2
;
591 l2
->set_delegate(&d2
);
592 DrawTreeLayerDelegate d3
;
593 l3
->set_delegate(&d3
);
595 l2
->SchedulePaint(gfx::Rect(5, 5, 5, 5));
596 l3
->SchedulePaint(gfx::Rect(5, 5, 5, 5));
599 // |d2| should not have received a paint notification since it has no texture.
600 EXPECT_FALSE(d2
.painted());
601 // |d3| should have received a paint notification.
602 EXPECT_TRUE(d3
.painted());
605 class LayerWithNullDelegateTest
: public LayerWithDelegateTest
{
607 LayerWithNullDelegateTest() {}
608 ~LayerWithNullDelegateTest() override
{}
610 void SetUp() override
{
611 LayerWithDelegateTest::SetUp();
612 default_layer_delegate_
.reset(new NullLayerDelegate());
615 Layer
* CreateLayer(LayerType type
) override
{
616 Layer
* layer
= new Layer(type
);
617 layer
->set_delegate(default_layer_delegate_
.get());
621 Layer
* CreateTextureRootLayer(const gfx::Rect
& bounds
) {
622 Layer
* layer
= CreateTextureLayer(bounds
);
623 compositor()->SetRootLayer(layer
);
627 Layer
* CreateTextureLayer(const gfx::Rect
& bounds
) {
628 Layer
* layer
= CreateLayer(LAYER_TEXTURED
);
629 layer
->SetBounds(bounds
);
633 Layer
* CreateNoTextureLayer(const gfx::Rect
& bounds
) override
{
634 Layer
* layer
= CreateLayer(LAYER_NOT_DRAWN
);
635 layer
->SetBounds(bounds
);
640 scoped_ptr
<NullLayerDelegate
> default_layer_delegate_
;
642 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest
);
645 TEST_F(LayerWithNullDelegateTest
, EscapedDebugNames
) {
646 scoped_ptr
<Layer
> layer(CreateLayer(LAYER_NOT_DRAWN
));
647 std::string name
= "\"\'\\/\b\f\n\r\t\n";
648 layer
->set_name(name
);
649 scoped_refptr
<base::trace_event::ConvertableToTraceFormat
> debug_info
=
650 layer
->TakeDebugInfo();
651 EXPECT_TRUE(!!debug_info
.get());
653 debug_info
->AppendAsTraceFormat(&json
);
654 base::JSONReader json_reader
;
655 scoped_ptr
<base::Value
> debug_info_value(json_reader
.ReadToValue(json
));
656 EXPECT_TRUE(!!debug_info_value
);
657 EXPECT_TRUE(debug_info_value
->IsType(base::Value::TYPE_DICTIONARY
));
658 base::DictionaryValue
* dictionary
= 0;
659 EXPECT_TRUE(debug_info_value
->GetAsDictionary(&dictionary
));
660 std::string roundtrip
;
661 EXPECT_TRUE(dictionary
->GetString("layer_name", &roundtrip
));
662 EXPECT_EQ(name
, roundtrip
);
665 void ReturnMailbox(bool* run
, uint32 sync_point
, bool is_lost
) {
669 TEST_F(LayerWithNullDelegateTest
, SwitchLayerPreservesCCLayerState
) {
670 scoped_ptr
<Layer
> l1(CreateLayer(LAYER_SOLID_COLOR
));
671 l1
->SetFillsBoundsOpaquely(true);
672 l1
->SetForceRenderSurface(true);
673 l1
->SetVisible(false);
675 EXPECT_EQ(gfx::Point3F(), l1
->cc_layer()->transform_origin());
676 EXPECT_TRUE(l1
->cc_layer()->DrawsContent());
677 EXPECT_TRUE(l1
->cc_layer()->contents_opaque());
678 EXPECT_TRUE(l1
->cc_layer()->force_render_surface());
679 EXPECT_TRUE(l1
->cc_layer()->hide_layer_and_subtree());
681 cc::Layer
* before_layer
= l1
->cc_layer();
683 bool callback1_run
= false;
684 cc::TextureMailbox
mailbox(gpu::Mailbox::Generate(), 0, 0);
685 l1
->SetTextureMailbox(mailbox
,
686 cc::SingleReleaseCallback::Create(
687 base::Bind(ReturnMailbox
, &callback1_run
)),
690 EXPECT_NE(before_layer
, l1
->cc_layer());
692 EXPECT_EQ(gfx::Point3F(), l1
->cc_layer()->transform_origin());
693 EXPECT_TRUE(l1
->cc_layer()->DrawsContent());
694 EXPECT_TRUE(l1
->cc_layer()->contents_opaque());
695 EXPECT_TRUE(l1
->cc_layer()->force_render_surface());
696 EXPECT_TRUE(l1
->cc_layer()->hide_layer_and_subtree());
697 EXPECT_FALSE(callback1_run
);
699 bool callback2_run
= false;
700 mailbox
= cc::TextureMailbox(gpu::Mailbox::Generate(), 0, 0);
701 l1
->SetTextureMailbox(mailbox
,
702 cc::SingleReleaseCallback::Create(
703 base::Bind(ReturnMailbox
, &callback2_run
)),
705 EXPECT_TRUE(callback1_run
);
706 EXPECT_FALSE(callback2_run
);
708 l1
->SetShowSolidColorContent();
709 EXPECT_EQ(gfx::Point3F(), l1
->cc_layer()->transform_origin());
710 EXPECT_TRUE(l1
->cc_layer()->DrawsContent());
711 EXPECT_TRUE(l1
->cc_layer()->contents_opaque());
712 EXPECT_TRUE(l1
->cc_layer()->force_render_surface());
713 EXPECT_TRUE(l1
->cc_layer()->hide_layer_and_subtree());
714 EXPECT_TRUE(callback2_run
);
717 // Various visibile/drawn assertions.
718 TEST_F(LayerWithNullDelegateTest
, Visibility
) {
719 scoped_ptr
<Layer
> l1(new Layer(LAYER_TEXTURED
));
720 scoped_ptr
<Layer
> l2(new Layer(LAYER_TEXTURED
));
721 scoped_ptr
<Layer
> l3(new Layer(LAYER_TEXTURED
));
725 NullLayerDelegate delegate
;
726 l1
->set_delegate(&delegate
);
727 l2
->set_delegate(&delegate
);
728 l3
->set_delegate(&delegate
);
730 // Layers should initially be drawn.
731 EXPECT_TRUE(l1
->IsDrawn());
732 EXPECT_TRUE(l2
->IsDrawn());
733 EXPECT_TRUE(l3
->IsDrawn());
734 EXPECT_FALSE(l1
->cc_layer()->hide_layer_and_subtree());
735 EXPECT_FALSE(l2
->cc_layer()->hide_layer_and_subtree());
736 EXPECT_FALSE(l3
->cc_layer()->hide_layer_and_subtree());
738 compositor()->SetRootLayer(l1
.get());
742 l1
->SetVisible(false);
743 EXPECT_FALSE(l1
->IsDrawn());
744 EXPECT_FALSE(l2
->IsDrawn());
745 EXPECT_FALSE(l3
->IsDrawn());
746 EXPECT_TRUE(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 l3
->SetVisible(false);
751 EXPECT_FALSE(l1
->IsDrawn());
752 EXPECT_FALSE(l2
->IsDrawn());
753 EXPECT_FALSE(l3
->IsDrawn());
754 EXPECT_TRUE(l1
->cc_layer()->hide_layer_and_subtree());
755 EXPECT_FALSE(l2
->cc_layer()->hide_layer_and_subtree());
756 EXPECT_TRUE(l3
->cc_layer()->hide_layer_and_subtree());
758 l1
->SetVisible(true);
759 EXPECT_TRUE(l1
->IsDrawn());
760 EXPECT_TRUE(l2
->IsDrawn());
761 EXPECT_FALSE(l3
->IsDrawn());
762 EXPECT_FALSE(l1
->cc_layer()->hide_layer_and_subtree());
763 EXPECT_FALSE(l2
->cc_layer()->hide_layer_and_subtree());
764 EXPECT_TRUE(l3
->cc_layer()->hide_layer_and_subtree());
767 // Checks that stacking-related methods behave as advertised.
768 TEST_F(LayerWithNullDelegateTest
, Stacking
) {
769 scoped_ptr
<Layer
> root(new Layer(LAYER_NOT_DRAWN
));
770 scoped_ptr
<Layer
> l1(new Layer(LAYER_TEXTURED
));
771 scoped_ptr
<Layer
> l2(new Layer(LAYER_TEXTURED
));
772 scoped_ptr
<Layer
> l3(new Layer(LAYER_TEXTURED
));
780 // Layers' children are stored in bottom-to-top order.
781 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root
.get()));
783 root
->StackAtTop(l3
.get());
784 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root
.get()));
786 root
->StackAtTop(l1
.get());
787 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root
.get()));
789 root
->StackAtTop(l1
.get());
790 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root
.get()));
792 root
->StackAbove(l2
.get(), l3
.get());
793 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root
.get()));
795 root
->StackAbove(l1
.get(), l3
.get());
796 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root
.get()));
798 root
->StackAbove(l2
.get(), l1
.get());
799 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root
.get()));
801 root
->StackAtBottom(l2
.get());
802 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root
.get()));
804 root
->StackAtBottom(l3
.get());
805 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root
.get()));
807 root
->StackAtBottom(l3
.get());
808 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root
.get()));
810 root
->StackBelow(l2
.get(), l3
.get());
811 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root
.get()));
813 root
->StackBelow(l1
.get(), l3
.get());
814 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root
.get()));
816 root
->StackBelow(l3
.get(), l2
.get());
817 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root
.get()));
819 root
->StackBelow(l3
.get(), l2
.get());
820 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root
.get()));
822 root
->StackBelow(l3
.get(), l1
.get());
823 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root
.get()));
826 // Verifies SetBounds triggers the appropriate painting/drawing.
827 TEST_F(LayerWithNullDelegateTest
, SetBoundsSchedulesPaint
) {
828 scoped_ptr
<Layer
> l1(CreateTextureLayer(gfx::Rect(0, 0, 200, 200)));
829 compositor()->SetRootLayer(l1
.get());
833 l1
->SetBounds(gfx::Rect(5, 5, 200, 200));
835 // The CompositorDelegate (us) should have been told to draw for a move.
838 l1
->SetBounds(gfx::Rect(5, 5, 100, 100));
840 // The CompositorDelegate (us) should have been told to draw for a resize.
844 void ExpectRgba(int x
, int y
, SkColor expected_color
, SkColor actual_color
) {
845 EXPECT_EQ(expected_color
, actual_color
)
846 << "Pixel error at x=" << x
<< " y=" << y
<< "; "
848 << SkColorGetR(actual_color
) << ","
849 << SkColorGetG(actual_color
) << ","
850 << SkColorGetB(actual_color
) << ","
851 << SkColorGetA(actual_color
) << "); "
853 << SkColorGetR(expected_color
) << ","
854 << SkColorGetG(expected_color
) << ","
855 << SkColorGetB(expected_color
) << ","
856 << SkColorGetA(expected_color
) << ")";
859 // Checks that pixels are actually drawn to the screen with a read back.
860 TEST_F(LayerWithRealCompositorTest
, DrawPixels
) {
861 gfx::Size viewport_size
= GetCompositor()->size();
863 // The window should be some non-trivial size but may not be exactly
864 // 500x500 on all platforms/bots.
865 EXPECT_GE(viewport_size
.width(), 200);
866 EXPECT_GE(viewport_size
.height(), 200);
868 int blue_height
= 10;
870 scoped_ptr
<Layer
> layer(
871 CreateColorLayer(SK_ColorRED
, gfx::Rect(viewport_size
)));
872 scoped_ptr
<Layer
> layer2(
873 CreateColorLayer(SK_ColorBLUE
,
874 gfx::Rect(0, 0, viewport_size
.width(), blue_height
)));
876 layer
->Add(layer2
.get());
878 DrawTree(layer
.get());
881 ReadPixels(&bitmap
, gfx::Rect(viewport_size
));
882 ASSERT_FALSE(bitmap
.empty());
884 SkAutoLockPixels
lock(bitmap
);
885 for (int x
= 0; x
< viewport_size
.width(); x
++) {
886 for (int y
= 0; y
< viewport_size
.height(); y
++) {
887 SkColor actual_color
= bitmap
.getColor(x
, y
);
888 SkColor expected_color
= y
< blue_height
? SK_ColorBLUE
: SK_ColorRED
;
889 ExpectRgba(x
, y
, expected_color
, actual_color
);
894 // Checks that drawing a layer with transparent pixels is blended correctly
895 // with the lower layer.
896 TEST_F(LayerWithRealCompositorTest
, DrawAlphaBlendedPixels
) {
897 gfx::Size viewport_size
= GetCompositor()->size();
900 EXPECT_GE(viewport_size
.width(), test_size
);
901 EXPECT_GE(viewport_size
.height(), test_size
);
903 // Blue with a wee bit of transparency.
904 SkColor blue_with_alpha
= SkColorSetARGBInline(40, 10, 20, 200);
905 SkColor blend_color
= SkColorSetARGBInline(255, 216, 3, 32);
907 scoped_ptr
<Layer
> background_layer(
908 CreateColorLayer(SK_ColorRED
, gfx::Rect(viewport_size
)));
909 scoped_ptr
<Layer
> foreground_layer(
910 CreateColorLayer(blue_with_alpha
, gfx::Rect(viewport_size
)));
912 // This must be set to false for layers with alpha to be blended correctly.
913 foreground_layer
->SetFillsBoundsOpaquely(false);
915 background_layer
->Add(foreground_layer
.get());
916 DrawTree(background_layer
.get());
919 ReadPixels(&bitmap
, gfx::Rect(viewport_size
));
920 ASSERT_FALSE(bitmap
.empty());
922 SkAutoLockPixels
lock(bitmap
);
923 for (int x
= 0; x
< test_size
; x
++) {
924 for (int y
= 0; y
< test_size
; y
++) {
925 SkColor actual_color
= bitmap
.getColor(x
, y
);
926 ExpectRgba(x
, y
, blend_color
, actual_color
);
931 // Checks that using the AlphaShape filter applied to a layer with
932 // transparency, alpha-blends properly with the layer below.
933 TEST_F(LayerWithRealCompositorTest
, DrawAlphaThresholdFilterPixels
) {
934 gfx::Size viewport_size
= GetCompositor()->size();
937 EXPECT_GE(viewport_size
.width(), test_size
);
938 EXPECT_GE(viewport_size
.height(), test_size
);
940 int blue_height
= 10;
941 SkColor blue_with_alpha
= SkColorSetARGBInline(40, 0, 0, 255);
942 SkColor blend_color
= SkColorSetARGBInline(255, 215, 0, 40);
944 scoped_ptr
<Layer
> background_layer(
945 CreateColorLayer(SK_ColorRED
, gfx::Rect(viewport_size
)));
946 scoped_ptr
<Layer
> foreground_layer(
947 CreateColorLayer(blue_with_alpha
, gfx::Rect(viewport_size
)));
949 // Add a shape to restrict the visible part of the layer.
951 shape
.setRect(0, 0, viewport_size
.width(), blue_height
);
952 foreground_layer
->SetAlphaShape(make_scoped_ptr(new SkRegion(shape
)));
954 foreground_layer
->SetFillsBoundsOpaquely(false);
956 background_layer
->Add(foreground_layer
.get());
957 DrawTree(background_layer
.get());
960 ReadPixels(&bitmap
, gfx::Rect(viewport_size
));
961 ASSERT_FALSE(bitmap
.empty());
963 SkAutoLockPixels
lock(bitmap
);
964 for (int x
= 0; x
< test_size
; x
++) {
965 for (int y
= 0; y
< test_size
; y
++) {
966 SkColor actual_color
= bitmap
.getColor(x
, y
);
967 ExpectRgba(x
, y
, actual_color
,
968 y
< blue_height
? blend_color
: SK_ColorRED
);
973 // Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
974 TEST_F(LayerWithRealCompositorTest
, SetRootLayer
) {
975 Compositor
* compositor
= GetCompositor();
976 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorRED
,
977 gfx::Rect(20, 20, 400, 400)));
978 scoped_ptr
<Layer
> l2(CreateColorLayer(SK_ColorBLUE
,
979 gfx::Rect(10, 10, 350, 350)));
981 EXPECT_EQ(NULL
, l1
->GetCompositor());
982 EXPECT_EQ(NULL
, l2
->GetCompositor());
984 compositor
->SetRootLayer(l1
.get());
985 EXPECT_EQ(compositor
, l1
->GetCompositor());
988 EXPECT_EQ(compositor
, l2
->GetCompositor());
990 l1
->Remove(l2
.get());
991 EXPECT_EQ(NULL
, l2
->GetCompositor());
994 EXPECT_EQ(compositor
, l2
->GetCompositor());
996 compositor
->SetRootLayer(NULL
);
997 EXPECT_EQ(NULL
, l1
->GetCompositor());
998 EXPECT_EQ(NULL
, l2
->GetCompositor());
1001 // Checks that compositor observers are notified when:
1002 // - DrawTree is called,
1003 // - After ScheduleDraw is called, or
1004 // - Whenever SetBounds, SetOpacity or SetTransform are called.
1005 // TODO(vollick): could be reorganized into compositor_unittest.cc
1006 TEST_F(LayerWithRealCompositorTest
, CompositorObservers
) {
1007 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorRED
,
1008 gfx::Rect(20, 20, 400, 400)));
1009 scoped_ptr
<Layer
> l2(CreateColorLayer(SK_ColorBLUE
,
1010 gfx::Rect(10, 10, 350, 350)));
1012 TestCompositorObserver observer
;
1013 GetCompositor()->AddObserver(&observer
);
1015 // Explicitly called DrawTree should cause the observers to be notified.
1016 // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
1018 EXPECT_TRUE(observer
.notified());
1020 // ScheduleDraw without any visible change should cause a commit.
1024 EXPECT_TRUE(observer
.committed());
1026 // Moving, but not resizing, a layer should alert the observers.
1028 l2
->SetBounds(gfx::Rect(0, 0, 350, 350));
1030 EXPECT_TRUE(observer
.notified());
1032 // So should resizing a layer.
1034 l2
->SetBounds(gfx::Rect(0, 0, 400, 400));
1036 EXPECT_TRUE(observer
.notified());
1038 // Opacity changes should alert the observers.
1040 l2
->SetOpacity(0.5f
);
1042 EXPECT_TRUE(observer
.notified());
1044 // So should setting the opacity back.
1046 l2
->SetOpacity(1.0f
);
1048 EXPECT_TRUE(observer
.notified());
1050 // Setting the transform of a layer should alert the observers.
1052 gfx::Transform transform
;
1053 transform
.Translate(200.0, 200.0);
1054 transform
.Rotate(90.0);
1055 transform
.Translate(-200.0, -200.0);
1056 l2
->SetTransform(transform
);
1058 EXPECT_TRUE(observer
.notified());
1060 // A change resulting in an aborted swap buffer should alert the observer
1061 // and also signal an abort.
1063 l2
->SetOpacity(0.1f
);
1064 GetCompositor()->DidAbortSwapBuffers();
1066 EXPECT_TRUE(observer
.notified());
1067 EXPECT_TRUE(observer
.aborted());
1069 GetCompositor()->RemoveObserver(&observer
);
1071 // Opacity changes should no longer alert the removed observer.
1073 l2
->SetOpacity(0.5f
);
1076 EXPECT_FALSE(observer
.notified());
1079 // Checks that modifying the hierarchy correctly affects final composite.
1080 TEST_F(LayerWithRealCompositorTest
, ModifyHierarchy
) {
1081 GetCompositor()->SetScaleAndSize(1.0f
, gfx::Size(50, 50));
1087 scoped_ptr
<Layer
> l0(CreateColorLayer(SK_ColorRED
,
1088 gfx::Rect(0, 0, 50, 50)));
1089 scoped_ptr
<Layer
> l11(CreateColorLayer(SK_ColorGREEN
,
1090 gfx::Rect(0, 0, 25, 25)));
1091 scoped_ptr
<Layer
> l21(CreateColorLayer(SK_ColorMAGENTA
,
1092 gfx::Rect(0, 0, 15, 15)));
1093 scoped_ptr
<Layer
> l12(CreateColorLayer(SK_ColorBLUE
,
1094 gfx::Rect(10, 10, 25, 25)));
1096 base::FilePath ref_img1
=
1097 test_data_directory().AppendASCII("ModifyHierarchy1.png");
1098 base::FilePath ref_img2
=
1099 test_data_directory().AppendASCII("ModifyHierarchy2.png");
1103 l11
->Add(l21
.get());
1106 ReadPixels(&bitmap
);
1107 ASSERT_FALSE(bitmap
.empty());
1108 // WritePNGFile(bitmap, ref_img1);
1109 EXPECT_TRUE(MatchesPNGFile(bitmap
, ref_img1
, cc::ExactPixelComparator(true)));
1111 l0
->StackAtTop(l11
.get());
1113 ReadPixels(&bitmap
);
1114 ASSERT_FALSE(bitmap
.empty());
1115 // WritePNGFile(bitmap, ref_img2);
1116 EXPECT_TRUE(MatchesPNGFile(bitmap
, ref_img2
, cc::ExactPixelComparator(true)));
1118 // should restore to original configuration
1119 l0
->StackAbove(l12
.get(), l11
.get());
1121 ReadPixels(&bitmap
);
1122 ASSERT_FALSE(bitmap
.empty());
1123 EXPECT_TRUE(MatchesPNGFile(bitmap
, ref_img1
, cc::ExactPixelComparator(true)));
1125 // l11 back to front
1126 l0
->StackAtTop(l11
.get());
1128 ReadPixels(&bitmap
);
1129 ASSERT_FALSE(bitmap
.empty());
1130 EXPECT_TRUE(MatchesPNGFile(bitmap
, ref_img2
, cc::ExactPixelComparator(true)));
1132 // should restore to original configuration
1133 l0
->StackAbove(l12
.get(), l11
.get());
1135 ReadPixels(&bitmap
);
1136 ASSERT_FALSE(bitmap
.empty());
1137 EXPECT_TRUE(MatchesPNGFile(bitmap
, ref_img1
, cc::ExactPixelComparator(true)));
1139 // l11 back to front
1140 l0
->StackAbove(l11
.get(), l12
.get());
1142 ReadPixels(&bitmap
);
1143 ASSERT_FALSE(bitmap
.empty());
1144 EXPECT_TRUE(MatchesPNGFile(bitmap
, ref_img2
, cc::ExactPixelComparator(true)));
1147 // Opacity is rendered correctly.
1148 // Checks that modifying the hierarchy correctly affects final composite.
1149 TEST_F(LayerWithRealCompositorTest
, Opacity
) {
1150 GetCompositor()->SetScaleAndSize(1.0f
, gfx::Size(50, 50));
1154 scoped_ptr
<Layer
> l0(CreateColorLayer(SK_ColorRED
,
1155 gfx::Rect(0, 0, 50, 50)));
1156 scoped_ptr
<Layer
> l11(CreateColorLayer(SK_ColorGREEN
,
1157 gfx::Rect(0, 0, 25, 25)));
1159 base::FilePath ref_img
= test_data_directory().AppendASCII("Opacity.png");
1161 l11
->SetOpacity(0.75);
1165 ReadPixels(&bitmap
);
1166 ASSERT_FALSE(bitmap
.empty());
1167 // WritePNGFile(bitmap, ref_img);
1168 EXPECT_TRUE(MatchesPNGFile(bitmap
, ref_img
, cc::ExactPixelComparator(true)));
1173 class SchedulePaintLayerDelegate
: public LayerDelegate
{
1175 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL
) {}
1177 ~SchedulePaintLayerDelegate() override
{}
1179 void set_layer(Layer
* layer
) {
1181 layer_
->set_delegate(this);
1184 void SetSchedulePaintRect(const gfx::Rect
& rect
) {
1185 schedule_paint_rect_
= rect
;
1188 int GetPaintCountAndClear() {
1189 int value
= paint_count_
;
1194 const gfx::RectF
& last_clip_rect() const { return last_clip_rect_
; }
1197 // Overridden from LayerDelegate:
1198 void OnPaintLayer(gfx::Canvas
* canvas
) override
{
1200 if (!schedule_paint_rect_
.IsEmpty()) {
1201 layer_
->SchedulePaint(schedule_paint_rect_
);
1202 schedule_paint_rect_
= gfx::Rect();
1204 SkRect sk_clip_rect
;
1205 if (canvas
->sk_canvas()->getClipBounds(&sk_clip_rect
))
1206 last_clip_rect_
= gfx::SkRectToRectF(sk_clip_rect
);
1209 void OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) override
{}
1211 void OnDeviceScaleFactorChanged(float device_scale_factor
) override
{}
1213 base::Closure
PrepareForLayerBoundsChange() override
{
1214 return base::Closure();
1219 gfx::Rect schedule_paint_rect_
;
1220 gfx::RectF last_clip_rect_
;
1222 DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate
);
1227 // Verifies that if SchedulePaint is invoked during painting the layer is still
1229 TEST_F(LayerWithDelegateTest
, SchedulePaintFromOnPaintLayer
) {
1230 scoped_ptr
<Layer
> root(CreateColorLayer(SK_ColorRED
,
1231 gfx::Rect(0, 0, 500, 500)));
1232 SchedulePaintLayerDelegate child_delegate
;
1233 scoped_ptr
<Layer
> child(CreateColorLayer(SK_ColorBLUE
,
1234 gfx::Rect(0, 0, 200, 200)));
1235 child_delegate
.set_layer(child
.get());
1237 root
->Add(child
.get());
1239 SchedulePaintForLayer(root
.get());
1240 DrawTree(root
.get());
1241 child
->SchedulePaint(gfx::Rect(0, 0, 20, 20));
1242 EXPECT_EQ(1, child_delegate
.GetPaintCountAndClear());
1244 // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
1246 child_delegate
.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
1248 EXPECT_EQ(1, child_delegate
.GetPaintCountAndClear());
1250 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
1251 // still need to be painted.
1253 EXPECT_EQ(1, child_delegate
.GetPaintCountAndClear());
1254 EXPECT_TRUE(child_delegate
.last_clip_rect().Contains(
1255 gfx::Rect(10, 10, 30, 30)));
1258 TEST_F(LayerWithRealCompositorTest
, ScaleUpDown
) {
1259 scoped_ptr
<Layer
> root(CreateColorLayer(SK_ColorWHITE
,
1260 gfx::Rect(10, 20, 200, 220)));
1261 TestLayerDelegate root_delegate
;
1262 root_delegate
.AddColor(SK_ColorWHITE
);
1263 root
->set_delegate(&root_delegate
);
1265 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorWHITE
,
1266 gfx::Rect(10, 20, 140, 180)));
1267 TestLayerDelegate l1_delegate
;
1268 l1_delegate
.AddColor(SK_ColorWHITE
);
1269 l1
->set_delegate(&l1_delegate
);
1271 GetCompositor()->SetScaleAndSize(1.0f
, gfx::Size(500, 500));
1272 GetCompositor()->SetRootLayer(root
.get());
1273 root
->Add(l1
.get());
1276 EXPECT_EQ("10,20 200x220", root
->bounds().ToString());
1277 EXPECT_EQ("10,20 140x180", l1
->bounds().ToString());
1278 gfx::Size cc_bounds_size
= root
->cc_layer()->bounds();
1279 EXPECT_EQ("200x220", cc_bounds_size
.ToString());
1280 cc_bounds_size
= l1
->cc_layer()->bounds();
1281 EXPECT_EQ("140x180", cc_bounds_size
.ToString());
1282 // No scale change, so no scale notification.
1283 EXPECT_EQ(0.0f
, root_delegate
.device_scale_factor());
1284 EXPECT_EQ(0.0f
, l1_delegate
.device_scale_factor());
1286 EXPECT_EQ("200x220", root_delegate
.paint_size().ToString());
1287 EXPECT_EQ("140x180", l1_delegate
.paint_size().ToString());
1289 // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
1290 GetCompositor()->SetScaleAndSize(2.0f
, gfx::Size(500, 500));
1291 EXPECT_EQ("10,20 200x220", root
->bounds().ToString());
1292 EXPECT_EQ("10,20 140x180", l1
->bounds().ToString());
1293 // CC layer should still match the UI layer bounds.
1294 cc_bounds_size
= root
->cc_layer()->bounds();
1295 EXPECT_EQ("200x220", cc_bounds_size
.ToString());
1296 cc_bounds_size
= l1
->cc_layer()->bounds();
1297 EXPECT_EQ("140x180", cc_bounds_size
.ToString());
1298 // New scale factor must have been notified.
1299 EXPECT_EQ(2.0f
, root_delegate
.device_scale_factor());
1300 EXPECT_EQ(2.0f
, l1_delegate
.device_scale_factor());
1302 // Canvas size must have been scaled down up.
1304 EXPECT_EQ("400x440", root_delegate
.paint_size().ToString());
1305 EXPECT_EQ("2.0 2.0", root_delegate
.ToScaleString());
1306 EXPECT_EQ("280x360", l1_delegate
.paint_size().ToString());
1307 EXPECT_EQ("2.0 2.0", l1_delegate
.ToScaleString());
1309 // Scale down back to 1.0f.
1310 GetCompositor()->SetScaleAndSize(1.0f
, gfx::Size(500, 500));
1311 EXPECT_EQ("10,20 200x220", root
->bounds().ToString());
1312 EXPECT_EQ("10,20 140x180", l1
->bounds().ToString());
1313 // CC layer should still match the UI layer bounds.
1314 cc_bounds_size
= root
->cc_layer()->bounds();
1315 EXPECT_EQ("200x220", cc_bounds_size
.ToString());
1316 cc_bounds_size
= l1
->cc_layer()->bounds();
1317 EXPECT_EQ("140x180", cc_bounds_size
.ToString());
1318 // New scale factor must have been notified.
1319 EXPECT_EQ(1.0f
, root_delegate
.device_scale_factor());
1320 EXPECT_EQ(1.0f
, l1_delegate
.device_scale_factor());
1322 // Canvas size must have been scaled down too.
1324 EXPECT_EQ("200x220", root_delegate
.paint_size().ToString());
1325 EXPECT_EQ("1.0 1.0", root_delegate
.ToScaleString());
1326 EXPECT_EQ("140x180", l1_delegate
.paint_size().ToString());
1327 EXPECT_EQ("1.0 1.0", l1_delegate
.ToScaleString());
1329 root_delegate
.reset();
1330 l1_delegate
.reset();
1331 // Just changing the size shouldn't notify the scale change nor
1333 GetCompositor()->SetScaleAndSize(1.0f
, gfx::Size(1000, 1000));
1334 // No scale change, so no scale notification.
1335 EXPECT_EQ(0.0f
, root_delegate
.device_scale_factor());
1336 EXPECT_EQ(0.0f
, l1_delegate
.device_scale_factor());
1338 EXPECT_EQ("0x0", root_delegate
.paint_size().ToString());
1339 EXPECT_EQ("0.0 0.0", root_delegate
.ToScaleString());
1340 EXPECT_EQ("0x0", l1_delegate
.paint_size().ToString());
1341 EXPECT_EQ("0.0 0.0", l1_delegate
.ToScaleString());
1344 TEST_F(LayerWithRealCompositorTest
, ScaleReparent
) {
1345 scoped_ptr
<Layer
> root(CreateColorLayer(SK_ColorWHITE
,
1346 gfx::Rect(10, 20, 200, 220)));
1347 scoped_ptr
<Layer
> l1(CreateColorLayer(SK_ColorWHITE
,
1348 gfx::Rect(10, 20, 140, 180)));
1349 TestLayerDelegate l1_delegate
;
1350 l1_delegate
.AddColor(SK_ColorWHITE
);
1351 l1
->set_delegate(&l1_delegate
);
1353 GetCompositor()->SetScaleAndSize(1.0f
, gfx::Size(500, 500));
1354 GetCompositor()->SetRootLayer(root
.get());
1357 root
->Add(l1
.get());
1358 EXPECT_EQ("10,20 140x180", l1
->bounds().ToString());
1359 gfx::Size cc_bounds_size
= l1
->cc_layer()->bounds();
1360 EXPECT_EQ("140x180", cc_bounds_size
.ToString());
1361 EXPECT_EQ(0.0f
, l1_delegate
.device_scale_factor());
1364 EXPECT_EQ("140x180", l1_delegate
.paint_size().ToString());
1365 EXPECT_EQ("1.0 1.0", l1_delegate
.ToScaleString());
1367 // Remove l1 from root and change the scale.
1368 root
->Remove(l1
.get());
1369 EXPECT_EQ(NULL
, l1
->parent());
1370 EXPECT_EQ(NULL
, l1
->GetCompositor());
1371 GetCompositor()->SetScaleAndSize(2.0f
, gfx::Size(500, 500));
1372 // Sanity check on root and l1.
1373 EXPECT_EQ("10,20 200x220", root
->bounds().ToString());
1374 cc_bounds_size
= l1
->cc_layer()->bounds();
1375 EXPECT_EQ("140x180", cc_bounds_size
.ToString());
1377 root
->Add(l1
.get());
1378 EXPECT_EQ("10,20 140x180", l1
->bounds().ToString());
1379 cc_bounds_size
= l1
->cc_layer()->bounds();
1380 EXPECT_EQ("140x180", cc_bounds_size
.ToString());
1381 EXPECT_EQ(2.0f
, l1_delegate
.device_scale_factor());
1383 EXPECT_EQ("280x360", l1_delegate
.paint_size().ToString());
1384 EXPECT_EQ("2.0 2.0", l1_delegate
.ToScaleString());
1387 // Verifies that when changing bounds on a layer that is invisible, and then
1388 // made visible, the right thing happens:
1389 // - if just a move, then no painting should happen.
1390 // - if a resize, the layer should be repainted.
1391 TEST_F(LayerWithDelegateTest
, SetBoundsWhenInvisible
) {
1392 scoped_ptr
<Layer
> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1394 scoped_ptr
<Layer
> child(CreateLayer(LAYER_TEXTURED
));
1395 child
->SetBounds(gfx::Rect(0, 0, 500, 500));
1396 DrawTreeLayerDelegate delegate
;
1397 child
->set_delegate(&delegate
);
1398 root
->Add(child
.get());
1400 // Paint once for initial damage.
1401 child
->SetVisible(true);
1402 DrawTree(root
.get());
1404 // Reset into invisible state.
1405 child
->SetVisible(false);
1406 DrawTree(root
.get());
1410 child
->SetBounds(gfx::Rect(200, 200, 500, 500));
1411 child
->SetVisible(true);
1412 DrawTree(root
.get());
1413 EXPECT_FALSE(delegate
.painted());
1415 // Reset into invisible state.
1416 child
->SetVisible(false);
1417 DrawTree(root
.get());
1421 child
->SetBounds(gfx::Rect(200, 200, 400, 400));
1422 child
->SetVisible(true);
1423 DrawTree(root
.get());
1424 EXPECT_TRUE(delegate
.painted());
1427 static scoped_ptr
<cc::DelegatedFrameData
> MakeFrameData(gfx::Size size
) {
1428 scoped_ptr
<cc::DelegatedFrameData
> frame_data(new cc::DelegatedFrameData
);
1429 scoped_ptr
<cc::RenderPass
> render_pass(cc::RenderPass::Create());
1430 render_pass
->SetNew(
1431 cc::RenderPassId(1, 1), gfx::Rect(size
), gfx::Rect(), gfx::Transform());
1432 frame_data
->render_pass_list
.push_back(render_pass
.Pass());
1433 return frame_data
.Pass();
1436 TEST_F(LayerWithDelegateTest
, DelegatedLayer
) {
1437 scoped_ptr
<Layer
> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1439 scoped_ptr
<Layer
> child(CreateLayer(LAYER_TEXTURED
));
1441 child
->SetBounds(gfx::Rect(0, 0, 10, 10));
1442 child
->SetVisible(true);
1443 root
->Add(child
.get());
1444 DrawTree(root
.get());
1446 scoped_refptr
<cc::DelegatedFrameResourceCollection
> resource_collection
=
1447 new cc::DelegatedFrameResourceCollection
;
1448 scoped_refptr
<cc::DelegatedFrameProvider
> frame_provider
;
1450 // Content matches layer size.
1451 frame_provider
= new cc::DelegatedFrameProvider(
1452 resource_collection
.get(), MakeFrameData(gfx::Size(10, 10)));
1453 child
->SetShowDelegatedContent(frame_provider
.get(), gfx::Size(10, 10));
1454 EXPECT_EQ(child
->cc_layer()->bounds().ToString(),
1455 gfx::Size(10, 10).ToString());
1457 // Content larger than layer.
1458 child
->SetBounds(gfx::Rect(0, 0, 5, 5));
1459 EXPECT_EQ(child
->cc_layer()->bounds().ToString(),
1460 gfx::Size(5, 5).ToString());
1462 // Content smaller than layer.
1463 child
->SetBounds(gfx::Rect(0, 0, 10, 10));
1464 frame_provider
= new cc::DelegatedFrameProvider(
1465 resource_collection
.get(), MakeFrameData(gfx::Size(5, 5)));
1466 child
->SetShowDelegatedContent(frame_provider
.get(), gfx::Size(5, 5));
1467 EXPECT_EQ(child
->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
1469 // Hi-DPI content on low-DPI layer.
1470 frame_provider
= new cc::DelegatedFrameProvider(
1471 resource_collection
.get(), MakeFrameData(gfx::Size(20, 20)));
1472 child
->SetShowDelegatedContent(frame_provider
.get(), gfx::Size(10, 10));
1473 EXPECT_EQ(child
->cc_layer()->bounds().ToString(),
1474 gfx::Size(10, 10).ToString());
1476 // Hi-DPI content on hi-DPI layer.
1477 compositor()->SetScaleAndSize(2.f
, gfx::Size(1000, 1000));
1478 EXPECT_EQ(child
->cc_layer()->bounds().ToString(),
1479 gfx::Size(10, 10).ToString());
1481 // Low-DPI content on hi-DPI layer.
1482 frame_provider
= new cc::DelegatedFrameProvider(
1483 resource_collection
.get(), MakeFrameData(gfx::Size(10, 10)));
1484 child
->SetShowDelegatedContent(frame_provider
.get(), gfx::Size(10, 10));
1485 EXPECT_EQ(child
->cc_layer()->bounds().ToString(),
1486 gfx::Size(10, 10).ToString());
1489 TEST_F(LayerWithDelegateTest
, ExternalContent
) {
1490 scoped_ptr
<Layer
> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
1491 scoped_ptr
<Layer
> child(CreateLayer(LAYER_SOLID_COLOR
));
1493 child
->SetBounds(gfx::Rect(0, 0, 10, 10));
1494 child
->SetVisible(true);
1495 root
->Add(child
.get());
1497 // The layer is already showing solid color content, so the cc layer won't
1499 scoped_refptr
<cc::Layer
> before
= child
->cc_layer();
1500 child
->SetShowSolidColorContent();
1501 EXPECT_TRUE(child
->cc_layer());
1502 EXPECT_EQ(before
.get(), child
->cc_layer());
1504 scoped_refptr
<cc::DelegatedFrameResourceCollection
> resource_collection
=
1505 new cc::DelegatedFrameResourceCollection
;
1506 scoped_refptr
<cc::DelegatedFrameProvider
> frame_provider
=
1507 new cc::DelegatedFrameProvider(resource_collection
.get(),
1508 MakeFrameData(gfx::Size(10, 10)));
1510 // Showing delegated content changes the underlying cc layer.
1511 before
= child
->cc_layer();
1512 child
->SetShowDelegatedContent(frame_provider
.get(), gfx::Size(10, 10));
1513 EXPECT_TRUE(child
->cc_layer());
1514 EXPECT_NE(before
.get(), child
->cc_layer());
1516 // Changing to painted content should change the underlying cc layer.
1517 before
= child
->cc_layer();
1518 child
->SetShowSolidColorContent();
1519 EXPECT_TRUE(child
->cc_layer());
1520 EXPECT_NE(before
.get(), child
->cc_layer());
1523 // Verifies that layer filters still attached after changing implementation
1525 TEST_F(LayerWithDelegateTest
, LayerFiltersSurvival
) {
1526 scoped_ptr
<Layer
> layer(CreateLayer(LAYER_TEXTURED
));
1527 layer
->SetBounds(gfx::Rect(0, 0, 10, 10));
1528 EXPECT_TRUE(layer
->cc_layer());
1529 EXPECT_EQ(0u, layer
->cc_layer()->filters().size());
1531 layer
->SetLayerGrayscale(0.5f
);
1532 EXPECT_EQ(layer
->layer_grayscale(), 0.5f
);
1533 EXPECT_EQ(1u, layer
->cc_layer()->filters().size());
1535 scoped_refptr
<cc::DelegatedFrameResourceCollection
> resource_collection
=
1536 new cc::DelegatedFrameResourceCollection
;
1537 scoped_refptr
<cc::DelegatedFrameProvider
> frame_provider
=
1538 new cc::DelegatedFrameProvider(resource_collection
.get(),
1539 MakeFrameData(gfx::Size(10, 10)));
1541 // Showing delegated content changes the underlying cc layer.
1542 scoped_refptr
<cc::Layer
> before
= layer
->cc_layer();
1543 layer
->SetShowDelegatedContent(frame_provider
.get(), gfx::Size(10, 10));
1544 EXPECT_EQ(layer
->layer_grayscale(), 0.5f
);
1545 EXPECT_TRUE(layer
->cc_layer());
1546 EXPECT_NE(before
.get(), layer
->cc_layer());
1547 EXPECT_EQ(1u, layer
->cc_layer()->filters().size());
1550 // Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
1551 TEST_F(LayerWithRealCompositorTest
, AddRemoveThreadedAnimations
) {
1552 scoped_ptr
<Layer
> root(CreateLayer(LAYER_TEXTURED
));
1553 scoped_ptr
<Layer
> l1(CreateLayer(LAYER_TEXTURED
));
1554 scoped_ptr
<Layer
> l2(CreateLayer(LAYER_TEXTURED
));
1556 l1
->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1557 l2
->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1559 EXPECT_FALSE(l1
->HasPendingThreadedAnimations());
1561 // Trigger a threaded animation.
1562 l1
->SetOpacity(0.5f
);
1564 EXPECT_TRUE(l1
->HasPendingThreadedAnimations());
1566 // Ensure we can remove a pending threaded animation.
1567 l1
->GetAnimator()->StopAnimating();
1569 EXPECT_FALSE(l1
->HasPendingThreadedAnimations());
1571 // Trigger another threaded animation.
1572 l1
->SetOpacity(0.2f
);
1574 EXPECT_TRUE(l1
->HasPendingThreadedAnimations());
1576 root
->Add(l1
.get());
1577 GetCompositor()->SetRootLayer(root
.get());
1579 // Now that l1 is part of a tree, it should have dispatched the pending
1581 EXPECT_FALSE(l1
->HasPendingThreadedAnimations());
1583 // Ensure that l1 no longer holds on to animations.
1584 l1
->SetOpacity(0.1f
);
1585 EXPECT_FALSE(l1
->HasPendingThreadedAnimations());
1587 // Ensure that adding a layer to an existing tree causes its pending
1588 // animations to get dispatched.
1589 l2
->SetOpacity(0.5f
);
1590 EXPECT_TRUE(l2
->HasPendingThreadedAnimations());
1593 EXPECT_FALSE(l2
->HasPendingThreadedAnimations());
1596 // Tests that in-progress threaded animations complete when a Layer's
1597 // cc::Layer changes.
1598 TEST_F(LayerWithRealCompositorTest
, SwitchCCLayerAnimations
) {
1599 scoped_ptr
<Layer
> root(CreateLayer(LAYER_TEXTURED
));
1600 scoped_ptr
<Layer
> l1(CreateLayer(LAYER_TEXTURED
));
1601 GetCompositor()->SetRootLayer(root
.get());
1602 root
->Add(l1
.get());
1604 l1
->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1606 EXPECT_FLOAT_EQ(l1
->opacity(), 1.0f
);
1608 // Trigger a threaded animation.
1609 l1
->SetOpacity(0.5f
);
1611 // Change l1's cc::Layer.
1612 l1
->SwitchCCLayerForTest();
1614 // Ensure that the opacity animation completed.
1615 EXPECT_FLOAT_EQ(l1
->opacity(), 0.5f
);
1618 // Tests that the animators in the layer tree is added to the
1619 // animator-collection when the root-layer is set to the compositor.
1620 TEST_F(LayerWithDelegateTest
, RootLayerAnimatorsInCompositor
) {
1621 scoped_ptr
<Layer
> root(CreateLayer(LAYER_SOLID_COLOR
));
1622 scoped_ptr
<Layer
> child(CreateColorLayer(SK_ColorRED
, gfx::Rect(10, 10)));
1623 child
->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1624 child
->SetOpacity(0.5f
);
1625 root
->Add(child
.get());
1627 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1628 compositor()->SetRootLayer(root
.get());
1629 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1632 // Tests that adding/removing a layer adds/removes the animator from its entire
1633 // subtree from the compositor's animator-collection.
1634 TEST_F(LayerWithDelegateTest
, AddRemoveLayerUpdatesAnimatorsFromSubtree
) {
1635 scoped_ptr
<Layer
> root(CreateLayer(LAYER_TEXTURED
));
1636 scoped_ptr
<Layer
> child(CreateLayer(LAYER_TEXTURED
));
1637 scoped_ptr
<Layer
> grandchild(CreateColorLayer(SK_ColorRED
,
1638 gfx::Rect(10, 10)));
1639 root
->Add(child
.get());
1640 child
->Add(grandchild
.get());
1641 compositor()->SetRootLayer(root
.get());
1643 grandchild
->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1644 grandchild
->SetOpacity(0.5f
);
1645 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1647 root
->Remove(child
.get());
1648 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1650 root
->Add(child
.get());
1651 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1654 TEST_F(LayerWithDelegateTest
, DestroyingLayerRemovesTheAnimatorFromCollection
) {
1655 scoped_ptr
<Layer
> root(CreateLayer(LAYER_TEXTURED
));
1656 scoped_ptr
<Layer
> child(CreateLayer(LAYER_TEXTURED
));
1657 root
->Add(child
.get());
1658 compositor()->SetRootLayer(root
.get());
1660 child
->SetAnimator(LayerAnimator::CreateImplicitAnimator());
1661 child
->SetOpacity(0.5f
);
1662 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
1665 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
1670 std::string
Vector2dFTo100thPercisionString(const gfx::Vector2dF
& vector
) {
1671 return base::StringPrintf("%.2f %0.2f", vector
.x(), vector
.y());
1676 TEST_F(LayerWithRealCompositorTest
, SnapLayerToPixels
) {
1677 scoped_ptr
<Layer
> root(CreateLayer(LAYER_TEXTURED
));
1678 scoped_ptr
<Layer
> c1(CreateLayer(LAYER_TEXTURED
));
1679 scoped_ptr
<Layer
> c11(CreateLayer(LAYER_TEXTURED
));
1681 GetCompositor()->SetScaleAndSize(1.25f
, gfx::Size(100, 100));
1682 GetCompositor()->SetRootLayer(root
.get());
1683 root
->Add(c1
.get());
1686 root
->SetBounds(gfx::Rect(0, 0, 100, 100));
1687 c1
->SetBounds(gfx::Rect(1, 1, 10, 10));
1688 c11
->SetBounds(gfx::Rect(1, 1, 10, 10));
1689 SnapLayerToPhysicalPixelBoundary(root
.get(), c11
.get());
1690 // 0.5 at 1.25 scale : (1 - 0.25 + 0.25) / 1.25 = 0.4
1691 EXPECT_EQ("0.40 0.40",
1692 Vector2dFTo100thPercisionString(c11
->subpixel_position_offset()));
1694 GetCompositor()->SetScaleAndSize(1.5f
, gfx::Size(100, 100));
1695 SnapLayerToPhysicalPixelBoundary(root
.get(), c11
.get());
1696 // c11 must already be aligned at 1.5 scale.
1697 EXPECT_EQ("0.00 0.00",
1698 Vector2dFTo100thPercisionString(c11
->subpixel_position_offset()));
1700 c11
->SetBounds(gfx::Rect(2, 2, 10, 10));
1701 SnapLayerToPhysicalPixelBoundary(root
.get(), c11
.get());
1702 // c11 is now off the pixel.
1703 // 0.5 / 1.5 = 0.333...
1704 EXPECT_EQ("0.33 0.33",
1705 Vector2dFTo100thPercisionString(c11
->subpixel_position_offset()));
1708 class FrameDamageCheckingDelegate
: public TestLayerDelegate
{
1710 FrameDamageCheckingDelegate() : delegated_frame_damage_called_(false) {}
1712 void OnDelegatedFrameDamage(const gfx::Rect
& damage_rect_in_dip
) override
{
1713 delegated_frame_damage_called_
= true;
1714 delegated_frame_damage_rect_
= damage_rect_in_dip
;
1717 const gfx::Rect
& delegated_frame_damage_rect() const {
1718 return delegated_frame_damage_rect_
;
1720 bool delegated_frame_damage_called() const {
1721 return delegated_frame_damage_called_
;
1725 gfx::Rect delegated_frame_damage_rect_
;
1726 bool delegated_frame_damage_called_
;
1728 DISALLOW_COPY_AND_ASSIGN(FrameDamageCheckingDelegate
);
1731 TEST(LayerDelegateTest
, DelegatedFrameDamage
) {
1732 scoped_ptr
<Layer
> layer(new Layer(LAYER_TEXTURED
));
1733 gfx::Rect
damage_rect(2, 1, 5, 3);
1735 FrameDamageCheckingDelegate delegate
;
1736 layer
->set_delegate(&delegate
);
1737 scoped_refptr
<cc::DelegatedFrameResourceCollection
> resource_collection
=
1738 new cc::DelegatedFrameResourceCollection
;
1739 scoped_refptr
<cc::DelegatedFrameProvider
> frame_provider(
1740 new cc::DelegatedFrameProvider(resource_collection
.get(),
1741 MakeFrameData(gfx::Size(10, 10))));
1742 layer
->SetShowDelegatedContent(frame_provider
.get(), gfx::Size(10, 10));
1744 EXPECT_FALSE(delegate
.delegated_frame_damage_called());
1745 layer
->OnDelegatedFrameDamage(damage_rect
);
1746 EXPECT_TRUE(delegate
.delegated_frame_damage_called());
1747 EXPECT_EQ(damage_rect
, delegate
.delegated_frame_damage_rect());