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