Home | History | Annotate | Download | only in common
      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 
     22 using cc::CheckerboardDrawQuad;
     23 using cc::DelegatedFrameData;
     24 using cc::DebugBorderDrawQuad;
     25 using cc::DrawQuad;
     26 using cc::FilterOperation;
     27 using cc::FilterOperations;
     28 using cc::IOSurfaceDrawQuad;
     29 using cc::PictureDrawQuad;
     30 using cc::RenderPass;
     31 using cc::RenderPassDrawQuad;
     32 using cc::ResourceProvider;
     33 using cc::SharedQuadState;
     34 using cc::SoftwareFrameData;
     35 using cc::SolidColorDrawQuad;
     36 using cc::SurfaceDrawQuad;
     37 using cc::TextureDrawQuad;
     38 using cc::TileDrawQuad;
     39 using cc::TransferableResource;
     40 using cc::StreamVideoDrawQuad;
     41 using cc::VideoLayerImpl;
     42 using cc::YUVVideoDrawQuad;
     43 using gfx::Transform;
     44 
     45 namespace content {
     46 namespace {
     47 
     48 class 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 
    221 TEST_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 
    545 TEST_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 
    656 TEST_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 
    711 TEST_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 
    763 TEST_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 
    785 TEST_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