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