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.
4
5#include "content/common/cc_messages.h"
6
7#include <string.h>
8
9#include <algorithm>
10
11#include "cc/output/compositor_frame.h"
12#include "content/public/common/common_param_traits.h"
13#include "ipc/ipc_message.h"
14#include "testing/gtest/include/gtest/gtest.h"
15#include "third_party/khronos/GLES2/gl2ext.h"
16#include "third_party/skia/include/effects/SkBlurImageFilter.h"
17
18#if defined(OS_POSIX)
19#include "base/file_descriptor_posix.h"
20#endif
21
22using cc::CheckerboardDrawQuad;
23using cc::DelegatedFrameData;
24using cc::DebugBorderDrawQuad;
25using cc::DrawQuad;
26using cc::FilterOperation;
27using cc::FilterOperations;
28using cc::IOSurfaceDrawQuad;
29using cc::PictureDrawQuad;
30using cc::RenderPass;
31using cc::RenderPassDrawQuad;
32using cc::ResourceProvider;
33using cc::SharedQuadState;
34using cc::SoftwareFrameData;
35using cc::SolidColorDrawQuad;
36using cc::SurfaceDrawQuad;
37using cc::TextureDrawQuad;
38using cc::TileDrawQuad;
39using cc::TransferableResource;
40using cc::StreamVideoDrawQuad;
41using cc::VideoLayerImpl;
42using cc::YUVVideoDrawQuad;
43using gfx::Transform;
44
45namespace content {
46namespace {
47
48class CCMessagesTest : public testing::Test {
49 protected:
50  void Compare(const RenderPass* a, const RenderPass* b) {
51    EXPECT_EQ(a->id, b->id);
52    EXPECT_EQ(a->output_rect.ToString(), b->output_rect.ToString());
53    EXPECT_EQ(a->damage_rect.ToString(), b->damage_rect.ToString());
54    EXPECT_EQ(a->transform_to_root_target, b->transform_to_root_target);
55    EXPECT_EQ(a->has_transparent_background, b->has_transparent_background);
56  }
57
58  void Compare(const SharedQuadState* a, const SharedQuadState* b) {
59    EXPECT_EQ(a->content_to_target_transform, b->content_to_target_transform);
60    EXPECT_EQ(a->content_bounds, b->content_bounds);
61    EXPECT_EQ(a->visible_content_rect, b->visible_content_rect);
62    EXPECT_EQ(a->clip_rect, b->clip_rect);
63    EXPECT_EQ(a->is_clipped, b->is_clipped);
64    EXPECT_EQ(a->opacity, b->opacity);
65    EXPECT_EQ(a->blend_mode, b->blend_mode);
66    EXPECT_EQ(a->sorting_context_id, b->sorting_context_id);
67  }
68
69  void Compare(const DrawQuad* a, const DrawQuad* b) {
70    ASSERT_NE(DrawQuad::INVALID, a->material);
71    ASSERT_EQ(a->material, b->material);
72    EXPECT_EQ(a->rect.ToString(), b->rect.ToString());
73    EXPECT_EQ(a->opaque_rect.ToString(), b->opaque_rect.ToString());
74    EXPECT_EQ(a->visible_rect.ToString(), b->visible_rect.ToString());
75    EXPECT_EQ(a->needs_blending, b->needs_blending);
76
77    Compare(a->shared_quad_state, b->shared_quad_state);
78
79    switch (a->material) {
80      case DrawQuad::CHECKERBOARD:
81        Compare(CheckerboardDrawQuad::MaterialCast(a),
82                CheckerboardDrawQuad::MaterialCast(b));
83        break;
84      case DrawQuad::DEBUG_BORDER:
85        Compare(DebugBorderDrawQuad::MaterialCast(a),
86                DebugBorderDrawQuad::MaterialCast(b));
87        break;
88      case DrawQuad::IO_SURFACE_CONTENT:
89        Compare(IOSurfaceDrawQuad::MaterialCast(a),
90                IOSurfaceDrawQuad::MaterialCast(b));
91        break;
92      case DrawQuad::PICTURE_CONTENT:
93        Compare(PictureDrawQuad::MaterialCast(a),
94                PictureDrawQuad::MaterialCast(b));
95        break;
96      case DrawQuad::RENDER_PASS:
97        Compare(RenderPassDrawQuad::MaterialCast(a),
98                RenderPassDrawQuad::MaterialCast(b));
99        break;
100      case DrawQuad::TEXTURE_CONTENT:
101        Compare(TextureDrawQuad::MaterialCast(a),
102                TextureDrawQuad::MaterialCast(b));
103        break;
104      case DrawQuad::TILED_CONTENT:
105        Compare(TileDrawQuad::MaterialCast(a),
106                TileDrawQuad::MaterialCast(b));
107        break;
108      case DrawQuad::SOLID_COLOR:
109        Compare(SolidColorDrawQuad::MaterialCast(a),
110                SolidColorDrawQuad::MaterialCast(b));
111        break;
112      case DrawQuad::STREAM_VIDEO_CONTENT:
113        Compare(StreamVideoDrawQuad::MaterialCast(a),
114                StreamVideoDrawQuad::MaterialCast(b));
115        break;
116      case DrawQuad::SURFACE_CONTENT:
117        Compare(SurfaceDrawQuad::MaterialCast(a),
118                SurfaceDrawQuad::MaterialCast(b));
119        break;
120      case DrawQuad::YUV_VIDEO_CONTENT:
121        Compare(YUVVideoDrawQuad::MaterialCast(a),
122                YUVVideoDrawQuad::MaterialCast(b));
123        break;
124      case DrawQuad::INVALID:
125        break;
126    }
127  }
128
129  void Compare(const CheckerboardDrawQuad* a, const CheckerboardDrawQuad* b) {
130    EXPECT_EQ(a->color, b->color);
131  }
132
133  void Compare(const DebugBorderDrawQuad* a, const DebugBorderDrawQuad* b) {
134    EXPECT_EQ(a->color, b->color);
135    EXPECT_EQ(a->width, b->width);
136  }
137
138  void Compare(const IOSurfaceDrawQuad* a, const IOSurfaceDrawQuad* b) {
139    EXPECT_EQ(a->io_surface_size.ToString(), b->io_surface_size.ToString());
140    EXPECT_EQ(a->io_surface_resource_id, b->io_surface_resource_id);
141    EXPECT_EQ(a->orientation, b->orientation);
142  }
143
144  void Compare(const RenderPassDrawQuad* a, const RenderPassDrawQuad* b) {
145    EXPECT_EQ(a->render_pass_id, b->render_pass_id);
146    EXPECT_EQ(a->is_replica, b->is_replica);
147    EXPECT_EQ(a->mask_resource_id, b->mask_resource_id);
148    EXPECT_EQ(a->contents_changed_since_last_frame,
149              b->contents_changed_since_last_frame);
150    EXPECT_EQ(a->mask_uv_rect.ToString(), b->mask_uv_rect.ToString());
151    EXPECT_EQ(a->filters.size(), b->filters.size());
152    for (size_t i = 0; i < a->filters.size(); ++i) {
153      if (a->filters.at(i).type() != cc::FilterOperation::REFERENCE) {
154        EXPECT_EQ(a->filters.at(i), b->filters.at(i));
155      } else {
156        EXPECT_EQ(b->filters.at(i).type(), cc::FilterOperation::REFERENCE);
157        EXPECT_EQ(a->filters.at(i).image_filter()->countInputs(),
158                  b->filters.at(i).image_filter()->countInputs());
159      }
160    }
161    EXPECT_EQ(a->background_filters, b->background_filters);
162  }
163
164  void Compare(const SolidColorDrawQuad* a, const SolidColorDrawQuad* b) {
165    EXPECT_EQ(a->color, b->color);
166    EXPECT_EQ(a->force_anti_aliasing_off, b->force_anti_aliasing_off);
167  }
168
169  void Compare(const StreamVideoDrawQuad* a, const StreamVideoDrawQuad* b) {
170    EXPECT_EQ(a->resource_id, b->resource_id);
171    EXPECT_EQ(a->matrix, b->matrix);
172  }
173
174  void Compare(const SurfaceDrawQuad* a, const SurfaceDrawQuad* b) {
175    EXPECT_EQ(a->surface_id, b->surface_id);
176  }
177
178  void Compare(const TextureDrawQuad* a, const TextureDrawQuad* b) {
179    EXPECT_EQ(a->resource_id, b->resource_id);
180    EXPECT_EQ(a->premultiplied_alpha, b->premultiplied_alpha);
181    EXPECT_EQ(a->uv_top_left, b->uv_top_left);
182    EXPECT_EQ(a->uv_bottom_right, b->uv_bottom_right);
183    EXPECT_EQ(a->background_color, b->background_color);
184    EXPECT_EQ(a->vertex_opacity[0], b->vertex_opacity[0]);
185    EXPECT_EQ(a->vertex_opacity[1], b->vertex_opacity[1]);
186    EXPECT_EQ(a->vertex_opacity[2], b->vertex_opacity[2]);
187    EXPECT_EQ(a->vertex_opacity[3], b->vertex_opacity[3]);
188    EXPECT_EQ(a->flipped, b->flipped);
189  }
190
191  void Compare(const TileDrawQuad* a, const TileDrawQuad* b) {
192    EXPECT_EQ(a->resource_id, b->resource_id);
193    EXPECT_EQ(a->tex_coord_rect, b->tex_coord_rect);
194    EXPECT_EQ(a->texture_size, b->texture_size);
195    EXPECT_EQ(a->swizzle_contents, b->swizzle_contents);
196  }
197
198  void Compare(const YUVVideoDrawQuad* a, const YUVVideoDrawQuad* b) {
199    EXPECT_EQ(a->tex_coord_rect, b->tex_coord_rect);
200    EXPECT_EQ(a->y_plane_resource_id, b->y_plane_resource_id);
201    EXPECT_EQ(a->u_plane_resource_id, b->u_plane_resource_id);
202    EXPECT_EQ(a->v_plane_resource_id, b->v_plane_resource_id);
203    EXPECT_EQ(a->a_plane_resource_id, b->a_plane_resource_id);
204    EXPECT_EQ(a->color_space, b->color_space);
205  }
206
207  void Compare(const TransferableResource& a, const TransferableResource& b) {
208    EXPECT_EQ(a.id, b.id);
209    EXPECT_EQ(a.format, b.format);
210    EXPECT_EQ(a.filter, b.filter);
211    EXPECT_EQ(a.size.ToString(), b.size.ToString());
212    for (size_t i = 0; i < arraysize(a.mailbox_holder.mailbox.name); ++i) {
213      EXPECT_EQ(a.mailbox_holder.mailbox.name[i],
214                b.mailbox_holder.mailbox.name[i]);
215    }
216    EXPECT_EQ(a.mailbox_holder.texture_target, b.mailbox_holder.texture_target);
217    EXPECT_EQ(a.mailbox_holder.sync_point, b.mailbox_holder.sync_point);
218  }
219};
220
221TEST_F(CCMessagesTest, AllQuads) {
222  IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
223
224  Transform arbitrary_matrix;
225  arbitrary_matrix.Scale(3, 3);
226  arbitrary_matrix.Translate(-5, 20);
227  arbitrary_matrix.Rotate(15);
228  gfx::Rect arbitrary_rect1(-5, 9, 3, 15);
229  gfx::Rect arbitrary_rect1_inside_rect1(-4, 12, 2, 8);
230  gfx::Rect arbitrary_rect2_inside_rect1(-5, 11, 1, 2);
231  gfx::Rect arbitrary_rect2(40, 23, 11, 7);
232  gfx::Rect arbitrary_rect1_inside_rect2(44, 23, 4, 2);
233  gfx::Rect arbitrary_rect2_inside_rect2(41, 25, 3, 5);
234  gfx::Rect arbitrary_rect3(7, -53, 22, 19);
235  gfx::Rect arbitrary_rect1_inside_rect3(10, -40, 6, 3);
236  gfx::Rect arbitrary_rect2_inside_rect3(12, -51, 5, 12);
237  gfx::Size arbitrary_size1(15, 19);
238  gfx::Size arbitrary_size2(3, 99);
239  gfx::Size arbitrary_size3(75, 1281);
240  gfx::RectF arbitrary_rectf1(4.2f, -922.1f, 15.6f, 29.5f);
241  gfx::SizeF arbitrary_sizef1(15.2f, 104.6f);
242  gfx::PointF arbitrary_pointf1(31.4f, 15.9f);
243  gfx::PointF arbitrary_pointf2(26.5f, -35.8f);
244  float arbitrary_float1 = 0.7f;
245  float arbitrary_float2 = 0.3f;
246  float arbitrary_float3 = 0.9f;
247  float arbitrary_float_array[4] = {3.5f, 6.2f, 9.3f, 12.3f};
248  bool arbitrary_bool1 = true;
249  bool arbitrary_bool2 = false;
250  bool arbitrary_bool3 = true;
251  int arbitrary_context_id1 = 12;
252  int arbitrary_context_id2 = 57;
253  int arbitrary_context_id3 = -503;
254  int arbitrary_int = 5;
255  SkColor arbitrary_color = SkColorSetARGB(25, 36, 47, 58);
256  SkXfermode::Mode arbitrary_blend_mode1 = SkXfermode::kScreen_Mode;
257  SkXfermode::Mode arbitrary_blend_mode2 = SkXfermode::kLighten_Mode;
258  SkXfermode::Mode arbitrary_blend_mode3 = SkXfermode::kOverlay_Mode;
259  IOSurfaceDrawQuad::Orientation arbitrary_orientation =
260      IOSurfaceDrawQuad::UNFLIPPED;
261  RenderPass::Id arbitrary_id(10, 14);
262  ResourceProvider::ResourceId arbitrary_resourceid1 = 55;
263  ResourceProvider::ResourceId arbitrary_resourceid2 = 47;
264  ResourceProvider::ResourceId arbitrary_resourceid3 = 23;
265  ResourceProvider::ResourceId arbitrary_resourceid4 = 16;
266  SkScalar arbitrary_sigma = SkFloatToScalar(2.0f);
267  YUVVideoDrawQuad::ColorSpace arbitrary_color_space =
268      YUVVideoDrawQuad::REC_601;
269
270  FilterOperations arbitrary_filters1;
271  arbitrary_filters1.Append(FilterOperation::CreateGrayscaleFilter(
272      arbitrary_float1));
273  skia::RefPtr<SkImageFilter> arbitrary_filter = skia::AdoptRef(
274      SkBlurImageFilter::Create(arbitrary_sigma, arbitrary_sigma));
275  arbitrary_filters1.Append(
276      cc::FilterOperation::CreateReferenceFilter(arbitrary_filter));
277
278  FilterOperations arbitrary_filters2;
279  arbitrary_filters2.Append(FilterOperation::CreateBrightnessFilter(
280      arbitrary_float2));
281
282  scoped_ptr<RenderPass> pass_in = RenderPass::Create();
283  pass_in->SetAll(arbitrary_id,
284                  arbitrary_rect1,
285                  arbitrary_rect2,
286                  arbitrary_matrix,
287                  arbitrary_bool1);
288
289  SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState();
290  shared_state1_in->SetAll(arbitrary_matrix,
291                           arbitrary_size1,
292                           arbitrary_rect1,
293                           arbitrary_rect2,
294                           arbitrary_bool1,
295                           arbitrary_float1,
296                           arbitrary_blend_mode1,
297                           arbitrary_context_id1);
298
299  scoped_ptr<RenderPass> pass_cmp = RenderPass::Create();
300  pass_cmp->SetAll(arbitrary_id,
301                   arbitrary_rect1,
302                   arbitrary_rect2,
303                   arbitrary_matrix,
304                   arbitrary_bool1);
305
306  SharedQuadState* shared_state1_cmp =
307      pass_cmp->CreateAndAppendSharedQuadState();
308  shared_state1_cmp->CopyFrom(shared_state1_in);
309
310  scoped_ptr<CheckerboardDrawQuad> checkerboard_in =
311      CheckerboardDrawQuad::Create();
312  checkerboard_in->SetAll(shared_state1_in,
313                          arbitrary_rect1,
314                          arbitrary_rect2_inside_rect1,
315                          arbitrary_rect1_inside_rect1,
316                          arbitrary_bool1,
317                          arbitrary_color);
318  scoped_ptr<DrawQuad> checkerboard_cmp = checkerboard_in->Copy(
319      checkerboard_in->shared_quad_state);
320
321  scoped_ptr<DebugBorderDrawQuad> debugborder_in =
322      DebugBorderDrawQuad::Create();
323  debugborder_in->SetAll(shared_state1_in,
324                         arbitrary_rect3,
325                         arbitrary_rect1_inside_rect3,
326                         arbitrary_rect2_inside_rect3,
327                         arbitrary_bool1,
328                         arbitrary_color,
329                         arbitrary_int);
330  scoped_ptr<DrawQuad> debugborder_cmp = debugborder_in->Copy(
331      debugborder_in->shared_quad_state);
332
333  scoped_ptr<IOSurfaceDrawQuad> iosurface_in =
334      IOSurfaceDrawQuad::Create();
335  iosurface_in->SetAll(shared_state1_in,
336                       arbitrary_rect2,
337                       arbitrary_rect2_inside_rect2,
338                       arbitrary_rect1_inside_rect2,
339                       arbitrary_bool1,
340                       arbitrary_size1,
341                       arbitrary_resourceid3,
342                       arbitrary_orientation);
343  scoped_ptr<DrawQuad> iosurface_cmp = iosurface_in->Copy(
344      iosurface_in->shared_quad_state);
345
346  SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState();
347  shared_state2_in->SetAll(arbitrary_matrix,
348                           arbitrary_size2,
349                           arbitrary_rect2,
350                           arbitrary_rect3,
351                           arbitrary_bool1,
352                           arbitrary_float2,
353                           arbitrary_blend_mode2,
354                           arbitrary_context_id2);
355  SharedQuadState* shared_state2_cmp =
356      pass_cmp->CreateAndAppendSharedQuadState();
357  shared_state2_cmp->CopyFrom(shared_state2_in);
358
359  scoped_ptr<RenderPassDrawQuad> renderpass_in =
360      RenderPassDrawQuad::Create();
361  renderpass_in->SetAll(shared_state2_in,
362                        arbitrary_rect1,
363                        arbitrary_rect2_inside_rect1,
364                        arbitrary_rect1_inside_rect1,
365                        arbitrary_bool1,
366                        arbitrary_id,
367                        arbitrary_bool2,
368                        arbitrary_resourceid2,
369                        arbitrary_rect1,
370                        arbitrary_rectf1,
371                        arbitrary_filters1,
372                        arbitrary_filters2);
373  scoped_ptr<RenderPassDrawQuad> renderpass_cmp = renderpass_in->Copy(
374      renderpass_in->shared_quad_state, renderpass_in->render_pass_id);
375
376  SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState();
377  shared_state3_in->SetAll(arbitrary_matrix,
378                           arbitrary_size3,
379                           arbitrary_rect3,
380                           arbitrary_rect1,
381                           arbitrary_bool1,
382                           arbitrary_float3,
383                           arbitrary_blend_mode3,
384                           arbitrary_context_id3);
385  SharedQuadState* shared_state3_cmp =
386      pass_cmp->CreateAndAppendSharedQuadState();
387  shared_state3_cmp->CopyFrom(shared_state3_in);
388
389  scoped_ptr<SolidColorDrawQuad> solidcolor_in =
390      SolidColorDrawQuad::Create();
391  solidcolor_in->SetAll(shared_state3_in,
392                        arbitrary_rect3,
393                        arbitrary_rect1_inside_rect3,
394                        arbitrary_rect2_inside_rect3,
395                        arbitrary_bool1,
396                        arbitrary_color,
397                        arbitrary_bool2);
398  scoped_ptr<DrawQuad> solidcolor_cmp = solidcolor_in->Copy(
399      solidcolor_in->shared_quad_state);
400
401  scoped_ptr<StreamVideoDrawQuad> streamvideo_in =
402      StreamVideoDrawQuad::Create();
403  streamvideo_in->SetAll(shared_state3_in,
404                         arbitrary_rect2,
405                         arbitrary_rect2_inside_rect2,
406                         arbitrary_rect1_inside_rect2,
407                         arbitrary_bool1,
408                         arbitrary_resourceid2,
409                         arbitrary_matrix);
410  scoped_ptr<DrawQuad> streamvideo_cmp = streamvideo_in->Copy(
411      streamvideo_in->shared_quad_state);
412
413  cc::SurfaceId arbitrary_surface_id(3);
414  scoped_ptr<SurfaceDrawQuad> surface_in = SurfaceDrawQuad::Create();
415  surface_in->SetAll(shared_state3_in,
416                     arbitrary_rect2,
417                     arbitrary_rect2_inside_rect2,
418                     arbitrary_rect1_inside_rect2,
419                     arbitrary_bool1,
420                     arbitrary_surface_id);
421  scoped_ptr<DrawQuad> surface_cmp = surface_in->Copy(
422      surface_in->shared_quad_state);
423
424  scoped_ptr<TextureDrawQuad> texture_in = TextureDrawQuad::Create();
425  texture_in->SetAll(shared_state3_in,
426                     arbitrary_rect2,
427                     arbitrary_rect2_inside_rect2,
428                     arbitrary_rect1_inside_rect2,
429                     arbitrary_bool1,
430                     arbitrary_resourceid1,
431                     arbitrary_bool2,
432                     arbitrary_pointf1,
433                     arbitrary_pointf2,
434                     arbitrary_color,
435                     arbitrary_float_array,
436                     arbitrary_bool3);
437  scoped_ptr<DrawQuad> texture_cmp = texture_in->Copy(
438      texture_in->shared_quad_state);
439
440  scoped_ptr<TileDrawQuad> tile_in = TileDrawQuad::Create();
441  tile_in->SetAll(shared_state3_in,
442                  arbitrary_rect2,
443                  arbitrary_rect2_inside_rect2,
444                  arbitrary_rect1_inside_rect2,
445                  arbitrary_bool1,
446                  arbitrary_resourceid3,
447                  arbitrary_rectf1,
448                  arbitrary_size1,
449                  arbitrary_bool2);
450  scoped_ptr<DrawQuad> tile_cmp = tile_in->Copy(
451      tile_in->shared_quad_state);
452
453  scoped_ptr<YUVVideoDrawQuad> yuvvideo_in =
454      YUVVideoDrawQuad::Create();
455  yuvvideo_in->SetAll(shared_state3_in,
456                      arbitrary_rect1,
457                      arbitrary_rect2_inside_rect1,
458                      arbitrary_rect1_inside_rect1,
459                      arbitrary_bool1,
460                      arbitrary_rectf1,
461                      arbitrary_resourceid1,
462                      arbitrary_resourceid2,
463                      arbitrary_resourceid3,
464                      arbitrary_resourceid4,
465                      arbitrary_color_space);
466  scoped_ptr<DrawQuad> yuvvideo_cmp = yuvvideo_in->Copy(
467      yuvvideo_in->shared_quad_state);
468
469  pass_in->quad_list.push_back(checkerboard_in.PassAs<DrawQuad>());
470  pass_in->quad_list.push_back(debugborder_in.PassAs<DrawQuad>());
471  pass_in->quad_list.push_back(iosurface_in.PassAs<DrawQuad>());
472  pass_in->quad_list.push_back(renderpass_in.PassAs<DrawQuad>());
473  pass_in->quad_list.push_back(solidcolor_in.PassAs<DrawQuad>());
474  pass_in->quad_list.push_back(streamvideo_in.PassAs<DrawQuad>());
475  pass_in->quad_list.push_back(surface_in.PassAs<DrawQuad>());
476  pass_in->quad_list.push_back(texture_in.PassAs<DrawQuad>());
477  pass_in->quad_list.push_back(tile_in.PassAs<DrawQuad>());
478  pass_in->quad_list.push_back(yuvvideo_in.PassAs<DrawQuad>());
479
480
481  pass_cmp->quad_list.push_back(checkerboard_cmp.PassAs<DrawQuad>());
482  pass_cmp->quad_list.push_back(debugborder_cmp.PassAs<DrawQuad>());
483  pass_cmp->quad_list.push_back(iosurface_cmp.PassAs<DrawQuad>());
484  pass_cmp->quad_list.push_back(renderpass_cmp.PassAs<DrawQuad>());
485  pass_cmp->quad_list.push_back(solidcolor_cmp.PassAs<DrawQuad>());
486  pass_cmp->quad_list.push_back(streamvideo_cmp.PassAs<DrawQuad>());
487  pass_cmp->quad_list.push_back(surface_cmp.PassAs<DrawQuad>());
488  pass_cmp->quad_list.push_back(texture_cmp.PassAs<DrawQuad>());
489  pass_cmp->quad_list.push_back(tile_cmp.PassAs<DrawQuad>());
490  pass_cmp->quad_list.push_back(yuvvideo_cmp.PassAs<DrawQuad>());
491
492  // Make sure the in and cmp RenderPasses match.
493  Compare(pass_cmp.get(), pass_in.get());
494  ASSERT_EQ(3u, pass_in->shared_quad_state_list.size());
495  ASSERT_EQ(10u, pass_in->quad_list.size());
496  for (size_t i = 0; i < 3; ++i) {
497    Compare(pass_cmp->shared_quad_state_list[i],
498            pass_in->shared_quad_state_list[i]);
499  }
500  for (size_t i = 0; i < pass_in->quad_list.size(); ++i)
501    Compare(pass_cmp->quad_list[i], pass_in->quad_list[i]);
502  for (size_t i = 1; i < pass_in->quad_list.size(); ++i) {
503    bool same_shared_quad_state_cmp =
504        pass_cmp->quad_list[i]->shared_quad_state ==
505        pass_cmp->quad_list[i - 1]->shared_quad_state;
506    bool same_shared_quad_state_in =
507        pass_in->quad_list[i]->shared_quad_state ==
508        pass_in->quad_list[i - 1]->shared_quad_state;
509    EXPECT_EQ(same_shared_quad_state_cmp, same_shared_quad_state_in);
510  }
511
512  DelegatedFrameData frame_in;
513  frame_in.render_pass_list.push_back(pass_in.Pass());
514
515  IPC::ParamTraits<DelegatedFrameData>::Write(&msg, frame_in);
516
517  DelegatedFrameData frame_out;
518  PickleIterator iter(msg);
519  EXPECT_TRUE(IPC::ParamTraits<DelegatedFrameData>::Read(&msg,
520      &iter, &frame_out));
521
522  // Make sure the out and cmp RenderPasses match.
523  scoped_ptr<RenderPass> pass_out = frame_out.render_pass_list.take(
524      frame_out.render_pass_list.begin());
525  Compare(pass_cmp.get(), pass_out.get());
526  ASSERT_EQ(3u, pass_out->shared_quad_state_list.size());
527  ASSERT_EQ(10u, pass_out->quad_list.size());
528  for (size_t i = 0; i < 3; ++i) {
529    Compare(pass_cmp->shared_quad_state_list[i],
530            pass_out->shared_quad_state_list[i]);
531  }
532  for (size_t i = 0; i < pass_out->quad_list.size(); ++i)
533    Compare(pass_cmp->quad_list[i], pass_out->quad_list[i]);
534  for (size_t i = 1; i < pass_out->quad_list.size(); ++i) {
535    bool same_shared_quad_state_cmp =
536        pass_cmp->quad_list[i]->shared_quad_state ==
537        pass_cmp->quad_list[i - 1]->shared_quad_state;
538    bool same_shared_quad_state_out =
539        pass_out->quad_list[i]->shared_quad_state ==
540        pass_out->quad_list[i - 1]->shared_quad_state;
541    EXPECT_EQ(same_shared_quad_state_cmp, same_shared_quad_state_out);
542  }
543}
544
545TEST_F(CCMessagesTest, UnusedSharedQuadStates) {
546  scoped_ptr<CheckerboardDrawQuad> quad;
547
548  scoped_ptr<RenderPass> pass_in = RenderPass::Create();
549  pass_in->SetAll(RenderPass::Id(1, 1),
550                  gfx::Rect(100, 100),
551                  gfx::Rect(),
552                  gfx::Transform(),
553                  false);
554
555  // The first SharedQuadState is used.
556  SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState();
557  shared_state1_in->SetAll(gfx::Transform(),
558                           gfx::Size(1, 1),
559                           gfx::Rect(),
560                           gfx::Rect(),
561                           false,
562                           1.f,
563                           SkXfermode::kSrcOver_Mode,
564                           0);
565
566  quad = CheckerboardDrawQuad::Create();
567  quad->SetAll(shared_state1_in,
568               gfx::Rect(10, 10),
569               gfx::Rect(10, 10),
570               gfx::Rect(10, 10),
571               false,
572               SK_ColorRED);
573  pass_in->quad_list.push_back(quad.PassAs<DrawQuad>());
574
575  // The second and third SharedQuadStates are not used.
576  SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState();
577  shared_state2_in->SetAll(gfx::Transform(),
578                           gfx::Size(2, 2),
579                           gfx::Rect(),
580                           gfx::Rect(),
581                           false,
582                           1.f,
583                           SkXfermode::kSrcOver_Mode,
584                           0);
585
586  SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState();
587  shared_state3_in->SetAll(gfx::Transform(),
588                           gfx::Size(3, 3),
589                           gfx::Rect(),
590                           gfx::Rect(),
591                           false,
592                           1.f,
593                           SkXfermode::kSrcOver_Mode,
594                           0);
595
596  // The fourth SharedQuadState is used.
597  SharedQuadState* shared_state4_in = pass_in->CreateAndAppendSharedQuadState();
598  shared_state4_in->SetAll(gfx::Transform(),
599                           gfx::Size(4, 4),
600                           gfx::Rect(),
601                           gfx::Rect(),
602                           false,
603                           1.f,
604                           SkXfermode::kSrcOver_Mode,
605                           0);
606
607  quad = CheckerboardDrawQuad::Create();
608  quad->SetAll(shared_state4_in,
609               gfx::Rect(10, 10),
610               gfx::Rect(10, 10),
611               gfx::Rect(10, 10),
612               false,
613               SK_ColorRED);
614  pass_in->quad_list.push_back(quad.PassAs<DrawQuad>());
615
616  // The fifth is not used again.
617  SharedQuadState* shared_state5_in = pass_in->CreateAndAppendSharedQuadState();
618  shared_state5_in->SetAll(gfx::Transform(),
619                           gfx::Size(5, 5),
620                           gfx::Rect(),
621                           gfx::Rect(),
622                           false,
623                           1.f,
624                           SkXfermode::kSrcOver_Mode,
625                           0);
626
627  // 5 SharedQuadStates go in.
628  ASSERT_EQ(5u, pass_in->shared_quad_state_list.size());
629  ASSERT_EQ(2u, pass_in->quad_list.size());
630
631  DelegatedFrameData frame_in;
632  frame_in.render_pass_list.push_back(pass_in.Pass());
633
634  IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
635  IPC::ParamTraits<DelegatedFrameData>::Write(&msg, frame_in);
636
637  DelegatedFrameData frame_out;
638  PickleIterator iter(msg);
639  EXPECT_TRUE(
640      IPC::ParamTraits<DelegatedFrameData>::Read(&msg, &iter, &frame_out));
641
642  scoped_ptr<RenderPass> pass_out =
643      frame_out.render_pass_list.take(frame_out.render_pass_list.begin());
644
645  // 2 SharedQuadStates come out. The first and fourth SharedQuadStates were
646  // used by quads, and so serialized. Others were not.
647  ASSERT_EQ(2u, pass_out->shared_quad_state_list.size());
648  ASSERT_EQ(2u, pass_out->quad_list.size());
649
650  EXPECT_EQ(gfx::Size(1, 1).ToString(),
651            pass_out->shared_quad_state_list[0]->content_bounds.ToString());
652  EXPECT_EQ(gfx::Size(4, 4).ToString(),
653            pass_out->shared_quad_state_list[1]->content_bounds.ToString());
654}
655
656TEST_F(CCMessagesTest, Resources) {
657  IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
658  gfx::Size arbitrary_size(757, 1281);
659  unsigned int arbitrary_uint1 = 71234838;
660  unsigned int arbitrary_uint2 = 53589793;
661
662  GLbyte arbitrary_mailbox1[GL_MAILBOX_SIZE_CHROMIUM] = {
663      1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
664      3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
665      5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4};
666
667  GLbyte arbitrary_mailbox2[GL_MAILBOX_SIZE_CHROMIUM] = {
668      0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9,
669      8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7,
670      6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7};
671
672  TransferableResource arbitrary_resource1;
673  arbitrary_resource1.id = 2178312;
674  arbitrary_resource1.format = cc::RGBA_8888;
675  arbitrary_resource1.filter = 53;
676  arbitrary_resource1.size = gfx::Size(37189, 123123);
677  arbitrary_resource1.mailbox_holder.mailbox.SetName(arbitrary_mailbox1);
678  arbitrary_resource1.mailbox_holder.texture_target = GL_TEXTURE_2D;
679  arbitrary_resource1.mailbox_holder.sync_point = arbitrary_uint1;
680
681  TransferableResource arbitrary_resource2;
682  arbitrary_resource2.id = 789132;
683  arbitrary_resource2.format = cc::RGBA_4444;
684  arbitrary_resource2.filter = 47;
685  arbitrary_resource2.size = gfx::Size(89123, 23789);
686  arbitrary_resource2.mailbox_holder.mailbox.SetName(arbitrary_mailbox2);
687  arbitrary_resource2.mailbox_holder.texture_target = GL_TEXTURE_EXTERNAL_OES;
688  arbitrary_resource2.mailbox_holder.sync_point = arbitrary_uint2;
689
690  scoped_ptr<RenderPass> renderpass_in = RenderPass::Create();
691  renderpass_in->SetNew(
692      RenderPass::Id(1, 1), gfx::Rect(), gfx::Rect(), gfx::Transform());
693
694  DelegatedFrameData frame_in;
695  frame_in.resource_list.push_back(arbitrary_resource1);
696  frame_in.resource_list.push_back(arbitrary_resource2);
697  frame_in.render_pass_list.push_back(renderpass_in.Pass());
698
699  IPC::ParamTraits<DelegatedFrameData>::Write(&msg, frame_in);
700
701  DelegatedFrameData frame_out;
702  PickleIterator iter(msg);
703  EXPECT_TRUE(IPC::ParamTraits<DelegatedFrameData>::Read(&msg,
704      &iter, &frame_out));
705
706  ASSERT_EQ(2u, frame_out.resource_list.size());
707  Compare(arbitrary_resource1, frame_out.resource_list[0]);
708  Compare(arbitrary_resource2, frame_out.resource_list[1]);
709}
710
711TEST_F(CCMessagesTest, LargestQuadType) {
712  size_t largest = 0;
713
714  bool done = false;
715  for (int i = 0; !done; ++i) {
716    switch (static_cast<DrawQuad::Material>(i)) {
717      case cc::DrawQuad::CHECKERBOARD:
718        largest = std::max(largest, sizeof(cc::CheckerboardDrawQuad));
719        break;
720      case cc::DrawQuad::DEBUG_BORDER:
721        largest = std::max(largest, sizeof(cc::DebugBorderDrawQuad));
722        break;
723      case cc::DrawQuad::IO_SURFACE_CONTENT:
724        largest = std::max(largest, sizeof(cc::IOSurfaceDrawQuad));
725        break;
726      case cc::DrawQuad::PICTURE_CONTENT:
727        largest = std::max(largest, sizeof(cc::PictureDrawQuad));
728        break;
729      case cc::DrawQuad::TEXTURE_CONTENT:
730        largest = std::max(largest, sizeof(cc::TextureDrawQuad));
731        break;
732      case cc::DrawQuad::RENDER_PASS:
733        largest = std::max(largest, sizeof(cc::RenderPassDrawQuad));
734        break;
735      case cc::DrawQuad::SOLID_COLOR:
736        largest = std::max(largest, sizeof(cc::SolidColorDrawQuad));
737        break;
738      case cc::DrawQuad::SURFACE_CONTENT:
739        largest = std::max(largest, sizeof(cc::SurfaceDrawQuad));
740        break;
741      case cc::DrawQuad::TILED_CONTENT:
742        largest = std::max(largest, sizeof(cc::TileDrawQuad));
743        break;
744      case cc::DrawQuad::STREAM_VIDEO_CONTENT:
745        largest = std::max(largest, sizeof(cc::StreamVideoDrawQuad));
746        break;
747      case cc::DrawQuad::YUV_VIDEO_CONTENT:
748        largest = std::max(largest, sizeof(cc::YUVVideoDrawQuad));
749        break;
750      case cc::DrawQuad::INVALID:
751        break;
752      default:
753        done = true;
754    }
755  }
756
757  // Verify the largest DrawQuad type is RenderPassDrawQuad. If this ever
758  // changes, then the ReserveSizeForRenderPassWrite() method needs to be
759  // updated as well to use the new largest quad.
760  EXPECT_EQ(sizeof(RenderPassDrawQuad), largest);
761}
762
763TEST_F(CCMessagesTest, SoftwareFrameData) {
764  cc::SoftwareFrameData frame_in;
765  frame_in.id = 3;
766  frame_in.size = gfx::Size(40, 20);
767  frame_in.damage_rect = gfx::Rect(5, 18, 31, 44);
768  frame_in.bitmap_id = cc::SharedBitmap::GenerateId();
769
770  // Write the frame.
771  IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
772  IPC::ParamTraits<cc::SoftwareFrameData>::Write(&msg, frame_in);
773
774  // Read the frame.
775  cc::SoftwareFrameData frame_out;
776  PickleIterator iter(msg);
777  EXPECT_TRUE(
778      IPC::ParamTraits<SoftwareFrameData>::Read(&msg, &iter, &frame_out));
779  EXPECT_EQ(frame_in.id, frame_out.id);
780  EXPECT_EQ(frame_in.size.ToString(), frame_out.size.ToString());
781  EXPECT_EQ(frame_in.damage_rect.ToString(), frame_out.damage_rect.ToString());
782  EXPECT_EQ(frame_in.bitmap_id, frame_out.bitmap_id);
783}
784
785TEST_F(CCMessagesTest, SoftwareFrameDataMaxInt) {
786  SoftwareFrameData frame_in;
787  frame_in.id = 3;
788  frame_in.size = gfx::Size(40, 20);
789  frame_in.damage_rect = gfx::Rect(5, 18, 31, 44);
790  frame_in.bitmap_id = cc::SharedBitmap::GenerateId();
791
792  // Write the SoftwareFrameData by hand, make sure it works.
793  {
794    IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
795    IPC::WriteParam(&msg, frame_in.id);
796    IPC::WriteParam(&msg, frame_in.size);
797    IPC::WriteParam(&msg, frame_in.damage_rect);
798    IPC::WriteParam(&msg, frame_in.bitmap_id);
799    SoftwareFrameData frame_out;
800    PickleIterator iter(msg);
801    EXPECT_TRUE(
802        IPC::ParamTraits<SoftwareFrameData>::Read(&msg, &iter, &frame_out));
803  }
804
805  // The size of the frame may overflow when multiplied together.
806  int max = std::numeric_limits<int>::max();
807  frame_in.size = gfx::Size(max, max);
808
809  // If size_t is larger than int, then int*int*4 can always fit in size_t.
810  bool expect_read = sizeof(size_t) >= sizeof(int) * 2;
811
812  // Write the SoftwareFrameData with the MaxInt size, if it causes overflow it
813  // should fail.
814  {
815    IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
816    IPC::WriteParam(&msg, frame_in.id);
817    IPC::WriteParam(&msg, frame_in.size);
818    IPC::WriteParam(&msg, frame_in.damage_rect);
819    IPC::WriteParam(&msg, frame_in.bitmap_id);
820    SoftwareFrameData frame_out;
821    PickleIterator iter(msg);
822    EXPECT_EQ(
823        expect_read,
824        IPC::ParamTraits<SoftwareFrameData>::Read(&msg, &iter, &frame_out));
825  }
826}
827
828}  // namespace
829}  // namespace content
830