surfaces_pixeltest.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright 2014 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.
4
5#include "cc/output/compositor_frame.h"
6#include "cc/quads/render_pass.h"
7#include "cc/quads/solid_color_draw_quad.h"
8#include "cc/quads/surface_draw_quad.h"
9#include "cc/surfaces/surface.h"
10#include "cc/surfaces/surface_aggregator.h"
11#include "cc/surfaces/surface_factory.h"
12#include "cc/surfaces/surface_factory_client.h"
13#include "cc/surfaces/surface_id_allocator.h"
14#include "cc/surfaces/surface_manager.h"
15#include "cc/test/pixel_comparator.h"
16#include "cc/test/pixel_test.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19#if !defined(OS_ANDROID)
20
21namespace cc {
22namespace {
23
24class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
25 public:
26  virtual void ReturnResources(
27      const ReturnedResourceArray& resources) OVERRIDE {}
28};
29
30class SurfacesPixelTest : public RendererPixelTest<GLRenderer> {
31 public:
32  SurfacesPixelTest() : allocator_(1u), factory_(&manager_, &client_) {}
33
34 protected:
35  SurfaceManager manager_;
36  SurfaceIdAllocator allocator_;
37  EmptySurfaceFactoryClient client_;
38  SurfaceFactory factory_;
39};
40
41SharedQuadState* CreateAndAppendTestSharedQuadState(
42    RenderPass* render_pass,
43    const gfx::Transform& transform,
44    const gfx::Size& size) {
45  const gfx::Size content_bounds = size;
46  const gfx::Rect visible_content_rect = gfx::Rect(size);
47  const gfx::Rect clip_rect = gfx::Rect(size);
48  bool is_clipped = false;
49  float opacity = 1.f;
50  const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
51  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
52  shared_state->SetAll(transform,
53                       content_bounds,
54                       visible_content_rect,
55                       clip_rect,
56                       is_clipped,
57                       opacity,
58                       blend_mode,
59                       0);
60  return shared_state;
61}
62
63// Draws a very simple frame with no surface references.
64TEST_F(SurfacesPixelTest, DrawSimpleFrame) {
65  gfx::Rect rect(device_viewport_size_);
66  RenderPassId id(1, 1);
67  scoped_ptr<RenderPass> pass = RenderPass::Create();
68  pass->SetNew(id, rect, rect, gfx::Transform());
69
70  CreateAndAppendTestSharedQuadState(
71      pass.get(), gfx::Transform(), device_viewport_size_);
72
73  SolidColorDrawQuad* color_quad =
74      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
75  bool force_anti_aliasing_off = false;
76  color_quad->SetNew(pass->shared_quad_state_list.back(),
77                     rect,
78                     rect,
79                     SK_ColorGREEN,
80                     force_anti_aliasing_off);
81
82  scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
83  delegated_frame_data->render_pass_list.push_back(pass.Pass());
84
85  scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
86  root_frame->delegated_frame_data = delegated_frame_data.Pass();
87
88  SurfaceId root_surface_id = allocator_.GenerateId();
89  factory_.Create(root_surface_id, device_viewport_size_);
90  factory_.SubmitFrame(root_surface_id, root_frame.Pass());
91
92  SurfaceAggregator aggregator(&manager_, resource_provider_.get());
93  std::set<SurfaceId> surface_set;
94  scoped_ptr<CompositorFrame> aggregated_frame =
95      aggregator.Aggregate(root_surface_id, &surface_set);
96  factory_.Destroy(root_surface_id);
97
98  bool discard_alpha = false;
99  ExactPixelComparator pixel_comparator(discard_alpha);
100  RenderPassList* pass_list =
101      &aggregated_frame->delegated_frame_data->render_pass_list;
102  EXPECT_TRUE(RunPixelTest(pass_list,
103                           base::FilePath(FILE_PATH_LITERAL("green.png")),
104                           pixel_comparator));
105}
106
107// Draws a frame with simple surface embedding.
108TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) {
109  gfx::Size child_size(200, 100);
110  SurfaceId child_surface_id = allocator_.GenerateId();
111  SurfaceId root_surface_id = allocator_.GenerateId();
112  factory_.Create(child_surface_id, child_size);
113  factory_.Create(root_surface_id, device_viewport_size_);
114  {
115    gfx::Rect rect(device_viewport_size_);
116    RenderPassId id(1, 1);
117    scoped_ptr<RenderPass> pass = RenderPass::Create();
118    pass->SetNew(id, rect, rect, gfx::Transform());
119
120    CreateAndAppendTestSharedQuadState(
121        pass.get(), gfx::Transform(), device_viewport_size_);
122
123    SurfaceDrawQuad* surface_quad =
124        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
125    surface_quad->SetNew(pass->shared_quad_state_list.back(),
126                         gfx::Rect(child_size),
127                         gfx::Rect(child_size),
128                         child_surface_id);
129
130    SolidColorDrawQuad* color_quad =
131        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
132    bool force_anti_aliasing_off = false;
133    color_quad->SetNew(pass->shared_quad_state_list.back(),
134                       rect,
135                       rect,
136                       SK_ColorYELLOW,
137                       force_anti_aliasing_off);
138
139    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
140    delegated_frame_data->render_pass_list.push_back(pass.Pass());
141
142    scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
143    root_frame->delegated_frame_data = delegated_frame_data.Pass();
144
145    factory_.SubmitFrame(root_surface_id, root_frame.Pass());
146  }
147
148  {
149    gfx::Rect rect(child_size);
150    RenderPassId id(1, 1);
151    scoped_ptr<RenderPass> pass = RenderPass::Create();
152    pass->SetNew(id, rect, rect, gfx::Transform());
153
154    CreateAndAppendTestSharedQuadState(
155        pass.get(), gfx::Transform(), child_size);
156
157    SolidColorDrawQuad* color_quad =
158        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
159    bool force_anti_aliasing_off = false;
160    color_quad->SetNew(pass->shared_quad_state_list.back(),
161                       rect,
162                       rect,
163                       SK_ColorBLUE,
164                       force_anti_aliasing_off);
165
166    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
167    delegated_frame_data->render_pass_list.push_back(pass.Pass());
168
169    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
170    child_frame->delegated_frame_data = delegated_frame_data.Pass();
171
172    factory_.SubmitFrame(child_surface_id, child_frame.Pass());
173  }
174
175  SurfaceAggregator aggregator(&manager_, resource_provider_.get());
176  std::set<SurfaceId> surface_set;
177  scoped_ptr<CompositorFrame> aggregated_frame =
178      aggregator.Aggregate(root_surface_id, &surface_set);
179
180  bool discard_alpha = false;
181  ExactPixelComparator pixel_comparator(discard_alpha);
182  RenderPassList* pass_list =
183      &aggregated_frame->delegated_frame_data->render_pass_list;
184  EXPECT_TRUE(RunPixelTest(pass_list,
185                           base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
186                           pixel_comparator));
187  factory_.Destroy(root_surface_id);
188  factory_.Destroy(child_surface_id);
189}
190
191// Tests a surface quad that has a non-identity transform into its pass.
192TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
193  gfx::Size child_size(100, 200);
194  gfx::Size quad_size(100, 100);
195  // Structure:
196  // root (200x200) -> left_child (100x200 @ 0x0,
197  //                   right_child (100x200 @ 0x100)
198  //   left_child -> top_green_quad (100x100 @ 0x0),
199  //                 bottom_blue_quad (100x100 @ 0x100)
200  //   right_child -> top_blue_quad (100x100 @ 0x0),
201  //                  bottom_green_quad (100x100 @ 0x100)
202  SurfaceId left_child_id = allocator_.GenerateId();
203  SurfaceId right_child_id = allocator_.GenerateId();
204  SurfaceId root_surface_id = allocator_.GenerateId();
205  factory_.Create(left_child_id, child_size);
206  factory_.Create(right_child_id, child_size);
207  factory_.Create(root_surface_id, device_viewport_size_);
208
209  {
210    gfx::Rect rect(device_viewport_size_);
211    RenderPassId id(1, 1);
212    scoped_ptr<RenderPass> pass = RenderPass::Create();
213    pass->SetNew(id, rect, rect, gfx::Transform());
214
215    gfx::Transform surface_transform;
216    CreateAndAppendTestSharedQuadState(
217        pass.get(), surface_transform, device_viewport_size_);
218
219    SurfaceDrawQuad* left_surface_quad =
220        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
221    left_surface_quad->SetNew(pass->shared_quad_state_list.back(),
222                              gfx::Rect(child_size),
223                              gfx::Rect(child_size),
224                              left_child_id);
225
226    surface_transform.Translate(100, 0);
227    CreateAndAppendTestSharedQuadState(
228        pass.get(), surface_transform, device_viewport_size_);
229
230    SurfaceDrawQuad* right_surface_quad =
231        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
232    right_surface_quad->SetNew(pass->shared_quad_state_list.back(),
233                               gfx::Rect(child_size),
234                               gfx::Rect(child_size),
235                               right_child_id);
236
237    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
238    delegated_frame_data->render_pass_list.push_back(pass.Pass());
239
240    scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
241    root_frame->delegated_frame_data = delegated_frame_data.Pass();
242
243    factory_.SubmitFrame(root_surface_id, root_frame.Pass());
244  }
245
246  {
247    gfx::Rect rect(child_size);
248    RenderPassId id(1, 1);
249    scoped_ptr<RenderPass> pass = RenderPass::Create();
250    pass->SetNew(id, rect, rect, gfx::Transform());
251
252    CreateAndAppendTestSharedQuadState(
253        pass.get(), gfx::Transform(), child_size);
254
255    SolidColorDrawQuad* top_color_quad =
256        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
257    bool force_anti_aliasing_off = false;
258    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
259                           gfx::Rect(quad_size),
260                           gfx::Rect(quad_size),
261                           SK_ColorGREEN,
262                           force_anti_aliasing_off);
263
264    SolidColorDrawQuad* bottom_color_quad =
265        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
266    bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
267                              gfx::Rect(0, 100, 100, 100),
268                              gfx::Rect(0, 100, 100, 100),
269                              SK_ColorBLUE,
270                              force_anti_aliasing_off);
271
272    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
273    delegated_frame_data->render_pass_list.push_back(pass.Pass());
274
275    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
276    child_frame->delegated_frame_data = delegated_frame_data.Pass();
277
278    factory_.SubmitFrame(left_child_id, child_frame.Pass());
279  }
280
281  {
282    gfx::Rect rect(child_size);
283    RenderPassId id(1, 1);
284    scoped_ptr<RenderPass> pass = RenderPass::Create();
285    pass->SetNew(id, rect, rect, gfx::Transform());
286
287    CreateAndAppendTestSharedQuadState(
288        pass.get(), gfx::Transform(), child_size);
289
290    SolidColorDrawQuad* top_color_quad =
291        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
292    bool force_anti_aliasing_off = false;
293    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
294                           gfx::Rect(quad_size),
295                           gfx::Rect(quad_size),
296                           SK_ColorBLUE,
297                           force_anti_aliasing_off);
298
299    SolidColorDrawQuad* bottom_color_quad =
300        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
301    bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
302                              gfx::Rect(0, 100, 100, 100),
303                              gfx::Rect(0, 100, 100, 100),
304                              SK_ColorGREEN,
305                              force_anti_aliasing_off);
306
307    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
308    delegated_frame_data->render_pass_list.push_back(pass.Pass());
309
310    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
311    child_frame->delegated_frame_data = delegated_frame_data.Pass();
312
313    factory_.SubmitFrame(right_child_id, child_frame.Pass());
314  }
315
316  SurfaceAggregator aggregator(&manager_, resource_provider_.get());
317  std::set<SurfaceId> surface_set;
318  scoped_ptr<CompositorFrame> aggregated_frame =
319      aggregator.Aggregate(root_surface_id, &surface_set);
320
321  bool discard_alpha = false;
322  ExactPixelComparator pixel_comparator(discard_alpha);
323  RenderPassList* pass_list =
324      &aggregated_frame->delegated_frame_data->render_pass_list;
325  EXPECT_TRUE(RunPixelTest(
326      pass_list,
327      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
328      pixel_comparator));
329
330  factory_.Destroy(root_surface_id);
331  factory_.Destroy(left_child_id);
332  factory_.Destroy(right_child_id);
333}
334
335}  // namespace
336}  // namespace cc
337
338#endif  // !defined(OS_ANDROID)
339