Home | History | Annotate | Download | only in lib
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h"
      6 
      7 #include "base/macros.h"
      8 #include "cc/output/compositor_frame.h"
      9 #include "cc/output/delegated_frame_data.h"
     10 #include "cc/quads/draw_quad.h"
     11 #include "cc/quads/render_pass.h"
     12 #include "cc/quads/render_pass_draw_quad.h"
     13 #include "cc/quads/shared_quad_state.h"
     14 #include "cc/quads/solid_color_draw_quad.h"
     15 #include "cc/quads/surface_draw_quad.h"
     16 #include "cc/quads/texture_draw_quad.h"
     17 #include "cc/quads/tile_draw_quad.h"
     18 #include "cc/quads/yuv_video_draw_quad.h"
     19 #include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
     20 
     21 namespace mojo {
     22 
     23 #define ASSERT_ENUM_VALUES_EQUAL(value)                                      \
     24   COMPILE_ASSERT(cc::DrawQuad::value == static_cast<cc::DrawQuad::Material>( \
     25                                             MATERIAL_##value),     \
     26                  value##_enum_value_matches)
     27 
     28 ASSERT_ENUM_VALUES_EQUAL(CHECKERBOARD);
     29 ASSERT_ENUM_VALUES_EQUAL(DEBUG_BORDER);
     30 ASSERT_ENUM_VALUES_EQUAL(IO_SURFACE_CONTENT);
     31 ASSERT_ENUM_VALUES_EQUAL(PICTURE_CONTENT);
     32 ASSERT_ENUM_VALUES_EQUAL(RENDER_PASS);
     33 ASSERT_ENUM_VALUES_EQUAL(SOLID_COLOR);
     34 ASSERT_ENUM_VALUES_EQUAL(STREAM_VIDEO_CONTENT);
     35 ASSERT_ENUM_VALUES_EQUAL(SURFACE_CONTENT);
     36 ASSERT_ENUM_VALUES_EQUAL(TEXTURE_CONTENT);
     37 ASSERT_ENUM_VALUES_EQUAL(TILED_CONTENT);
     38 ASSERT_ENUM_VALUES_EQUAL(YUV_VIDEO_CONTENT);
     39 
     40 COMPILE_ASSERT(
     41     cc::YUVVideoDrawQuad::REC_601 ==
     42         static_cast<cc::YUVVideoDrawQuad::ColorSpace>(YUV_COLOR_SPACE_REC_601),
     43     rec_601_enum_matches);
     44 COMPILE_ASSERT(cc::YUVVideoDrawQuad::REC_601_JPEG ==
     45                    static_cast<cc::YUVVideoDrawQuad::ColorSpace>(
     46                        YUV_COLOR_SPACE_REC_601_JPEG),
     47                rec_601_jpeg_enum_matches);
     48 
     49 namespace {
     50 
     51 cc::SharedQuadState* ConvertSharedQuadState(const SharedQuadStatePtr& input,
     52                                             cc::RenderPass* render_pass) {
     53   cc::SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState();
     54   state->SetAll(input->content_to_target_transform.To<gfx::Transform>(),
     55                 input->content_bounds.To<gfx::Size>(),
     56                 input->visible_content_rect.To<gfx::Rect>(),
     57                 input->clip_rect.To<gfx::Rect>(),
     58                 input->is_clipped,
     59                 input->opacity,
     60                 static_cast<::SkXfermode::Mode>(input->blend_mode),
     61                 input->sorting_context_id);
     62   return state;
     63 }
     64 
     65 bool ConvertDrawQuad(const QuadPtr& input,
     66                      cc::SharedQuadState* sqs,
     67                      cc::RenderPass* render_pass) {
     68   switch (input->material) {
     69     case MATERIAL_RENDER_PASS: {
     70       cc::RenderPassDrawQuad* render_pass_quad =
     71           render_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>();
     72       RenderPassQuadState* render_pass_quad_state =
     73           input->render_pass_quad_state.get();
     74       gfx::PointF filter_scale_as_point =
     75           render_pass_quad_state->filters_scale.To<gfx::PointF>();
     76       render_pass_quad->SetAll(
     77           sqs,
     78           input->rect.To<gfx::Rect>(),
     79           input->opaque_rect.To<gfx::Rect>(),
     80           input->visible_rect.To<gfx::Rect>(),
     81           input->needs_blending,
     82           render_pass_quad_state->render_pass_id.To<cc::RenderPassId>(),
     83           render_pass_quad_state->mask_resource_id,
     84           render_pass_quad_state->mask_uv_rect.To<gfx::RectF>(),
     85           cc::FilterOperations(),  // TODO(jamesr): filters
     86           gfx::Vector2dF(filter_scale_as_point.x(), filter_scale_as_point.y()),
     87           cc::FilterOperations());  // TODO(jamesr): background_filters
     88       break;
     89     }
     90     case MATERIAL_SOLID_COLOR: {
     91       if (input->solid_color_quad_state.is_null())
     92         return false;
     93       cc::SolidColorDrawQuad* color_quad =
     94           render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
     95       color_quad->SetAll(
     96           sqs,
     97           input->rect.To<gfx::Rect>(),
     98           input->opaque_rect.To<gfx::Rect>(),
     99           input->visible_rect.To<gfx::Rect>(),
    100           input->needs_blending,
    101           input->solid_color_quad_state->color.To<SkColor>(),
    102           input->solid_color_quad_state->force_anti_aliasing_off);
    103       break;
    104     }
    105     case MATERIAL_SURFACE_CONTENT: {
    106       if (input->surface_quad_state.is_null())
    107         return false;
    108       cc::SurfaceDrawQuad* surface_quad =
    109           render_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
    110       surface_quad->SetAll(
    111           sqs,
    112           input->rect.To<gfx::Rect>(),
    113           input->opaque_rect.To<gfx::Rect>(),
    114           input->visible_rect.To<gfx::Rect>(),
    115           input->needs_blending,
    116           input->surface_quad_state->surface.To<cc::SurfaceId>());
    117       break;
    118     }
    119     case MATERIAL_TEXTURE_CONTENT: {
    120       TextureQuadStatePtr& texture_quad_state =
    121           input->texture_quad_state;
    122       if (texture_quad_state.is_null() ||
    123           texture_quad_state->vertex_opacity.is_null() ||
    124           texture_quad_state->background_color.is_null())
    125         return false;
    126       cc::TextureDrawQuad* texture_quad =
    127           render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
    128       texture_quad->SetAll(
    129           sqs,
    130           input->rect.To<gfx::Rect>(),
    131           input->opaque_rect.To<gfx::Rect>(),
    132           input->visible_rect.To<gfx::Rect>(),
    133           input->needs_blending,
    134           texture_quad_state->resource_id,
    135           texture_quad_state->premultiplied_alpha,
    136           texture_quad_state->uv_top_left.To<gfx::PointF>(),
    137           texture_quad_state->uv_bottom_right.To<gfx::PointF>(),
    138           texture_quad_state->background_color.To<SkColor>(),
    139           &texture_quad_state->vertex_opacity.storage()[0],
    140           texture_quad_state->flipped);
    141       break;
    142     }
    143     case MATERIAL_TILED_CONTENT: {
    144       TileQuadStatePtr& tile_state = input->tile_quad_state;
    145       if (tile_state.is_null())
    146         return false;
    147       cc::TileDrawQuad* tile_quad =
    148           render_pass->CreateAndAppendDrawQuad<cc::TileDrawQuad>();
    149       tile_quad->SetAll(sqs,
    150                         input->rect.To<gfx::Rect>(),
    151                         input->opaque_rect.To<gfx::Rect>(),
    152                         input->visible_rect.To<gfx::Rect>(),
    153                         input->needs_blending,
    154                         tile_state->resource_id,
    155                         tile_state->tex_coord_rect.To<gfx::RectF>(),
    156                         tile_state->texture_size.To<gfx::Size>(),
    157                         tile_state->swizzle_contents);
    158       break;
    159     }
    160     case MATERIAL_YUV_VIDEO_CONTENT: {
    161       YUVVideoQuadStatePtr& yuv_state = input->yuv_video_quad_state;
    162       if (yuv_state.is_null())
    163         return false;
    164       cc::YUVVideoDrawQuad* yuv_quad =
    165           render_pass->CreateAndAppendDrawQuad<cc::YUVVideoDrawQuad>();
    166       yuv_quad->SetAll(sqs,
    167                        input->rect.To<gfx::Rect>(),
    168                        input->opaque_rect.To<gfx::Rect>(),
    169                        input->visible_rect.To<gfx::Rect>(),
    170                        input->needs_blending,
    171                        yuv_state->tex_coord_rect.To<gfx::RectF>(),
    172                        yuv_state->y_plane_resource_id,
    173                        yuv_state->u_plane_resource_id,
    174                        yuv_state->v_plane_resource_id,
    175                        yuv_state->a_plane_resource_id,
    176                        static_cast<cc::YUVVideoDrawQuad::ColorSpace>(
    177                            yuv_state->color_space));
    178       break;
    179     }
    180     default:
    181       NOTREACHED() << "Unsupported material " << input->material;
    182       return false;
    183   }
    184   return true;
    185 }
    186 
    187 }  // namespace
    188 
    189 // static
    190 SurfaceIdPtr TypeConverter<SurfaceIdPtr, cc::SurfaceId>::Convert(
    191     const cc::SurfaceId& input) {
    192   SurfaceIdPtr id(SurfaceId::New());
    193   id->id = input.id;
    194   return id.Pass();
    195 }
    196 
    197 // static
    198 cc::SurfaceId TypeConverter<cc::SurfaceId, SurfaceIdPtr>::Convert(
    199     const SurfaceIdPtr& input) {
    200   return cc::SurfaceId(input->id);
    201 }
    202 
    203 // static
    204 ColorPtr TypeConverter<ColorPtr, SkColor>::Convert(const SkColor& input) {
    205   ColorPtr color(Color::New());
    206   color->rgba = input;
    207   return color.Pass();
    208 }
    209 
    210 // static
    211 SkColor TypeConverter<SkColor, ColorPtr>::Convert(const ColorPtr& input) {
    212   return input->rgba;
    213 }
    214 
    215 // static
    216 RenderPassIdPtr TypeConverter<RenderPassIdPtr, cc::RenderPassId>::Convert(
    217     const cc::RenderPassId& input) {
    218   RenderPassIdPtr pass_id(RenderPassId::New());
    219   pass_id->layer_id = input.layer_id;
    220   pass_id->index = input.index;
    221   return pass_id.Pass();
    222 }
    223 
    224 // static
    225 cc::RenderPassId TypeConverter<cc::RenderPassId, RenderPassIdPtr>::Convert(
    226     const RenderPassIdPtr& input) {
    227   return cc::RenderPassId(input->layer_id, input->index);
    228 }
    229 
    230 // static
    231 QuadPtr TypeConverter<QuadPtr, cc::DrawQuad>::Convert(
    232     const cc::DrawQuad& input) {
    233   QuadPtr quad = Quad::New();
    234   quad->material = static_cast<Material>(input.material);
    235   quad->rect = Rect::From(input.rect);
    236   quad->opaque_rect = Rect::From(input.opaque_rect);
    237   quad->visible_rect = Rect::From(input.visible_rect);
    238   quad->needs_blending = input.needs_blending;
    239   // This is intentionally left set to an invalid value here. It's set when
    240   // converting an entire pass since it's an index into the pass' shared quad
    241   // state list.
    242   quad->shared_quad_state_index = -1;
    243   switch (input.material) {
    244     case cc::DrawQuad::RENDER_PASS: {
    245       const cc::RenderPassDrawQuad* render_pass_quad =
    246           cc::RenderPassDrawQuad::MaterialCast(&input);
    247       RenderPassQuadStatePtr pass_state = RenderPassQuadState::New();
    248       pass_state->render_pass_id =
    249           RenderPassId::From(render_pass_quad->render_pass_id);
    250       pass_state->mask_resource_id = render_pass_quad->mask_resource_id;
    251       pass_state->mask_uv_rect = RectF::From(render_pass_quad->mask_uv_rect);
    252       // TODO(jamesr): pass_state->filters
    253       pass_state->filters_scale = PointF::From(
    254           gfx::PointAtOffsetFromOrigin(render_pass_quad->filters_scale));
    255       // TODO(jamesr): pass_state->background_filters
    256       quad->render_pass_quad_state = pass_state.Pass();
    257       break;
    258     }
    259     case cc::DrawQuad::SOLID_COLOR: {
    260       const cc::SolidColorDrawQuad* color_quad =
    261           cc::SolidColorDrawQuad::MaterialCast(&input);
    262       SolidColorQuadStatePtr color_state = SolidColorQuadState::New();
    263       color_state->color = Color::From(color_quad->color);
    264       color_state->force_anti_aliasing_off =
    265           color_quad->force_anti_aliasing_off;
    266       quad->solid_color_quad_state = color_state.Pass();
    267       break;
    268     }
    269     case cc::DrawQuad::SURFACE_CONTENT: {
    270       const cc::SurfaceDrawQuad* surface_quad =
    271           cc::SurfaceDrawQuad::MaterialCast(&input);
    272       SurfaceQuadStatePtr surface_state =
    273           SurfaceQuadState::New();
    274       surface_state->surface = SurfaceId::From(surface_quad->surface_id);
    275       quad->surface_quad_state = surface_state.Pass();
    276       break;
    277     }
    278     case cc::DrawQuad::TEXTURE_CONTENT: {
    279       const cc::TextureDrawQuad* texture_quad =
    280           cc::TextureDrawQuad::MaterialCast(&input);
    281       TextureQuadStatePtr texture_state = TextureQuadState::New();
    282       texture_state->resource_id = texture_quad->resource_id;
    283       texture_state->premultiplied_alpha = texture_quad->premultiplied_alpha;
    284       texture_state->uv_top_left = PointF::From(texture_quad->uv_top_left);
    285       texture_state->uv_bottom_right =
    286           PointF::From(texture_quad->uv_bottom_right);
    287       texture_state->background_color =
    288           Color::From(texture_quad->background_color);
    289       Array<float> vertex_opacity(4);
    290       for (size_t i = 0; i < 4; ++i) {
    291         vertex_opacity[i] = texture_quad->vertex_opacity[i];
    292       }
    293       texture_state->vertex_opacity = vertex_opacity.Pass();
    294       texture_state->flipped = texture_quad->flipped;
    295       quad->texture_quad_state = texture_state.Pass();
    296       break;
    297     }
    298     case cc::DrawQuad::TILED_CONTENT: {
    299       const cc::TileDrawQuad* tile_quad =
    300           cc::TileDrawQuad::MaterialCast(&input);
    301       TileQuadStatePtr tile_state = TileQuadState::New();
    302       tile_state->tex_coord_rect = RectF::From(tile_quad->tex_coord_rect);
    303       tile_state->texture_size = Size::From(tile_quad->texture_size);
    304       tile_state->swizzle_contents = tile_quad->swizzle_contents;
    305       tile_state->resource_id = tile_quad->resource_id;
    306       quad->tile_quad_state = tile_state.Pass();
    307       break;
    308     }
    309     case cc::DrawQuad::YUV_VIDEO_CONTENT: {
    310       const cc::YUVVideoDrawQuad* yuv_quad =
    311           cc::YUVVideoDrawQuad::MaterialCast(&input);
    312       YUVVideoQuadStatePtr yuv_state = YUVVideoQuadState::New();
    313       yuv_state->tex_coord_rect = RectF::From(yuv_quad->tex_coord_rect);
    314       yuv_state->y_plane_resource_id = yuv_quad->y_plane_resource_id;
    315       yuv_state->u_plane_resource_id = yuv_quad->u_plane_resource_id;
    316       yuv_state->v_plane_resource_id = yuv_quad->v_plane_resource_id;
    317       yuv_state->a_plane_resource_id = yuv_quad->a_plane_resource_id;
    318       yuv_state->color_space =
    319           static_cast<YUVColorSpace>(yuv_quad->color_space);
    320       quad->yuv_video_quad_state = yuv_state.Pass();
    321       break;
    322     }
    323 
    324     default:
    325       NOTREACHED() << "Unsupported material " << input.material;
    326   }
    327   return quad.Pass();
    328 }
    329 
    330 // static
    331 SharedQuadStatePtr
    332 TypeConverter<SharedQuadStatePtr, cc::SharedQuadState>::Convert(
    333     const cc::SharedQuadState& input) {
    334   SharedQuadStatePtr state = SharedQuadState::New();
    335   state->content_to_target_transform =
    336       Transform::From(input.content_to_target_transform);
    337   state->content_bounds = Size::From(input.content_bounds);
    338   state->visible_content_rect = Rect::From(input.visible_content_rect);
    339   state->clip_rect = Rect::From(input.clip_rect);
    340   state->is_clipped = input.is_clipped;
    341   state->opacity = input.opacity;
    342   state->blend_mode = static_cast<SkXfermode>(input.blend_mode);
    343   state->sorting_context_id = input.sorting_context_id;
    344   return state.Pass();
    345 }
    346 
    347 // static
    348 PassPtr TypeConverter<PassPtr, cc::RenderPass>::Convert(
    349     const cc::RenderPass& input) {
    350   PassPtr pass = Pass::New();
    351   pass->id = input.id.index;
    352   pass->output_rect = Rect::From(input.output_rect);
    353   pass->damage_rect = Rect::From(input.damage_rect);
    354   pass->transform_to_root_target =
    355       Transform::From(input.transform_to_root_target);
    356   pass->has_transparent_background = input.has_transparent_background;
    357   Array<QuadPtr> quads(input.quad_list.size());
    358   Array<SharedQuadStatePtr> shared_quad_state(
    359       input.shared_quad_state_list.size());
    360   int sqs_i = -1;
    361   const cc::SharedQuadState* last_sqs = NULL;
    362   size_t i = 0;
    363   for (cc::QuadList::ConstIterator iter = input.quad_list.begin();
    364        iter != input.quad_list.end();
    365        ++iter) {
    366     const cc::DrawQuad& quad = *iter;
    367     quads[i] = Quad::From(quad);
    368     if (quad.shared_quad_state != last_sqs) {
    369       sqs_i++;
    370       shared_quad_state[sqs_i] =
    371           SharedQuadState::From(*input.shared_quad_state_list[sqs_i]);
    372       last_sqs = quad.shared_quad_state;
    373     }
    374     quads[i]->shared_quad_state_index = sqs_i;
    375     ++i;
    376   }
    377   // We should copy all shared quad states.
    378   DCHECK_EQ(static_cast<size_t>(sqs_i + 1), shared_quad_state.size());
    379   pass->quads = quads.Pass();
    380   pass->shared_quad_states = shared_quad_state.Pass();
    381   return pass.Pass();
    382 }
    383 
    384 // static
    385 scoped_ptr<cc::RenderPass>
    386 TypeConverter<scoped_ptr<cc::RenderPass>, PassPtr>::Convert(
    387     const PassPtr& input) {
    388   // TODO(weiliangc): RenderPass will have a constructor that takes in preset
    389   // size of quad list and shared quad state list size in upcoming CL.
    390   scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
    391   pass->SetAll(cc::RenderPassId(1, input->id),
    392                input->output_rect.To<gfx::Rect>(),
    393                input->damage_rect.To<gfx::Rect>(),
    394                input->transform_to_root_target.To<gfx::Transform>(),
    395                input->has_transparent_background);
    396   cc::SharedQuadStateList& sqs_list = pass->shared_quad_state_list;
    397   sqs_list.reserve(input->shared_quad_states.size());
    398   for (size_t i = 0; i < input->shared_quad_states.size(); ++i) {
    399     ConvertSharedQuadState(input->shared_quad_states[i], pass.get());
    400   }
    401   for (size_t i = 0; i < input->quads.size(); ++i) {
    402     QuadPtr quad = input->quads[i].Pass();
    403     if (!ConvertDrawQuad(
    404             quad, sqs_list[quad->shared_quad_state_index], pass.get()))
    405       return scoped_ptr<cc::RenderPass>();
    406   }
    407   return pass.Pass();
    408 }
    409 
    410 // static
    411 MailboxPtr TypeConverter<MailboxPtr, gpu::Mailbox>::Convert(
    412     const gpu::Mailbox& input) {
    413   Array<int8_t> name(64);
    414   for (int i = 0; i < 64; ++i) {
    415     name[i] = input.name[i];
    416   }
    417   MailboxPtr mailbox(Mailbox::New());
    418   mailbox->name = name.Pass();
    419   return mailbox.Pass();
    420 }
    421 
    422 // static
    423 gpu::Mailbox TypeConverter<gpu::Mailbox, MailboxPtr>::Convert(
    424     const MailboxPtr& input) {
    425   gpu::Mailbox mailbox;
    426   if (!input->name.is_null())
    427     mailbox.SetName(&input->name.storage()[0]);
    428   return mailbox;
    429 }
    430 
    431 // static
    432 MailboxHolderPtr TypeConverter<MailboxHolderPtr, gpu::MailboxHolder>::Convert(
    433     const gpu::MailboxHolder& input) {
    434   MailboxHolderPtr holder(MailboxHolder::New());
    435   holder->mailbox = Mailbox::From<gpu::Mailbox>(input.mailbox);
    436   holder->texture_target = input.texture_target;
    437   holder->sync_point = input.sync_point;
    438   return holder.Pass();
    439 }
    440 
    441 // static
    442 gpu::MailboxHolder TypeConverter<gpu::MailboxHolder, MailboxHolderPtr>::Convert(
    443     const MailboxHolderPtr& input) {
    444   gpu::MailboxHolder holder;
    445   holder.mailbox = input->mailbox.To<gpu::Mailbox>();
    446   holder.texture_target = input->texture_target;
    447   holder.sync_point = input->sync_point;
    448   return holder;
    449 }
    450 
    451 // static
    452 TransferableResourcePtr
    453 TypeConverter<TransferableResourcePtr, cc::TransferableResource>::Convert(
    454     const cc::TransferableResource& input) {
    455   TransferableResourcePtr transferable = TransferableResource::New();
    456   transferable->id = input.id;
    457   transferable->format = static_cast<ResourceFormat>(input.format);
    458   transferable->filter = input.filter;
    459   transferable->size = Size::From(input.size);
    460   transferable->mailbox_holder = MailboxHolder::From(input.mailbox_holder);
    461   transferable->is_repeated = input.is_repeated;
    462   transferable->is_software = input.is_software;
    463   return transferable.Pass();
    464 }
    465 
    466 // static
    467 cc::TransferableResource
    468 TypeConverter<cc::TransferableResource, TransferableResourcePtr>::Convert(
    469     const TransferableResourcePtr& input) {
    470   cc::TransferableResource transferable;
    471   transferable.id = input->id;
    472   transferable.format = static_cast<cc::ResourceFormat>(input->format);
    473   transferable.filter = input->filter;
    474   transferable.size = input->size.To<gfx::Size>();
    475   transferable.mailbox_holder = input->mailbox_holder.To<gpu::MailboxHolder>();
    476   transferable.is_repeated = input->is_repeated;
    477   transferable.is_software = input->is_software;
    478   return transferable;
    479 }
    480 
    481 // static
    482 Array<TransferableResourcePtr> TypeConverter<
    483     Array<TransferableResourcePtr>,
    484     cc::TransferableResourceArray>::Convert(const cc::TransferableResourceArray&
    485                                                 input) {
    486   Array<TransferableResourcePtr> resources(input.size());
    487   for (size_t i = 0; i < input.size(); ++i) {
    488     resources[i] = TransferableResource::From(input[i]);
    489   }
    490   return resources.Pass();
    491 }
    492 
    493 // static
    494 cc::TransferableResourceArray
    495 TypeConverter<cc::TransferableResourceArray, Array<TransferableResourcePtr> >::
    496     Convert(const Array<TransferableResourcePtr>& input) {
    497   cc::TransferableResourceArray resources(input.size());
    498   for (size_t i = 0; i < input.size(); ++i) {
    499     resources[i] = input[i].To<cc::TransferableResource>();
    500   }
    501   return resources;
    502 }
    503 
    504 // static
    505 ReturnedResourcePtr
    506 TypeConverter<ReturnedResourcePtr, cc::ReturnedResource>::Convert(
    507     const cc::ReturnedResource& input) {
    508   ReturnedResourcePtr returned = ReturnedResource::New();
    509   returned->id = input.id;
    510   returned->sync_point = input.sync_point;
    511   returned->count = input.count;
    512   returned->lost = input.lost;
    513   return returned.Pass();
    514 }
    515 
    516 // static
    517 cc::ReturnedResource
    518 TypeConverter<cc::ReturnedResource, ReturnedResourcePtr>::Convert(
    519     const ReturnedResourcePtr& input) {
    520   cc::ReturnedResource returned;
    521   returned.id = input->id;
    522   returned.sync_point = input->sync_point;
    523   returned.count = input->count;
    524   returned.lost = input->lost;
    525   return returned;
    526 }
    527 
    528 // static
    529 Array<ReturnedResourcePtr>
    530 TypeConverter<Array<ReturnedResourcePtr>, cc::ReturnedResourceArray>::Convert(
    531     const cc::ReturnedResourceArray& input) {
    532   Array<ReturnedResourcePtr> resources(input.size());
    533   for (size_t i = 0; i < input.size(); ++i) {
    534     resources[i] = ReturnedResource::From(input[i]);
    535   }
    536   return resources.Pass();
    537 }
    538 
    539 // static
    540 FramePtr TypeConverter<FramePtr, cc::CompositorFrame>::Convert(
    541     const cc::CompositorFrame& input) {
    542   FramePtr frame = Frame::New();
    543   DCHECK(input.delegated_frame_data);
    544   cc::DelegatedFrameData* frame_data = input.delegated_frame_data.get();
    545   frame->resources =
    546       Array<TransferableResourcePtr>::From(frame_data->resource_list);
    547   const cc::RenderPassList& pass_list = frame_data->render_pass_list;
    548   frame->passes = Array<PassPtr>::New(pass_list.size());
    549   for (size_t i = 0; i < pass_list.size(); ++i) {
    550     frame->passes[i] = Pass::From(*pass_list[i]);
    551   }
    552   return frame.Pass();
    553 }
    554 
    555 // static
    556 scoped_ptr<cc::CompositorFrame>
    557 TypeConverter<scoped_ptr<cc::CompositorFrame>, FramePtr>::Convert(
    558     const FramePtr& input) {
    559   scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
    560   frame_data->device_scale_factor = 1.f;
    561   frame_data->resource_list =
    562       input->resources.To<cc::TransferableResourceArray>();
    563   frame_data->render_pass_list.reserve(input->passes.size());
    564   for (size_t i = 0; i < input->passes.size(); ++i) {
    565     scoped_ptr<cc::RenderPass> pass =
    566         input->passes[i].To<scoped_ptr<cc::RenderPass> >();
    567     if (!pass)
    568       return scoped_ptr<cc::CompositorFrame>();
    569     frame_data->render_pass_list.push_back(pass.Pass());
    570   }
    571   scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
    572   frame->delegated_frame_data = frame_data.Pass();
    573   return frame.Pass();
    574 }
    575 
    576 }  // namespace mojo
    577