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.
5 #include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h"
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"
23 #define ASSERT_ENUM_VALUES_EQUAL(value) \
24 COMPILE_ASSERT(cc::DrawQuad::value == static_cast<cc::DrawQuad::Material>( \
26 value##_enum_value_matches)
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);
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);
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>(),
60 static_cast<::SkXfermode::Mode>(input->blend_mode),
61 input->sorting_context_id);
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(
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
90 case MATERIAL_SOLID_COLOR: {
91 if (input->solid_color_quad_state.is_null())
93 cc::SolidColorDrawQuad* color_quad =
94 render_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
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);
105 case MATERIAL_SURFACE_CONTENT: {
106 if (input->surface_quad_state.is_null())
108 cc::SurfaceDrawQuad* surface_quad =
109 render_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
110 surface_quad->SetAll(
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>());
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())
126 cc::TextureDrawQuad* texture_quad =
127 render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
128 texture_quad->SetAll(
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);
143 case MATERIAL_TILED_CONTENT: {
144 TileQuadStatePtr& tile_state = input->tile_quad_state;
145 if (tile_state.is_null())
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);
160 case MATERIAL_YUV_VIDEO_CONTENT: {
161 YUVVideoQuadStatePtr& yuv_state = input->yuv_video_quad_state;
162 if (yuv_state.is_null())
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));
181 NOTREACHED() << "Unsupported material " << input->material;
190 SurfaceIdPtr TypeConverter<SurfaceIdPtr, cc::SurfaceId>::Convert(
191 const cc::SurfaceId& input) {
192 SurfaceIdPtr id(SurfaceId::New());
198 cc::SurfaceId TypeConverter<cc::SurfaceId, SurfaceIdPtr>::Convert(
199 const SurfaceIdPtr& input) {
200 return cc::SurfaceId(input->id);
204 ColorPtr TypeConverter<ColorPtr, SkColor>::Convert(const SkColor& input) {
205 ColorPtr color(Color::New());
211 SkColor TypeConverter<SkColor, ColorPtr>::Convert(const ColorPtr& input) {
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();
225 cc::RenderPassId TypeConverter<cc::RenderPassId, RenderPassIdPtr>::Convert(
226 const RenderPassIdPtr& input) {
227 return cc::RenderPassId(input->layer_id, input->index);
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
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();
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();
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();
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];
293 texture_state->vertex_opacity = vertex_opacity.Pass();
294 texture_state->flipped = texture_quad->flipped;
295 quad->texture_quad_state = texture_state.Pass();
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();
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();
325 NOTREACHED() << "Unsupported material " << input.material;
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;
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());
361 const cc::SharedQuadState* last_sqs = NULL;
363 for (cc::QuadList::ConstIterator iter = input.quad_list.begin();
364 iter != input.quad_list.end();
366 const cc::DrawQuad& quad = *iter;
367 quads[i] = Quad::From(quad);
368 if (quad.shared_quad_state != last_sqs) {
370 shared_quad_state[sqs_i] =
371 SharedQuadState::From(*input.shared_quad_state_list[sqs_i]);
372 last_sqs = quad.shared_quad_state;
374 quads[i]->shared_quad_state_index = sqs_i;
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();
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());
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>();
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];
417 MailboxPtr mailbox(Mailbox::New());
418 mailbox->name = name.Pass();
419 return mailbox.Pass();
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]);
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();
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;
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();
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;
482 Array<TransferableResourcePtr> TypeConverter<
483 Array<TransferableResourcePtr>,
484 cc::TransferableResourceArray>::Convert(const cc::TransferableResourceArray&
486 Array<TransferableResourcePtr> resources(input.size());
487 for (size_t i = 0; i < input.size(); ++i) {
488 resources[i] = TransferableResource::From(input[i]);
490 return resources.Pass();
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>();
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();
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;
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]);
536 return resources.Pass();
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();
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]);
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> >();
568 return scoped_ptr<cc::CompositorFrame>();
569 frame_data->render_pass_list.push_back(pass.Pass());
571 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
572 frame->delegated_frame_data = frame_data.Pass();