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