• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Write(Message * m,const param_type & p)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 
Read(const Message * m,PickleIterator * iter,param_type * r)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 
Log(const param_type & p,std::string * l)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 
Write(Message * m,const param_type & p)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 
Read(const Message * m,PickleIterator * iter,param_type * r)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 
Log(const param_type & p,std::string * l)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 
Write(Message * m,const param_type & p)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::kDisableFiltersOverIPC)) {
213     skia::RefPtr<SkData> data =
214         skia::AdoptRef(SkValidatingSerializeFlattenable(filter));
215     m->WriteData(static_cast<const char*>(data->data()), data->size());
216   } else {
217     m->WriteData(0, 0);
218   }
219 }
220 
Read(const Message * m,PickleIterator * iter,param_type * r)221 bool ParamTraits<skia::RefPtr<SkImageFilter> >::Read(
222     const Message* m, PickleIterator* iter, param_type* r) {
223   const char* data = 0;
224   int length = 0;
225   if (!m->ReadData(iter, &data, &length))
226     return false;
227   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
228   if ((length > 0) &&
229       !command_line.HasSwitch(switches::kDisableFiltersOverIPC)) {
230     SkFlattenable* flattenable = SkValidatingDeserializeFlattenable(
231         data, length, SkImageFilter::GetFlattenableType());
232     *r = skia::AdoptRef(static_cast<SkImageFilter*>(flattenable));
233   } else {
234     r->clear();
235   }
236   return true;
237 }
238 
Log(const param_type & p,std::string * l)239 void ParamTraits<skia::RefPtr<SkImageFilter> >::Log(
240     const param_type& p, std::string* l) {
241   l->append("(");
242   LogParam(p.get() ? p->countInputs() : 0, l);
243   l->append(")");
244 }
245 
Write(Message * m,const param_type & p)246 void ParamTraits<gfx::Transform>::Write(
247     Message* m, const param_type& p) {
248 #ifdef SK_MSCALAR_IS_FLOAT
249   float column_major_data[16];
250   p.matrix().asColMajorf(column_major_data);
251 #else
252   double column_major_data[16];
253   p.matrix().asColMajord(column_major_data);
254 #endif
255   m->WriteBytes(&column_major_data, sizeof(SkMScalar) * 16);
256 }
257 
Read(const Message * m,PickleIterator * iter,param_type * r)258 bool ParamTraits<gfx::Transform>::Read(
259     const Message* m, PickleIterator* iter, param_type* r) {
260   const char* column_major_data;
261   if (!m->ReadBytes(iter, &column_major_data, sizeof(SkMScalar) * 16))
262     return false;
263   r->matrix().setColMajor(
264       reinterpret_cast<const SkMScalar*>(column_major_data));
265   return true;
266 }
267 
Log(const param_type & p,std::string * l)268 void ParamTraits<gfx::Transform>::Log(
269     const param_type& p, std::string* l) {
270 #ifdef SK_MSCALAR_IS_FLOAT
271   float row_major_data[16];
272   p.matrix().asRowMajorf(row_major_data);
273 #else
274   double row_major_data[16];
275   p.matrix().asRowMajord(row_major_data);
276 #endif
277   l->append("(");
278   for (int i = 0; i < 16; ++i) {
279     if (i > 0)
280       l->append(", ");
281     LogParam(row_major_data[i], l);
282   }
283   l->append(") ");
284 }
285 
Write(Message * m,const param_type & p)286 void ParamTraits<cc::RenderPass>::Write(
287     Message* m, const param_type& p) {
288   WriteParam(m, p.id);
289   WriteParam(m, p.output_rect);
290   WriteParam(m, p.damage_rect);
291   WriteParam(m, p.transform_to_root_target);
292   WriteParam(m, p.has_transparent_background);
293   WriteParam(m, p.shared_quad_state_list.size());
294   WriteParam(m, p.quad_list.size());
295 
296   size_t shared_quad_state_index = 0;
297   size_t last_shared_quad_state_index = kuint32max;
298   for (size_t i = 0; i < p.quad_list.size(); ++i) {
299     const cc::DrawQuad* quad = p.quad_list[i];
300     DCHECK(quad->rect.Contains(quad->visible_rect))
301         << quad->material << " rect: " << quad->rect.ToString()
302         << " visible_rect: " << quad->visible_rect.ToString();
303     DCHECK(quad->opaque_rect.IsEmpty() ||
304            quad->rect.Contains(quad->opaque_rect))
305         << quad->material << " rect: " << quad->rect.ToString()
306         << " opaque_rect: " << quad->opaque_rect.ToString();
307 
308     switch (quad->material) {
309       case cc::DrawQuad::CHECKERBOARD:
310         WriteParam(m, *cc::CheckerboardDrawQuad::MaterialCast(quad));
311         break;
312       case cc::DrawQuad::DEBUG_BORDER:
313         WriteParam(m, *cc::DebugBorderDrawQuad::MaterialCast(quad));
314         break;
315       case cc::DrawQuad::IO_SURFACE_CONTENT:
316         WriteParam(m, *cc::IOSurfaceDrawQuad::MaterialCast(quad));
317         break;
318       case cc::DrawQuad::PICTURE_CONTENT:
319         NOTREACHED();
320         break;
321       case cc::DrawQuad::TEXTURE_CONTENT:
322         WriteParam(m, *cc::TextureDrawQuad::MaterialCast(quad));
323         break;
324       case cc::DrawQuad::RENDER_PASS:
325         WriteParam(m, *cc::RenderPassDrawQuad::MaterialCast(quad));
326         break;
327       case cc::DrawQuad::SOLID_COLOR:
328         WriteParam(m, *cc::SolidColorDrawQuad::MaterialCast(quad));
329         break;
330       case cc::DrawQuad::TILED_CONTENT:
331         WriteParam(m, *cc::TileDrawQuad::MaterialCast(quad));
332         break;
333       case cc::DrawQuad::STREAM_VIDEO_CONTENT:
334         WriteParam(m, *cc::StreamVideoDrawQuad::MaterialCast(quad));
335         break;
336       case cc::DrawQuad::YUV_VIDEO_CONTENT:
337         WriteParam(m, *cc::YUVVideoDrawQuad::MaterialCast(quad));
338         break;
339       case cc::DrawQuad::INVALID:
340         break;
341     }
342 
343     const cc::ScopedPtrVector<cc::SharedQuadState>& sqs_list =
344         p.shared_quad_state_list;
345 
346     // This is an invalid index.
347     size_t bad_index = sqs_list.size();
348 
349     // Null shared quad states should not occur.
350     DCHECK(quad->shared_quad_state);
351     if (!quad->shared_quad_state) {
352       WriteParam(m, bad_index);
353       continue;
354     }
355 
356     // SharedQuadStates should appear in the order they are used by DrawQuads.
357     // Find the SharedQuadState for this DrawQuad.
358     while (shared_quad_state_index < sqs_list.size() &&
359            quad->shared_quad_state != sqs_list[shared_quad_state_index])
360       ++shared_quad_state_index;
361 
362     DCHECK_LT(shared_quad_state_index, sqs_list.size());
363     if (shared_quad_state_index >= sqs_list.size()) {
364       WriteParam(m, bad_index);
365       continue;
366     }
367 
368     WriteParam(m, shared_quad_state_index);
369     if (shared_quad_state_index != last_shared_quad_state_index) {
370       WriteParam(m, *sqs_list[shared_quad_state_index]);
371       last_shared_quad_state_index = shared_quad_state_index;
372     }
373   }
374 }
375 
ReserveSizeForRenderPassWrite(const cc::RenderPass & p)376 static size_t ReserveSizeForRenderPassWrite(const cc::RenderPass& p) {
377   size_t to_reserve = sizeof(cc::RenderPass);
378 
379   to_reserve += p.shared_quad_state_list.size() * sizeof(cc::SharedQuadState);
380 
381   // The shared_quad_state_index for each quad.
382   to_reserve += p.quad_list.size() * sizeof(size_t);
383 
384   // The largest quad type, verified by a unit test.
385   to_reserve += p.quad_list.size() * sizeof(cc::RenderPassDrawQuad);
386   return to_reserve;
387 }
388 
389 template<typename QuadType>
ReadDrawQuad(const Message * m,PickleIterator * iter)390 static scoped_ptr<cc::DrawQuad> ReadDrawQuad(const Message* m,
391                                              PickleIterator* iter) {
392   scoped_ptr<QuadType> quad = QuadType::Create();
393   if (!ReadParam(m, iter, quad.get()))
394     return scoped_ptr<QuadType>().template PassAs<cc::DrawQuad>();
395   return quad.template PassAs<cc::DrawQuad>();
396 }
397 
Read(const Message * m,PickleIterator * iter,param_type * p)398 bool ParamTraits<cc::RenderPass>::Read(
399     const Message* m, PickleIterator* iter, param_type* p) {
400   cc::RenderPass::Id id(-1, -1);
401   gfx::Rect output_rect;
402   gfx::RectF damage_rect;
403   gfx::Transform transform_to_root_target;
404   bool has_transparent_background;
405   size_t shared_quad_state_list_size;
406   size_t quad_list_size;
407 
408   if (!ReadParam(m, iter, &id) ||
409       !ReadParam(m, iter, &output_rect) ||
410       !ReadParam(m, iter, &damage_rect) ||
411       !ReadParam(m, iter, &transform_to_root_target) ||
412       !ReadParam(m, iter, &has_transparent_background) ||
413       !ReadParam(m, iter, &shared_quad_state_list_size) ||
414       !ReadParam(m, iter, &quad_list_size))
415     return false;
416 
417   p->SetAll(id,
418             output_rect,
419             damage_rect,
420             transform_to_root_target,
421             has_transparent_background);
422 
423   size_t last_shared_quad_state_index = kuint32max;
424   for (size_t i = 0; i < quad_list_size; ++i) {
425     cc::DrawQuad::Material material;
426     PickleIterator temp_iter = *iter;
427     if (!ReadParam(m, &temp_iter, &material))
428       return false;
429 
430     scoped_ptr<cc::DrawQuad> draw_quad;
431     switch (material) {
432       case cc::DrawQuad::CHECKERBOARD:
433         draw_quad = ReadDrawQuad<cc::CheckerboardDrawQuad>(m, iter);
434         break;
435       case cc::DrawQuad::DEBUG_BORDER:
436         draw_quad = ReadDrawQuad<cc::DebugBorderDrawQuad>(m, iter);
437         break;
438       case cc::DrawQuad::IO_SURFACE_CONTENT:
439         draw_quad = ReadDrawQuad<cc::IOSurfaceDrawQuad>(m, iter);
440         break;
441       case cc::DrawQuad::PICTURE_CONTENT:
442         NOTREACHED();
443         return false;
444       case cc::DrawQuad::TEXTURE_CONTENT:
445         draw_quad = ReadDrawQuad<cc::TextureDrawQuad>(m, iter);
446         break;
447       case cc::DrawQuad::RENDER_PASS:
448         draw_quad = ReadDrawQuad<cc::RenderPassDrawQuad>(m, iter);
449         break;
450       case cc::DrawQuad::SOLID_COLOR:
451         draw_quad = ReadDrawQuad<cc::SolidColorDrawQuad>(m, iter);
452         break;
453       case cc::DrawQuad::TILED_CONTENT:
454         draw_quad = ReadDrawQuad<cc::TileDrawQuad>(m, iter);
455         break;
456       case cc::DrawQuad::STREAM_VIDEO_CONTENT:
457         draw_quad = ReadDrawQuad<cc::StreamVideoDrawQuad>(m, iter);
458         break;
459       case cc::DrawQuad::YUV_VIDEO_CONTENT:
460         draw_quad = ReadDrawQuad<cc::YUVVideoDrawQuad>(m, iter);
461         break;
462       case cc::DrawQuad::INVALID:
463         break;
464     }
465     if (!draw_quad)
466       return false;
467     if (!draw_quad->rect.Contains(draw_quad->visible_rect)) {
468       LOG(ERROR) << "Quad with invalid visible rect " << draw_quad->material
469                  << " rect: " << draw_quad->rect.ToString()
470                  << " visible_rect: " << draw_quad->visible_rect.ToString();
471       return false;
472     }
473     if (!draw_quad->opaque_rect.IsEmpty() &&
474         !draw_quad->rect.Contains(draw_quad->opaque_rect)) {
475       LOG(ERROR) << "Quad with invalid opaque rect " << draw_quad->material
476                  << " rect: " << draw_quad->rect.ToString()
477                  << " opaque_rect: " << draw_quad->opaque_rect.ToString();
478       return false;
479     }
480 
481     size_t shared_quad_state_index;
482     if (!ReadParam(m, iter, &shared_quad_state_index))
483       return false;
484     if (shared_quad_state_index >= shared_quad_state_list_size)
485       return false;
486     // SharedQuadState indexes should be in ascending order.
487     if (last_shared_quad_state_index != kuint32max &&
488         shared_quad_state_index < last_shared_quad_state_index)
489       return false;
490 
491     // If the quad has a new shared quad state, read it in.
492     if (last_shared_quad_state_index != shared_quad_state_index) {
493       scoped_ptr<cc::SharedQuadState> state(cc::SharedQuadState::Create());
494       if (!ReadParam(m, iter, state.get()))
495         return false;
496       p->shared_quad_state_list.push_back(state.Pass());
497       last_shared_quad_state_index = shared_quad_state_index;
498     }
499 
500     draw_quad->shared_quad_state = p->shared_quad_state_list.back();
501     p->quad_list.push_back(draw_quad.Pass());
502   }
503 
504   return true;
505 }
506 
Log(const param_type & p,std::string * l)507 void ParamTraits<cc::RenderPass>::Log(
508     const param_type& p, std::string* l) {
509   l->append("RenderPass((");
510   LogParam(p.id, l);
511   l->append("), ");
512   LogParam(p.output_rect, l);
513   l->append(", ");
514   LogParam(p.damage_rect, l);
515   l->append(", ");
516   LogParam(p.transform_to_root_target, l);
517   l->append(", ");
518   LogParam(p.has_transparent_background, l);
519   l->append(", ");
520 
521   l->append("[");
522   for (size_t i = 0; i < p.shared_quad_state_list.size(); ++i) {
523     if (i)
524       l->append(", ");
525     LogParam(*p.shared_quad_state_list[i], l);
526   }
527   l->append("], [");
528   for (size_t i = 0; i < p.quad_list.size(); ++i) {
529     if (i)
530       l->append(", ");
531     const cc::DrawQuad* quad = p.quad_list[i];
532     switch (quad->material) {
533       case cc::DrawQuad::CHECKERBOARD:
534         LogParam(*cc::CheckerboardDrawQuad::MaterialCast(quad), l);
535         break;
536       case cc::DrawQuad::DEBUG_BORDER:
537         LogParam(*cc::DebugBorderDrawQuad::MaterialCast(quad), l);
538         break;
539       case cc::DrawQuad::IO_SURFACE_CONTENT:
540         LogParam(*cc::IOSurfaceDrawQuad::MaterialCast(quad), l);
541         break;
542       case cc::DrawQuad::PICTURE_CONTENT:
543         NOTREACHED();
544         break;
545       case cc::DrawQuad::TEXTURE_CONTENT:
546         LogParam(*cc::TextureDrawQuad::MaterialCast(quad), l);
547         break;
548       case cc::DrawQuad::RENDER_PASS:
549         LogParam(*cc::RenderPassDrawQuad::MaterialCast(quad), l);
550         break;
551       case cc::DrawQuad::SOLID_COLOR:
552         LogParam(*cc::SolidColorDrawQuad::MaterialCast(quad), l);
553         break;
554       case cc::DrawQuad::TILED_CONTENT:
555         LogParam(*cc::TileDrawQuad::MaterialCast(quad), l);
556         break;
557       case cc::DrawQuad::STREAM_VIDEO_CONTENT:
558         LogParam(*cc::StreamVideoDrawQuad::MaterialCast(quad), l);
559         break;
560       case cc::DrawQuad::YUV_VIDEO_CONTENT:
561         LogParam(*cc::YUVVideoDrawQuad::MaterialCast(quad), l);
562         break;
563       case cc::DrawQuad::INVALID:
564         break;
565     }
566   }
567   l->append("])");
568 }
569 
570 namespace {
571   enum CompositorFrameType {
572     NO_FRAME,
573     DELEGATED_FRAME,
574     GL_FRAME,
575     SOFTWARE_FRAME,
576   };
577 }
578 
Write(Message * m,const param_type & p)579 void ParamTraits<cc::CompositorFrame>::Write(Message* m,
580                                              const param_type& p) {
581   WriteParam(m, p.metadata);
582   if (p.delegated_frame_data) {
583     DCHECK(!p.gl_frame_data);
584     DCHECK(!p.software_frame_data);
585     WriteParam(m, static_cast<int>(DELEGATED_FRAME));
586     WriteParam(m, *p.delegated_frame_data);
587   } else if (p.gl_frame_data) {
588     DCHECK(!p.software_frame_data);
589     WriteParam(m, static_cast<int>(GL_FRAME));
590     WriteParam(m, *p.gl_frame_data);
591   } else if (p.software_frame_data) {
592     WriteParam(m, static_cast<int>(SOFTWARE_FRAME));
593     WriteParam(m, *p.software_frame_data);
594   } else {
595     WriteParam(m, static_cast<int>(NO_FRAME));
596   }
597 }
598 
Read(const Message * m,PickleIterator * iter,param_type * p)599 bool ParamTraits<cc::CompositorFrame>::Read(const Message* m,
600                                             PickleIterator* iter,
601                                             param_type* p) {
602   if (!ReadParam(m, iter, &p->metadata))
603     return false;
604 
605   int compositor_frame_type;
606   if (!ReadParam(m, iter, &compositor_frame_type))
607     return false;
608 
609   switch (compositor_frame_type) {
610     case DELEGATED_FRAME:
611       p->delegated_frame_data.reset(new cc::DelegatedFrameData());
612       if (!ReadParam(m, iter, p->delegated_frame_data.get()))
613         return false;
614       break;
615     case GL_FRAME:
616       p->gl_frame_data.reset(new cc::GLFrameData());
617       if (!ReadParam(m, iter, p->gl_frame_data.get()))
618         return false;
619       break;
620     case SOFTWARE_FRAME:
621       p->software_frame_data.reset(new cc::SoftwareFrameData());
622       if (!ReadParam(m, iter, p->software_frame_data.get()))
623         return false;
624       break;
625     case NO_FRAME:
626       break;
627     default:
628       return false;
629   }
630   return true;
631 }
632 
Log(const param_type & p,std::string * l)633 void ParamTraits<cc::CompositorFrame>::Log(const param_type& p,
634                                            std::string* l) {
635   l->append("CompositorFrame(");
636   LogParam(p.metadata, l);
637   l->append(", ");
638   if (p.delegated_frame_data)
639     LogParam(*p.delegated_frame_data, l);
640   else if (p.gl_frame_data)
641     LogParam(*p.gl_frame_data, l);
642   else if (p.software_frame_data)
643     LogParam(*p.software_frame_data, l);
644   l->append(")");
645 }
646 
Write(Message * m,const param_type & p)647 void ParamTraits<cc::CompositorFrameAck>::Write(Message* m,
648                                                 const param_type& p) {
649   WriteParam(m, p.resources);
650   WriteParam(m, p.last_software_frame_id);
651   if (p.gl_frame_data) {
652     WriteParam(m, static_cast<int>(GL_FRAME));
653     WriteParam(m, *p.gl_frame_data);
654   } else {
655     WriteParam(m, static_cast<int>(NO_FRAME));
656   }
657 }
658 
Read(const Message * m,PickleIterator * iter,param_type * p)659 bool ParamTraits<cc::CompositorFrameAck>::Read(const Message* m,
660                                                PickleIterator* iter,
661                                                param_type* p) {
662   if (!ReadParam(m, iter, &p->resources))
663     return false;
664 
665   if (!ReadParam(m, iter, &p->last_software_frame_id))
666     return false;
667 
668   int compositor_frame_type;
669   if (!ReadParam(m, iter, &compositor_frame_type))
670     return false;
671 
672   switch (compositor_frame_type) {
673     case NO_FRAME:
674       break;
675     case GL_FRAME:
676       p->gl_frame_data.reset(new cc::GLFrameData());
677       if (!ReadParam(m, iter, p->gl_frame_data.get()))
678         return false;
679       break;
680     default:
681       return false;
682   }
683   return true;
684 }
685 
Log(const param_type & p,std::string * l)686 void ParamTraits<cc::CompositorFrameAck>::Log(const param_type& p,
687                                               std::string* l) {
688   l->append("CompositorFrameAck(");
689   LogParam(p.resources, l);
690   l->append(", ");
691   LogParam(p.last_software_frame_id, l);
692   l->append(", ");
693   if (p.gl_frame_data)
694     LogParam(*p.gl_frame_data, l);
695   l->append(")");
696 }
697 
Write(Message * m,const param_type & p)698 void ParamTraits<cc::DelegatedFrameData>::Write(Message* m,
699                                                 const param_type& p) {
700   DCHECK_NE(0u, p.render_pass_list.size());
701 
702   size_t to_reserve = p.resource_list.size() * sizeof(cc::TransferableResource);
703   for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
704     const cc::RenderPass* pass = p.render_pass_list[i];
705     to_reserve += ReserveSizeForRenderPassWrite(*pass);
706   }
707   m->Reserve(to_reserve);
708 
709   WriteParam(m, p.resource_list);
710   WriteParam(m, p.render_pass_list.size());
711   for (size_t i = 0; i < p.render_pass_list.size(); ++i)
712     WriteParam(m, *p.render_pass_list[i]);
713 }
714 
Read(const Message * m,PickleIterator * iter,param_type * p)715 bool ParamTraits<cc::DelegatedFrameData>::Read(const Message* m,
716                                                PickleIterator* iter,
717                                                param_type* p) {
718   const static size_t kMaxRenderPasses = 10000;
719 
720   size_t num_render_passes;
721   if (!ReadParam(m, iter, &p->resource_list) ||
722       !ReadParam(m, iter, &num_render_passes) ||
723       num_render_passes > kMaxRenderPasses || num_render_passes == 0)
724     return false;
725   for (size_t i = 0; i < num_render_passes; ++i) {
726     scoped_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
727     if (!ReadParam(m, iter, render_pass.get()))
728       return false;
729     p->render_pass_list.push_back(render_pass.Pass());
730   }
731   return true;
732 }
733 
Log(const param_type & p,std::string * l)734 void ParamTraits<cc::DelegatedFrameData>::Log(const param_type& p,
735                                               std::string* l) {
736   l->append("DelegatedFrameData(");
737   LogParam(p.resource_list, l);
738   l->append(", [");
739   for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
740     if (i)
741       l->append(", ");
742     LogParam(*p.render_pass_list[i], l);
743   }
744   l->append("])");
745 }
746 
747 }  // namespace IPC
748