- add sources.
[platform/framework/web/crosswalk.git] / src / content / common / cc_messages.cc
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 "base/command_line.h"
8 #include "cc/output/compositor_frame.h"
9 #include "cc/output/filter_operations.h"
10 #include "content/public/common/common_param_traits.h"
11 #include "content/public/common/content_switches.h"
12 #include "third_party/skia/include/core/SkData.h"
13 #include "third_party/skia/include/core/SkFlattenableSerialization.h"
14 #include "ui/gfx/transform.h"
15
16 namespace IPC {
17
18 void ParamTraits<cc::FilterOperation>::Write(
19     Message* m, const param_type& p) {
20   WriteParam(m, p.type());
21   switch (p.type()) {
22     case cc::FilterOperation::GRAYSCALE:
23     case cc::FilterOperation::SEPIA:
24     case cc::FilterOperation::SATURATE:
25     case cc::FilterOperation::HUE_ROTATE:
26     case cc::FilterOperation::INVERT:
27     case cc::FilterOperation::BRIGHTNESS:
28     case cc::FilterOperation::SATURATING_BRIGHTNESS:
29     case cc::FilterOperation::CONTRAST:
30     case cc::FilterOperation::OPACITY:
31     case cc::FilterOperation::BLUR:
32       WriteParam(m, p.amount());
33       break;
34     case cc::FilterOperation::DROP_SHADOW:
35       WriteParam(m, p.drop_shadow_offset());
36       WriteParam(m, p.amount());
37       WriteParam(m, p.drop_shadow_color());
38       break;
39     case cc::FilterOperation::COLOR_MATRIX:
40       for (int i = 0; i < 20; ++i)
41         WriteParam(m, p.matrix()[i]);
42       break;
43     case cc::FilterOperation::ZOOM:
44       WriteParam(m, p.amount());
45       WriteParam(m, p.zoom_inset());
46       break;
47     case cc::FilterOperation::REFERENCE:
48       WriteParam(m, p.image_filter());
49       break;
50   }
51 }
52
53 bool ParamTraits<cc::FilterOperation>::Read(
54     const Message* m, PickleIterator* iter, param_type* r) {
55   cc::FilterOperation::FilterType type;
56   float amount;
57   gfx::Point drop_shadow_offset;
58   SkColor drop_shadow_color;
59   SkScalar matrix[20];
60   int zoom_inset;
61
62   if (!ReadParam(m, iter, &type))
63     return false;
64   r->set_type(type);
65
66   bool success = false;
67   switch (type) {
68     case cc::FilterOperation::GRAYSCALE:
69     case cc::FilterOperation::SEPIA:
70     case cc::FilterOperation::SATURATE:
71     case cc::FilterOperation::HUE_ROTATE:
72     case cc::FilterOperation::INVERT:
73     case cc::FilterOperation::BRIGHTNESS:
74     case cc::FilterOperation::SATURATING_BRIGHTNESS:
75     case cc::FilterOperation::CONTRAST:
76     case cc::FilterOperation::OPACITY:
77     case cc::FilterOperation::BLUR:
78       if (ReadParam(m, iter, &amount)) {
79         r->set_amount(amount);
80         success = true;
81       }
82       break;
83     case cc::FilterOperation::DROP_SHADOW:
84       if (ReadParam(m, iter, &drop_shadow_offset) &&
85           ReadParam(m, iter, &amount) &&
86           ReadParam(m, iter, &drop_shadow_color)) {
87         r->set_drop_shadow_offset(drop_shadow_offset);
88         r->set_amount(amount);
89         r->set_drop_shadow_color(drop_shadow_color);
90         success = true;
91       }
92       break;
93     case cc::FilterOperation::COLOR_MATRIX: {
94       int i;
95       for (i = 0; i < 20; ++i) {
96         if (!ReadParam(m, iter, &matrix[i]))
97           break;
98       }
99       if (i == 20) {
100         r->set_matrix(matrix);
101         success = true;
102       }
103       break;
104     }
105     case cc::FilterOperation::ZOOM:
106       if (ReadParam(m, iter, &amount) &&
107           ReadParam(m, iter, &zoom_inset) &&
108           amount >= 0.f &&
109           zoom_inset >= 0) {
110         r->set_amount(amount);
111         r->set_zoom_inset(zoom_inset);
112         success = true;
113       }
114       break;
115     case cc::FilterOperation::REFERENCE: {
116       skia::RefPtr<SkImageFilter> filter;
117       if (!ReadParam(m, iter, &filter)) {
118         success = false;
119         break;
120       }
121       r->set_image_filter(filter);
122       success = true;
123       break;
124     }
125   }
126   return success;
127 }
128
129 void ParamTraits<cc::FilterOperation>::Log(
130     const param_type& p, std::string* l) {
131   l->append("(");
132   LogParam(static_cast<unsigned>(p.type()), l);
133   l->append(", ");
134
135   switch (p.type()) {
136     case cc::FilterOperation::GRAYSCALE:
137     case cc::FilterOperation::SEPIA:
138     case cc::FilterOperation::SATURATE:
139     case cc::FilterOperation::HUE_ROTATE:
140     case cc::FilterOperation::INVERT:
141     case cc::FilterOperation::BRIGHTNESS:
142     case cc::FilterOperation::SATURATING_BRIGHTNESS:
143     case cc::FilterOperation::CONTRAST:
144     case cc::FilterOperation::OPACITY:
145     case cc::FilterOperation::BLUR:
146       LogParam(p.amount(), l);
147       break;
148     case cc::FilterOperation::DROP_SHADOW:
149       LogParam(p.drop_shadow_offset(), l);
150       l->append(", ");
151       LogParam(p.amount(), l);
152       l->append(", ");
153       LogParam(p.drop_shadow_color(), l);
154       break;
155     case cc::FilterOperation::COLOR_MATRIX:
156       for (int i = 0; i < 20; ++i) {
157         if (i)
158           l->append(", ");
159         LogParam(p.matrix()[i], l);
160       }
161       break;
162     case cc::FilterOperation::ZOOM:
163       LogParam(p.amount(), l);
164       l->append(", ");
165       LogParam(p.zoom_inset(), l);
166       break;
167     case cc::FilterOperation::REFERENCE:
168       LogParam(p.image_filter(), l);
169       break;
170   }
171   l->append(")");
172 }
173
174 void ParamTraits<cc::FilterOperations>::Write(
175     Message* m, const param_type& p) {
176   WriteParam(m, p.size());
177   for (std::size_t i = 0; i < p.size(); ++i) {
178     WriteParam(m, p.at(i));
179   }
180 }
181
182 bool ParamTraits<cc::FilterOperations>::Read(
183     const Message* m, PickleIterator* iter, param_type* r) {
184   size_t count;
185   if (!ReadParam(m, iter, &count))
186     return false;
187
188   for (std::size_t i = 0; i < count; ++i) {
189     cc::FilterOperation op = cc::FilterOperation::CreateEmptyFilter();
190     if (!ReadParam(m, iter, &op))
191       return false;
192     r->Append(op);
193   }
194   return true;
195 }
196
197 void ParamTraits<cc::FilterOperations>::Log(
198     const param_type& p, std::string* l) {
199   l->append("(");
200   for (std::size_t i = 0; i < p.size(); ++i) {
201     if (i)
202       l->append(", ");
203     LogParam(p.at(i), l);
204   }
205   l->append(")");
206 }
207
208 void ParamTraits<skia::RefPtr<SkImageFilter> >::Write(
209     Message* m, const param_type& p) {
210   SkImageFilter* filter = p.get();
211   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
212   if (filter && command_line.HasSwitch(switches::kAllowFiltersOverIPC)) {
213     skia::RefPtr<SkData> data = skia::AdoptRef(SkSerializeFlattenable(filter));
214     m->WriteData(static_cast<const char*>(data->data()), data->size());
215   } else {
216     m->WriteData(0, 0);
217   }
218 }
219
220 bool ParamTraits<skia::RefPtr<SkImageFilter> >::Read(
221     const Message* m, PickleIterator* iter, param_type* r) {
222   const char* data = 0;
223   int length = 0;
224   if (!m->ReadData(iter, &data, &length))
225     return false;
226   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
227   if ((length > 0) && command_line.HasSwitch(switches::kAllowFiltersOverIPC)) {
228     SkFlattenable* flattenable = SkDeserializeFlattenable(data, length);
229     *r = skia::AdoptRef(static_cast<SkImageFilter*>(flattenable));
230   } else {
231     r->clear();
232   }
233   return true;
234 }
235
236 void ParamTraits<skia::RefPtr<SkImageFilter> >::Log(
237     const param_type& p, std::string* l) {
238   l->append("(");
239   LogParam(p.get() ? p->countInputs() : 0, l);
240   l->append(")");
241 }
242
243 void ParamTraits<gfx::Transform>::Write(
244     Message* m, const param_type& p) {
245 #ifdef SK_MSCALAR_IS_FLOAT
246   float column_major_data[16];
247   p.matrix().asColMajorf(column_major_data);
248 #else
249   double column_major_data[16];
250   p.matrix().asColMajord(column_major_data);
251 #endif
252   m->WriteBytes(&column_major_data, sizeof(SkMScalar) * 16);
253 }
254
255 bool ParamTraits<gfx::Transform>::Read(
256     const Message* m, PickleIterator* iter, param_type* r) {
257   const char* column_major_data;
258   if (!m->ReadBytes(iter, &column_major_data, sizeof(SkMScalar) * 16))
259     return false;
260   r->matrix().setColMajor(
261       reinterpret_cast<const SkMScalar*>(column_major_data));
262   return true;
263 }
264
265 void ParamTraits<gfx::Transform>::Log(
266     const param_type& p, std::string* l) {
267 #ifdef SK_MSCALAR_IS_FLOAT
268   float row_major_data[16];
269   p.matrix().asRowMajorf(row_major_data);
270 #else
271   double row_major_data[16];
272   p.matrix().asRowMajord(row_major_data);
273 #endif
274   l->append("(");
275   for (int i = 0; i < 16; ++i) {
276     if (i > 0)
277       l->append(", ");
278     LogParam(row_major_data[i], l);
279   }
280   l->append(") ");
281 }
282
283 void ParamTraits<cc::RenderPass>::Write(
284     Message* m, const param_type& p) {
285   WriteParam(m, p.id);
286   WriteParam(m, p.output_rect);
287   WriteParam(m, p.damage_rect);
288   WriteParam(m, p.transform_to_root_target);
289   WriteParam(m, p.has_transparent_background);
290   WriteParam(m, p.shared_quad_state_list.size());
291   WriteParam(m, p.quad_list.size());
292
293   for (size_t i = 0; i < p.shared_quad_state_list.size(); ++i)
294     WriteParam(m, *p.shared_quad_state_list[i]);
295
296   size_t shared_quad_state_index = 0;
297   for (size_t i = 0; i < p.quad_list.size(); ++i) {
298     const cc::DrawQuad* quad = p.quad_list[i];
299     DCHECK(quad->rect.Contains(quad->visible_rect))
300         << quad->material << " rect: " << quad->rect.ToString()
301         << " visible_rect: " << quad->visible_rect.ToString();
302     DCHECK(quad->opaque_rect.IsEmpty() ||
303            quad->rect.Contains(quad->opaque_rect))
304         << quad->material << " rect: " << quad->rect.ToString()
305         << " opaque_rect: " << quad->opaque_rect.ToString();
306
307     switch (quad->material) {
308       case cc::DrawQuad::CHECKERBOARD:
309         WriteParam(m, *cc::CheckerboardDrawQuad::MaterialCast(quad));
310         break;
311       case cc::DrawQuad::DEBUG_BORDER:
312         WriteParam(m, *cc::DebugBorderDrawQuad::MaterialCast(quad));
313         break;
314       case cc::DrawQuad::IO_SURFACE_CONTENT:
315         WriteParam(m, *cc::IOSurfaceDrawQuad::MaterialCast(quad));
316         break;
317       case cc::DrawQuad::PICTURE_CONTENT:
318         NOTREACHED();
319         break;
320       case cc::DrawQuad::TEXTURE_CONTENT:
321         WriteParam(m, *cc::TextureDrawQuad::MaterialCast(quad));
322         break;
323       case cc::DrawQuad::RENDER_PASS:
324         WriteParam(m, *cc::RenderPassDrawQuad::MaterialCast(quad));
325         break;
326       case cc::DrawQuad::SOLID_COLOR:
327         WriteParam(m, *cc::SolidColorDrawQuad::MaterialCast(quad));
328         break;
329       case cc::DrawQuad::TILED_CONTENT:
330         WriteParam(m, *cc::TileDrawQuad::MaterialCast(quad));
331         break;
332       case cc::DrawQuad::STREAM_VIDEO_CONTENT:
333         WriteParam(m, *cc::StreamVideoDrawQuad::MaterialCast(quad));
334         break;
335       case cc::DrawQuad::YUV_VIDEO_CONTENT:
336         WriteParam(m, *cc::YUVVideoDrawQuad::MaterialCast(quad));
337         break;
338       case cc::DrawQuad::INVALID:
339         break;
340     }
341
342     const cc::ScopedPtrVector<cc::SharedQuadState>& sqs_list =
343         p.shared_quad_state_list;
344
345     // This is an invalid index.
346     size_t bad_index = sqs_list.size();
347
348     // Null shared quad states should not occur.
349     DCHECK(quad->shared_quad_state);
350     if (!quad->shared_quad_state) {
351       WriteParam(m, bad_index);
352       continue;
353     }
354
355     // SharedQuadStates should appear in the order they are used by DrawQuads.
356     // Find the SharedQuadState for this DrawQuad.
357     while (shared_quad_state_index < sqs_list.size() &&
358            quad->shared_quad_state != sqs_list[shared_quad_state_index])
359       ++shared_quad_state_index;
360
361     DCHECK_LT(shared_quad_state_index, sqs_list.size());
362     if (shared_quad_state_index >= sqs_list.size()) {
363       WriteParam(m, bad_index);
364       continue;
365     }
366
367     DCHECK_LT(shared_quad_state_index, p.shared_quad_state_list.size());
368     WriteParam(m, shared_quad_state_index);
369   }
370 }
371
372 static size_t ReserveSizeForRenderPassWrite(const cc::RenderPass& p) {
373   size_t to_reserve = sizeof(cc::RenderPass);
374
375   to_reserve += p.shared_quad_state_list.size() * sizeof(cc::SharedQuadState);
376
377   // The shared_quad_state_index for each quad.
378   to_reserve += p.quad_list.size() * sizeof(size_t);
379
380   // The largest quad type, verified by a unit test.
381   to_reserve += p.quad_list.size() * sizeof(cc::RenderPassDrawQuad);
382   return to_reserve;
383 }
384
385 template<typename QuadType>
386 static scoped_ptr<cc::DrawQuad> ReadDrawQuad(const Message* m,
387                                              PickleIterator* iter) {
388   scoped_ptr<QuadType> quad = QuadType::Create();
389   if (!ReadParam(m, iter, quad.get()))
390     return scoped_ptr<QuadType>().template PassAs<cc::DrawQuad>();
391   return quad.template PassAs<cc::DrawQuad>();
392 }
393
394 bool ParamTraits<cc::RenderPass>::Read(
395     const Message* m, PickleIterator* iter, param_type* p) {
396   cc::RenderPass::Id id(-1, -1);
397   gfx::Rect output_rect;
398   gfx::RectF damage_rect;
399   gfx::Transform transform_to_root_target;
400   bool has_transparent_background;
401   size_t shared_quad_state_list_size;
402   size_t quad_list_size;
403
404   if (!ReadParam(m, iter, &id) ||
405       !ReadParam(m, iter, &output_rect) ||
406       !ReadParam(m, iter, &damage_rect) ||
407       !ReadParam(m, iter, &transform_to_root_target) ||
408       !ReadParam(m, iter, &has_transparent_background) ||
409       !ReadParam(m, iter, &shared_quad_state_list_size) ||
410       !ReadParam(m, iter, &quad_list_size))
411     return false;
412
413   p->SetAll(id,
414             output_rect,
415             damage_rect,
416             transform_to_root_target,
417             has_transparent_background);
418
419   for (size_t i = 0; i < shared_quad_state_list_size; ++i) {
420     scoped_ptr<cc::SharedQuadState> state(cc::SharedQuadState::Create());
421     if (!ReadParam(m, iter, state.get()))
422       return false;
423     p->shared_quad_state_list.push_back(state.Pass());
424   }
425
426   size_t last_shared_quad_state_index = 0;
427   for (size_t i = 0; i < quad_list_size; ++i) {
428     cc::DrawQuad::Material material;
429     PickleIterator temp_iter = *iter;
430     if (!ReadParam(m, &temp_iter, &material))
431       return false;
432
433     scoped_ptr<cc::DrawQuad> draw_quad;
434     switch (material) {
435       case cc::DrawQuad::CHECKERBOARD:
436         draw_quad = ReadDrawQuad<cc::CheckerboardDrawQuad>(m, iter);
437         break;
438       case cc::DrawQuad::DEBUG_BORDER:
439         draw_quad = ReadDrawQuad<cc::DebugBorderDrawQuad>(m, iter);
440         break;
441       case cc::DrawQuad::IO_SURFACE_CONTENT:
442         draw_quad = ReadDrawQuad<cc::IOSurfaceDrawQuad>(m, iter);
443         break;
444       case cc::DrawQuad::PICTURE_CONTENT:
445         NOTREACHED();
446         return false;
447       case cc::DrawQuad::TEXTURE_CONTENT:
448         draw_quad = ReadDrawQuad<cc::TextureDrawQuad>(m, iter);
449         break;
450       case cc::DrawQuad::RENDER_PASS:
451         draw_quad = ReadDrawQuad<cc::RenderPassDrawQuad>(m, iter);
452         break;
453       case cc::DrawQuad::SOLID_COLOR:
454         draw_quad = ReadDrawQuad<cc::SolidColorDrawQuad>(m, iter);
455         break;
456       case cc::DrawQuad::TILED_CONTENT:
457         draw_quad = ReadDrawQuad<cc::TileDrawQuad>(m, iter);
458         break;
459       case cc::DrawQuad::STREAM_VIDEO_CONTENT:
460         draw_quad = ReadDrawQuad<cc::StreamVideoDrawQuad>(m, iter);
461         break;
462       case cc::DrawQuad::YUV_VIDEO_CONTENT:
463         draw_quad = ReadDrawQuad<cc::YUVVideoDrawQuad>(m, iter);
464         break;
465       case cc::DrawQuad::INVALID:
466         break;
467     }
468     if (!draw_quad)
469       return false;
470     if (!draw_quad->rect.Contains(draw_quad->visible_rect)) {
471       LOG(ERROR) << "Quad with invalid visible rect " << draw_quad->material
472                  << " rect: " << draw_quad->rect.ToString()
473                  << " visible_rect: " << draw_quad->visible_rect.ToString();
474       return false;
475     }
476     if (!draw_quad->opaque_rect.IsEmpty() &&
477         !draw_quad->rect.Contains(draw_quad->opaque_rect)) {
478       LOG(ERROR) << "Quad with invalid opaque rect " << draw_quad->material
479                  << " rect: " << draw_quad->rect.ToString()
480                  << " opaque_rect: " << draw_quad->opaque_rect.ToString();
481       return false;
482     }
483
484     size_t shared_quad_state_index;
485     if (!ReadParam(m, iter, &shared_quad_state_index) ||
486         shared_quad_state_index >= p->shared_quad_state_list.size())
487       return false;
488     // SharedQuadState indexes should be in ascending order.
489     if (shared_quad_state_index < last_shared_quad_state_index)
490       return false;
491     last_shared_quad_state_index = shared_quad_state_index;
492
493     draw_quad->shared_quad_state =
494         p->shared_quad_state_list[shared_quad_state_index];
495
496     p->quad_list.push_back(draw_quad.Pass());
497   }
498
499   return true;
500 }
501
502 void ParamTraits<cc::RenderPass>::Log(
503     const param_type& p, std::string* l) {
504   l->append("RenderPass((");
505   LogParam(p.id, l);
506   l->append("), ");
507   LogParam(p.output_rect, l);
508   l->append(", ");
509   LogParam(p.damage_rect, l);
510   l->append(", ");
511   LogParam(p.transform_to_root_target, l);
512   l->append(", ");
513   LogParam(p.has_transparent_background, l);
514   l->append(", ");
515
516   l->append("[");
517   for (size_t i = 0; i < p.shared_quad_state_list.size(); ++i) {
518     if (i)
519       l->append(", ");
520     LogParam(*p.shared_quad_state_list[i], l);
521   }
522   l->append("], [");
523   for (size_t i = 0; i < p.quad_list.size(); ++i) {
524     if (i)
525       l->append(", ");
526     const cc::DrawQuad* quad = p.quad_list[i];
527     switch (quad->material) {
528       case cc::DrawQuad::CHECKERBOARD:
529         LogParam(*cc::CheckerboardDrawQuad::MaterialCast(quad), l);
530         break;
531       case cc::DrawQuad::DEBUG_BORDER:
532         LogParam(*cc::DebugBorderDrawQuad::MaterialCast(quad), l);
533         break;
534       case cc::DrawQuad::IO_SURFACE_CONTENT:
535         LogParam(*cc::IOSurfaceDrawQuad::MaterialCast(quad), l);
536         break;
537       case cc::DrawQuad::PICTURE_CONTENT:
538         NOTREACHED();
539         break;
540       case cc::DrawQuad::TEXTURE_CONTENT:
541         LogParam(*cc::TextureDrawQuad::MaterialCast(quad), l);
542         break;
543       case cc::DrawQuad::RENDER_PASS:
544         LogParam(*cc::RenderPassDrawQuad::MaterialCast(quad), l);
545         break;
546       case cc::DrawQuad::SOLID_COLOR:
547         LogParam(*cc::SolidColorDrawQuad::MaterialCast(quad), l);
548         break;
549       case cc::DrawQuad::TILED_CONTENT:
550         LogParam(*cc::TileDrawQuad::MaterialCast(quad), l);
551         break;
552       case cc::DrawQuad::STREAM_VIDEO_CONTENT:
553         LogParam(*cc::StreamVideoDrawQuad::MaterialCast(quad), l);
554         break;
555       case cc::DrawQuad::YUV_VIDEO_CONTENT:
556         LogParam(*cc::YUVVideoDrawQuad::MaterialCast(quad), l);
557         break;
558       case cc::DrawQuad::INVALID:
559         break;
560     }
561   }
562   l->append("])");
563 }
564
565 namespace {
566   enum CompositorFrameType {
567     NO_FRAME,
568     DELEGATED_FRAME,
569     GL_FRAME,
570     SOFTWARE_FRAME,
571   };
572 }
573
574 void ParamTraits<cc::CompositorFrame>::Write(Message* m,
575                                              const param_type& p) {
576   WriteParam(m, p.metadata);
577   if (p.delegated_frame_data) {
578     DCHECK(!p.gl_frame_data);
579     DCHECK(!p.software_frame_data);
580     WriteParam(m, static_cast<int>(DELEGATED_FRAME));
581     WriteParam(m, *p.delegated_frame_data);
582   } else if (p.gl_frame_data) {
583     DCHECK(!p.software_frame_data);
584     WriteParam(m, static_cast<int>(GL_FRAME));
585     WriteParam(m, *p.gl_frame_data);
586   } else if (p.software_frame_data) {
587     WriteParam(m, static_cast<int>(SOFTWARE_FRAME));
588     WriteParam(m, *p.software_frame_data);
589   } else {
590     WriteParam(m, static_cast<int>(NO_FRAME));
591   }
592 }
593
594 bool ParamTraits<cc::CompositorFrame>::Read(const Message* m,
595                                             PickleIterator* iter,
596                                             param_type* p) {
597   if (!ReadParam(m, iter, &p->metadata))
598     return false;
599
600   int compositor_frame_type;
601   if (!ReadParam(m, iter, &compositor_frame_type))
602     return false;
603
604   switch (compositor_frame_type) {
605     case DELEGATED_FRAME:
606       p->delegated_frame_data.reset(new cc::DelegatedFrameData());
607       if (!ReadParam(m, iter, p->delegated_frame_data.get()))
608         return false;
609       break;
610     case GL_FRAME:
611       p->gl_frame_data.reset(new cc::GLFrameData());
612       if (!ReadParam(m, iter, p->gl_frame_data.get()))
613         return false;
614       break;
615     case SOFTWARE_FRAME:
616       p->software_frame_data.reset(new cc::SoftwareFrameData());
617       if (!ReadParam(m, iter, p->software_frame_data.get()))
618         return false;
619       break;
620     case NO_FRAME:
621       break;
622     default:
623       return false;
624   }
625   return true;
626 }
627
628 void ParamTraits<cc::CompositorFrame>::Log(const param_type& p,
629                                            std::string* l) {
630   l->append("CompositorFrame(");
631   LogParam(p.metadata, l);
632   l->append(", ");
633   if (p.delegated_frame_data)
634     LogParam(*p.delegated_frame_data, l);
635   else if (p.gl_frame_data)
636     LogParam(*p.gl_frame_data, l);
637   else if (p.software_frame_data)
638     LogParam(*p.software_frame_data, l);
639   l->append(")");
640 }
641
642 void ParamTraits<cc::CompositorFrameAck>::Write(Message* m,
643                                                 const param_type& p) {
644   WriteParam(m, p.resources);
645   WriteParam(m, p.last_software_frame_id);
646   if (p.gl_frame_data) {
647     WriteParam(m, static_cast<int>(GL_FRAME));
648     WriteParam(m, *p.gl_frame_data);
649   } else {
650     WriteParam(m, static_cast<int>(NO_FRAME));
651   }
652 }
653
654 bool ParamTraits<cc::CompositorFrameAck>::Read(const Message* m,
655                                                PickleIterator* iter,
656                                                param_type* p) {
657   if (!ReadParam(m, iter, &p->resources))
658     return false;
659
660   if (!ReadParam(m, iter, &p->last_software_frame_id))
661     return false;
662
663   int compositor_frame_type;
664   if (!ReadParam(m, iter, &compositor_frame_type))
665     return false;
666
667   switch (compositor_frame_type) {
668     case NO_FRAME:
669       break;
670     case GL_FRAME:
671       p->gl_frame_data.reset(new cc::GLFrameData());
672       if (!ReadParam(m, iter, p->gl_frame_data.get()))
673         return false;
674       break;
675     default:
676       return false;
677   }
678   return true;
679 }
680
681 void ParamTraits<cc::CompositorFrameAck>::Log(const param_type& p,
682                                               std::string* l) {
683   l->append("CompositorFrameAck(");
684   LogParam(p.resources, l);
685   l->append(", ");
686   LogParam(p.last_software_frame_id, l);
687   l->append(", ");
688   if (p.gl_frame_data)
689     LogParam(*p.gl_frame_data, l);
690   l->append(")");
691 }
692
693 void ParamTraits<cc::DelegatedFrameData>::Write(Message* m,
694                                                 const param_type& p) {
695   DCHECK_NE(0u, p.render_pass_list.size());
696
697   size_t to_reserve = p.resource_list.size() * sizeof(cc::TransferableResource);
698   for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
699     const cc::RenderPass* pass = p.render_pass_list[i];
700     to_reserve += ReserveSizeForRenderPassWrite(*pass);
701   }
702   m->Reserve(to_reserve);
703
704   WriteParam(m, p.resource_list);
705   WriteParam(m, p.render_pass_list.size());
706   for (size_t i = 0; i < p.render_pass_list.size(); ++i)
707     WriteParam(m, *p.render_pass_list[i]);
708 }
709
710 bool ParamTraits<cc::DelegatedFrameData>::Read(const Message* m,
711                                                PickleIterator* iter,
712                                                param_type* p) {
713   const static size_t kMaxRenderPasses = 10000;
714
715   size_t num_render_passes;
716   if (!ReadParam(m, iter, &p->resource_list) ||
717       !ReadParam(m, iter, &num_render_passes) ||
718       num_render_passes > kMaxRenderPasses || num_render_passes == 0)
719     return false;
720   for (size_t i = 0; i < num_render_passes; ++i) {
721     scoped_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
722     if (!ReadParam(m, iter, render_pass.get()))
723       return false;
724     p->render_pass_list.push_back(render_pass.Pass());
725   }
726   return true;
727 }
728
729 void ParamTraits<cc::DelegatedFrameData>::Log(const param_type& p,
730                                               std::string* l) {
731   l->append("DelegatedFrameData(");
732   LogParam(p.resource_list, l);
733   l->append(", [");
734   for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
735     if (i)
736       l->append(", ");
737     LogParam(*p.render_pass_list[i], l);
738   }
739   l->append("])");
740 }
741
742 }  // namespace IPC