1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/compositor_frame.h"
6 #include "cc/output/delegated_frame_data.h"
7 #include "cc/quads/render_pass.h"
8 #include "cc/quads/render_pass_id.h"
9 #include "cc/quads/solid_color_draw_quad.h"
10 #include "cc/quads/surface_draw_quad.h"
11 #include "cc/surfaces/surface.h"
12 #include "cc/surfaces/surface_factory.h"
13 #include "cc/surfaces/surface_factory_client.h"
14 #include "cc/surfaces/surface_hittest.h"
15 #include "cc/surfaces/surface_id_allocator.h"
16 #include "cc/surfaces/surface_manager.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/skia/include/core/SkColor.h"
19 #include "ui/gfx/geometry/size.h"
23 class EmptySurfaceFactoryClient
: public SurfaceFactoryClient
{
25 void ReturnResources(const ReturnedResourceArray
& resources
) override
{}
28 TEST(SurfaceHittestTest
, Hittest_SingleSurface
) {
29 SurfaceManager manager
;
30 EmptySurfaceFactoryClient client
;
31 SurfaceFactory
factory(&manager
, &client
);
32 SurfaceIdAllocator
root_allocator(2);
34 // Creates a root surface.
35 SurfaceId root_surface_id
= root_allocator
.GenerateId();
36 factory
.Create(root_surface_id
);
37 gfx::Rect
rect(300, 300);
38 RenderPassId
id(1, 1);
39 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
40 pass
->SetNew(id
, rect
, rect
, gfx::Transform());
41 scoped_ptr
<DelegatedFrameData
> delegated_frame_data(new DelegatedFrameData
);
42 delegated_frame_data
->render_pass_list
.push_back(pass
.Pass());
43 scoped_ptr
<CompositorFrame
> root_frame(new CompositorFrame
);
44 root_frame
->delegated_frame_data
= delegated_frame_data
.Pass();
45 factory
.SubmitCompositorFrame(root_surface_id
, root_frame
.Pass(),
46 SurfaceFactory::DrawCallback());
49 SurfaceHittest
hittest(&manager
);
50 gfx::Point transformed_point
;
51 EXPECT_EQ(root_surface_id
,
52 hittest
.Hittest(root_surface_id
, gfx::Point(100, 100),
54 EXPECT_EQ(gfx::Point(100, 100), transformed_point
);
57 factory
.Destroy(root_surface_id
);
60 TEST(SurfaceHittestTest
, Hittest_ChildSurface
) {
61 SurfaceManager manager
;
62 EmptySurfaceFactoryClient client
;
63 SurfaceFactory
factory(&manager
, &client
);
64 SurfaceIdAllocator
root_allocator(2);
65 SurfaceIdAllocator
child_allocator(3);
67 SurfaceId root_surface_id
= root_allocator
.GenerateId();
68 SurfaceId child_surface_id
= child_allocator
.GenerateId();
69 gfx::Size
root_size(300, 300);
70 gfx::Rect
root_rect(root_size
);
71 gfx::Size
child_size(200, 200);
72 gfx::Rect
child_rect(child_size
);
73 gfx::Rect
child_solid_quad_size(100, 100);
74 gfx::Rect
child_solid_quad_rect(child_solid_quad_size
);
76 // Creates a root surface.
77 factory
.Create(root_surface_id
);
78 RenderPassId
root_id(1, 1);
79 scoped_ptr
<RenderPass
> root_pass
= RenderPass::Create();
80 root_pass
->SetNew(root_id
, root_rect
, root_rect
, gfx::Transform());
82 // Add a reference to the child surface on the root surface.
83 SharedQuadState
* root_shared_state
=
84 root_pass
->CreateAndAppendSharedQuadState();
85 root_shared_state
->SetAll(gfx::Transform(1.0f
, 0.0f
, 0.0f
, 50.0f
,
86 0.0f
, 1.0f
, 0.0f
, 50.0f
,
87 0.0f
, 0.0f
, 1.0f
, 0.0f
,
88 0.0f
, 0.0f
, 0.0f
, 1.0f
),
89 root_size
, root_rect
, root_rect
, false, 1.0f
,
90 SkXfermode::kSrcOver_Mode
, 0);
91 SurfaceDrawQuad
* surface_quad
=
92 root_pass
->CreateAndAppendDrawQuad
<SurfaceDrawQuad
>();
93 surface_quad
->SetNew(root_pass
->shared_quad_state_list
.back(), child_rect
,
94 child_rect
, child_surface_id
);
96 // Submit the root frame.
97 scoped_ptr
<DelegatedFrameData
> root_delegated_frame_data(
98 new DelegatedFrameData
);
99 root_delegated_frame_data
->render_pass_list
.push_back(root_pass
.Pass());
100 scoped_ptr
<CompositorFrame
> root_frame(new CompositorFrame
);
101 root_frame
->delegated_frame_data
= root_delegated_frame_data
.Pass();
102 factory
.SubmitCompositorFrame(root_surface_id
, root_frame
.Pass(),
103 SurfaceFactory::DrawCallback());
105 // Creates a child surface.
106 factory
.Create(child_surface_id
);
107 RenderPassId
child_id(1, 1);
108 scoped_ptr
<RenderPass
> child_pass
= RenderPass::Create();
109 child_pass
->SetNew(child_id
, child_rect
, child_rect
, gfx::Transform());
111 // Add a solid quad in the child surface.
112 SharedQuadState
* child_shared_state
=
113 child_pass
->CreateAndAppendSharedQuadState();
114 child_shared_state
->SetAll(gfx::Transform(1.0f
, 0.0f
, 0.0f
, 50.0f
,
115 0.0f
, 1.0f
, 0.0f
, 50.0f
,
116 0.0f
, 0.0f
, 1.0f
, 0.0f
,
117 0.0f
, 0.0f
, 0.0f
, 1.0f
),
118 root_size
, root_rect
, root_rect
, false, 1.0f
,
119 SkXfermode::kSrcOver_Mode
, 0);
120 SolidColorDrawQuad
* color_quad
=
121 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
122 color_quad
->SetNew(child_pass
->shared_quad_state_list
.back(),
123 child_solid_quad_rect
, child_solid_quad_rect
,
124 SK_ColorYELLOW
, false);
127 scoped_ptr
<DelegatedFrameData
> child_delegated_frame_data(
128 new DelegatedFrameData
);
129 child_delegated_frame_data
->render_pass_list
.push_back(child_pass
.Pass());
130 scoped_ptr
<CompositorFrame
> child_frame(new CompositorFrame
);
131 child_frame
->delegated_frame_data
= child_delegated_frame_data
.Pass();
132 factory
.SubmitCompositorFrame(child_surface_id
, child_frame
.Pass(),
133 SurfaceFactory::DrawCallback());
136 SurfaceHittest
hittest(&manager
);
137 gfx::Point transformed_point
;
138 EXPECT_EQ(root_surface_id
,
139 hittest
.Hittest(root_surface_id
, gfx::Point(10, 10),
140 &transformed_point
));
141 EXPECT_EQ(gfx::Point(10, 10), transformed_point
);
142 EXPECT_EQ(root_surface_id
,
143 hittest
.Hittest(root_surface_id
, gfx::Point(99, 99),
144 &transformed_point
));
145 EXPECT_EQ(gfx::Point(99, 99), transformed_point
);
146 EXPECT_EQ(child_surface_id
,
147 hittest
.Hittest(root_surface_id
, gfx::Point(100, 100),
148 &transformed_point
));
149 EXPECT_EQ(gfx::Point(50, 50), transformed_point
);
150 EXPECT_EQ(child_surface_id
,
151 hittest
.Hittest(root_surface_id
, gfx::Point(199, 199),
152 &transformed_point
));
153 EXPECT_EQ(gfx::Point(149, 149), transformed_point
);
154 EXPECT_EQ(root_surface_id
,
155 hittest
.Hittest(root_surface_id
, gfx::Point(200, 200),
156 &transformed_point
));
157 EXPECT_EQ(gfx::Point(200, 200), transformed_point
);
158 EXPECT_EQ(root_surface_id
,
159 hittest
.Hittest(root_surface_id
, gfx::Point(290, 290),
160 &transformed_point
));
161 EXPECT_EQ(gfx::Point(290, 290), transformed_point
);
164 factory
.Destroy(root_surface_id
);
165 factory
.Destroy(child_surface_id
);