Add @VisibleForTesting to fix ChromePublic release build.
[chromium-blink-merge.git] / content / common / cc_messages.cc
blobe7c2ad21fdee1ab412f3766a0991cd0fb750f9b0
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.
5 #include "content/common/cc_messages.h"
7 #include "cc/output/compositor_frame.h"
8 #include "cc/output/filter_operations.h"
9 #include "cc/quads/largest_draw_quad.h"
10 #include "cc/quads/render_pass_id.h"
11 #include "content/public/common/common_param_traits.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"
16 namespace IPC {
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;
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;
65 if (!ReadParam(m, iter, &type))
66 return false;
67 r->set_type(type);
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;
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;
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;
102 if (i == 20) {
103 r->set_matrix(matrix);
104 success = true;
106 break;
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;
117 break;
118 case cc::FilterOperation::REFERENCE: {
119 skia::RefPtr<SkImageFilter> filter;
120 if (!ReadParam(m, iter, &filter)) {
121 success = false;
122 break;
124 r->set_image_filter(filter);
125 success = true;
126 break;
128 case cc::FilterOperation::ALPHA_THRESHOLD:
129 break;
131 return success;
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(", ");
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);
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;
179 l->append(")");
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));
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;
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);
202 return true;
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);
213 l->append(")");
216 void ParamTraits<skia::RefPtr<SkImageFilter> >::Write(
217 Message* m, const param_type& p) {
218 SkImageFilter* filter = p.get();
219 if (filter) {
220 skia::RefPtr<SkData> data =
221 skia::AdoptRef(SkValidatingSerializeFlattenable(filter));
222 m->WriteData(static_cast<const char*>(data->data()), data->size());
223 } else {
224 m->WriteData(0, 0);
228 bool ParamTraits<skia::RefPtr<SkImageFilter> >::Read(
229 const Message* m, PickleIterator* iter, param_type* r) {
230 const char* data = 0;
231 int length = 0;
232 if (!iter->ReadData(&data, &length))
233 return false;
234 if (length > 0) {
235 SkFlattenable* flattenable = SkValidatingDeserializeFlattenable(
236 data, length, SkImageFilter::GetFlattenableType());
237 *r = skia::AdoptRef(static_cast<SkImageFilter*>(flattenable));
238 } else {
239 r->clear();
241 return true;
244 void ParamTraits<skia::RefPtr<SkImageFilter> >::Log(
245 const param_type& p, std::string* l) {
246 l->append("(");
247 LogParam(p.get() ? p->countInputs() : 0, l);
248 l->append(")");
251 void ParamTraits<gfx::Transform>::Write(
252 Message* m, const param_type& p) {
253 #ifdef SK_MSCALAR_IS_FLOAT
254 float column_major_data[16];
255 p.matrix().asColMajorf(column_major_data);
256 #else
257 double column_major_data[16];
258 p.matrix().asColMajord(column_major_data);
259 #endif
260 m->WriteBytes(&column_major_data, sizeof(SkMScalar) * 16);
263 bool ParamTraits<gfx::Transform>::Read(
264 const Message* m, PickleIterator* iter, param_type* r) {
265 const char* column_major_data;
266 if (!iter->ReadBytes(&column_major_data, sizeof(SkMScalar) * 16))
267 return false;
268 r->matrix().setColMajor(
269 reinterpret_cast<const SkMScalar*>(column_major_data));
270 return true;
273 void ParamTraits<gfx::Transform>::Log(
274 const param_type& p, std::string* l) {
275 #ifdef SK_MSCALAR_IS_FLOAT
276 float row_major_data[16];
277 p.matrix().asRowMajorf(row_major_data);
278 #else
279 double row_major_data[16];
280 p.matrix().asRowMajord(row_major_data);
281 #endif
282 l->append("(");
283 for (int i = 0; i < 16; ++i) {
284 if (i > 0)
285 l->append(", ");
286 LogParam(row_major_data[i], l);
288 l->append(") ");
291 void ParamTraits<cc::RenderPass>::Write(
292 Message* m, const param_type& p) {
293 WriteParam(m, p.id);
294 WriteParam(m, p.output_rect);
295 WriteParam(m, p.damage_rect);
296 WriteParam(m, p.transform_to_root_target);
297 WriteParam(m, p.has_transparent_background);
298 WriteParam(m, p.quad_list.size());
300 cc::SharedQuadStateList::ConstIterator shared_quad_state_iter =
301 p.shared_quad_state_list.begin();
302 cc::SharedQuadStateList::ConstIterator last_shared_quad_state_iter =
303 p.shared_quad_state_list.end();
304 for (const auto& quad : p.quad_list) {
305 DCHECK(quad->rect.Contains(quad->visible_rect))
306 << quad->material << " rect: " << quad->rect.ToString()
307 << " visible_rect: " << quad->visible_rect.ToString();
308 DCHECK(quad->opaque_rect.IsEmpty() ||
309 quad->rect.Contains(quad->opaque_rect))
310 << quad->material << " rect: " << quad->rect.ToString()
311 << " opaque_rect: " << quad->opaque_rect.ToString();
313 switch (quad->material) {
314 case cc::DrawQuad::CHECKERBOARD:
315 WriteParam(m, *cc::CheckerboardDrawQuad::MaterialCast(quad));
316 break;
317 case cc::DrawQuad::DEBUG_BORDER:
318 WriteParam(m, *cc::DebugBorderDrawQuad::MaterialCast(quad));
319 break;
320 case cc::DrawQuad::IO_SURFACE_CONTENT:
321 WriteParam(m, *cc::IOSurfaceDrawQuad::MaterialCast(quad));
322 break;
323 case cc::DrawQuad::PICTURE_CONTENT:
324 NOTREACHED();
325 break;
326 case cc::DrawQuad::TEXTURE_CONTENT:
327 WriteParam(m, *cc::TextureDrawQuad::MaterialCast(quad));
328 break;
329 case cc::DrawQuad::RENDER_PASS:
330 WriteParam(m, *cc::RenderPassDrawQuad::MaterialCast(quad));
331 break;
332 case cc::DrawQuad::SOLID_COLOR:
333 WriteParam(m, *cc::SolidColorDrawQuad::MaterialCast(quad));
334 break;
335 case cc::DrawQuad::SURFACE_CONTENT:
336 WriteParam(m, *cc::SurfaceDrawQuad::MaterialCast(quad));
337 break;
338 case cc::DrawQuad::TILED_CONTENT:
339 WriteParam(m, *cc::TileDrawQuad::MaterialCast(quad));
340 break;
341 case cc::DrawQuad::STREAM_VIDEO_CONTENT:
342 WriteParam(m, *cc::StreamVideoDrawQuad::MaterialCast(quad));
343 break;
344 case cc::DrawQuad::YUV_VIDEO_CONTENT:
345 WriteParam(m, *cc::YUVVideoDrawQuad::MaterialCast(quad));
346 break;
347 case cc::DrawQuad::INVALID:
348 break;
351 // Null shared quad states should not occur.
352 DCHECK(quad->shared_quad_state);
354 // SharedQuadStates should appear in the order they are used by DrawQuads.
355 // Find the SharedQuadState for this DrawQuad.
356 while (shared_quad_state_iter != p.shared_quad_state_list.end() &&
357 quad->shared_quad_state != *shared_quad_state_iter)
358 ++shared_quad_state_iter;
360 DCHECK(shared_quad_state_iter != p.shared_quad_state_list.end());
362 if (shared_quad_state_iter != last_shared_quad_state_iter) {
363 WriteParam(m, true);
364 WriteParam(m, **shared_quad_state_iter);
365 last_shared_quad_state_iter = shared_quad_state_iter;
366 } else {
367 WriteParam(m, false);
372 static size_t ReserveSizeForRenderPassWrite(const cc::RenderPass& p) {
373 size_t to_reserve = sizeof(cc::RenderPass);
375 // Whether the quad points to a new shared quad state for each quad.
376 to_reserve += p.quad_list.size() * sizeof(bool);
378 // Shared quad state is only written when a quad contains a shared quad state
379 // that has not been written.
380 to_reserve += p.shared_quad_state_list.size() * sizeof(cc::SharedQuadState);
382 // The largest quad type, verified by a unit test.
383 to_reserve += p.quad_list.size() * cc::LargestDrawQuadSize();
384 return to_reserve;
387 template <typename QuadType>
388 static cc::DrawQuad* ReadDrawQuad(const Message* m,
389 PickleIterator* iter,
390 cc::RenderPass* render_pass) {
391 QuadType* quad = render_pass->CreateAndAppendDrawQuad<QuadType>();
392 if (!ReadParam(m, iter, quad))
393 return NULL;
394 return quad;
397 bool ParamTraits<cc::RenderPass>::Read(
398 const Message* m, PickleIterator* iter, param_type* p) {
399 cc::RenderPassId id(-1, -1);
400 gfx::Rect output_rect;
401 gfx::Rect damage_rect;
402 gfx::Transform transform_to_root_target;
403 bool has_transparent_background;
404 size_t quad_list_size;
406 if (!ReadParam(m, iter, &id) ||
407 !ReadParam(m, iter, &output_rect) ||
408 !ReadParam(m, iter, &damage_rect) ||
409 !ReadParam(m, iter, &transform_to_root_target) ||
410 !ReadParam(m, iter, &has_transparent_background) ||
411 !ReadParam(m, iter, &quad_list_size))
412 return false;
414 p->SetAll(id,
415 output_rect,
416 damage_rect,
417 transform_to_root_target,
418 has_transparent_background);
420 for (size_t i = 0; i < quad_list_size; ++i) {
421 cc::DrawQuad::Material material;
422 PickleIterator temp_iter = *iter;
423 if (!ReadParam(m, &temp_iter, &material))
424 return false;
426 cc::DrawQuad* draw_quad = NULL;
427 switch (material) {
428 case cc::DrawQuad::CHECKERBOARD:
429 draw_quad = ReadDrawQuad<cc::CheckerboardDrawQuad>(m, iter, p);
430 break;
431 case cc::DrawQuad::DEBUG_BORDER:
432 draw_quad = ReadDrawQuad<cc::DebugBorderDrawQuad>(m, iter, p);
433 break;
434 case cc::DrawQuad::IO_SURFACE_CONTENT:
435 draw_quad = ReadDrawQuad<cc::IOSurfaceDrawQuad>(m, iter, p);
436 break;
437 case cc::DrawQuad::PICTURE_CONTENT:
438 NOTREACHED();
439 return false;
440 case cc::DrawQuad::SURFACE_CONTENT:
441 draw_quad = ReadDrawQuad<cc::SurfaceDrawQuad>(m, iter, p);
442 break;
443 case cc::DrawQuad::TEXTURE_CONTENT:
444 draw_quad = ReadDrawQuad<cc::TextureDrawQuad>(m, iter, p);
445 break;
446 case cc::DrawQuad::RENDER_PASS:
447 draw_quad = ReadDrawQuad<cc::RenderPassDrawQuad>(m, iter, p);
448 break;
449 case cc::DrawQuad::SOLID_COLOR:
450 draw_quad = ReadDrawQuad<cc::SolidColorDrawQuad>(m, iter, p);
451 break;
452 case cc::DrawQuad::TILED_CONTENT:
453 draw_quad = ReadDrawQuad<cc::TileDrawQuad>(m, iter, p);
454 break;
455 case cc::DrawQuad::STREAM_VIDEO_CONTENT:
456 draw_quad = ReadDrawQuad<cc::StreamVideoDrawQuad>(m, iter, p);
457 break;
458 case cc::DrawQuad::YUV_VIDEO_CONTENT:
459 draw_quad = ReadDrawQuad<cc::YUVVideoDrawQuad>(m, iter, p);
460 break;
461 case cc::DrawQuad::INVALID:
462 break;
464 if (!draw_quad)
465 return false;
466 if (!draw_quad->rect.Contains(draw_quad->visible_rect)) {
467 LOG(ERROR) << "Quad with invalid visible rect " << draw_quad->material
468 << " rect: " << draw_quad->rect.ToString()
469 << " visible_rect: " << draw_quad->visible_rect.ToString();
470 return false;
472 if (!draw_quad->opaque_rect.IsEmpty() &&
473 !draw_quad->rect.Contains(draw_quad->opaque_rect)) {
474 LOG(ERROR) << "Quad with invalid opaque rect " << draw_quad->material
475 << " rect: " << draw_quad->rect.ToString()
476 << " opaque_rect: " << draw_quad->opaque_rect.ToString();
477 return false;
480 bool has_new_shared_quad_state;
481 if (!ReadParam(m, iter, &has_new_shared_quad_state))
482 return false;
484 // If the quad has a new shared quad state, read it in.
485 if (has_new_shared_quad_state) {
486 cc::SharedQuadState* state = p->CreateAndAppendSharedQuadState();
487 if (!ReadParam(m, iter, state))
488 return false;
491 draw_quad->shared_quad_state = p->shared_quad_state_list.back();
494 return true;
497 void ParamTraits<cc::RenderPass>::Log(
498 const param_type& p, std::string* l) {
499 l->append("RenderPass((");
500 LogParam(p.id, l);
501 l->append("), ");
502 LogParam(p.output_rect, l);
503 l->append(", ");
504 LogParam(p.damage_rect, l);
505 l->append(", ");
506 LogParam(p.transform_to_root_target, l);
507 l->append(", ");
508 LogParam(p.has_transparent_background, l);
509 l->append(", ");
511 l->append("[");
512 for (const auto& shared_quad_state : p.shared_quad_state_list) {
513 if (shared_quad_state != p.shared_quad_state_list.front())
514 l->append(", ");
515 LogParam(*shared_quad_state, l);
517 l->append("], [");
518 for (const auto& quad : p.quad_list) {
519 if (quad != p.quad_list.front())
520 l->append(", ");
521 switch (quad->material) {
522 case cc::DrawQuad::CHECKERBOARD:
523 LogParam(*cc::CheckerboardDrawQuad::MaterialCast(quad), l);
524 break;
525 case cc::DrawQuad::DEBUG_BORDER:
526 LogParam(*cc::DebugBorderDrawQuad::MaterialCast(quad), l);
527 break;
528 case cc::DrawQuad::IO_SURFACE_CONTENT:
529 LogParam(*cc::IOSurfaceDrawQuad::MaterialCast(quad), l);
530 break;
531 case cc::DrawQuad::PICTURE_CONTENT:
532 NOTREACHED();
533 break;
534 case cc::DrawQuad::TEXTURE_CONTENT:
535 LogParam(*cc::TextureDrawQuad::MaterialCast(quad), l);
536 break;
537 case cc::DrawQuad::RENDER_PASS:
538 LogParam(*cc::RenderPassDrawQuad::MaterialCast(quad), l);
539 break;
540 case cc::DrawQuad::SOLID_COLOR:
541 LogParam(*cc::SolidColorDrawQuad::MaterialCast(quad), l);
542 break;
543 case cc::DrawQuad::SURFACE_CONTENT:
544 LogParam(*cc::SurfaceDrawQuad::MaterialCast(quad), l);
545 break;
546 case cc::DrawQuad::TILED_CONTENT:
547 LogParam(*cc::TileDrawQuad::MaterialCast(quad), l);
548 break;
549 case cc::DrawQuad::STREAM_VIDEO_CONTENT:
550 LogParam(*cc::StreamVideoDrawQuad::MaterialCast(quad), l);
551 break;
552 case cc::DrawQuad::YUV_VIDEO_CONTENT:
553 LogParam(*cc::YUVVideoDrawQuad::MaterialCast(quad), l);
554 break;
555 case cc::DrawQuad::INVALID:
556 break;
559 l->append("])");
562 namespace {
563 enum CompositorFrameType {
564 NO_FRAME,
565 DELEGATED_FRAME,
566 GL_FRAME,
567 SOFTWARE_FRAME,
571 void ParamTraits<cc::CompositorFrame>::Write(Message* m,
572 const param_type& p) {
573 WriteParam(m, p.metadata);
574 if (p.delegated_frame_data) {
575 DCHECK(!p.gl_frame_data);
576 DCHECK(!p.software_frame_data);
577 WriteParam(m, static_cast<int>(DELEGATED_FRAME));
578 WriteParam(m, *p.delegated_frame_data);
579 } else if (p.gl_frame_data) {
580 DCHECK(!p.software_frame_data);
581 WriteParam(m, static_cast<int>(GL_FRAME));
582 WriteParam(m, *p.gl_frame_data);
583 } else if (p.software_frame_data) {
584 WriteParam(m, static_cast<int>(SOFTWARE_FRAME));
585 WriteParam(m, *p.software_frame_data);
586 } else {
587 WriteParam(m, static_cast<int>(NO_FRAME));
591 bool ParamTraits<cc::CompositorFrame>::Read(const Message* m,
592 PickleIterator* iter,
593 param_type* p) {
594 if (!ReadParam(m, iter, &p->metadata))
595 return false;
597 int compositor_frame_type;
598 if (!ReadParam(m, iter, &compositor_frame_type))
599 return false;
601 switch (compositor_frame_type) {
602 case DELEGATED_FRAME:
603 p->delegated_frame_data.reset(new cc::DelegatedFrameData());
604 if (!ReadParam(m, iter, p->delegated_frame_data.get()))
605 return false;
606 break;
607 case GL_FRAME:
608 p->gl_frame_data.reset(new cc::GLFrameData());
609 if (!ReadParam(m, iter, p->gl_frame_data.get()))
610 return false;
611 break;
612 case SOFTWARE_FRAME:
613 p->software_frame_data.reset(new cc::SoftwareFrameData());
614 if (!ReadParam(m, iter, p->software_frame_data.get()))
615 return false;
616 break;
617 case NO_FRAME:
618 break;
619 default:
620 return false;
622 return true;
625 void ParamTraits<cc::CompositorFrame>::Log(const param_type& p,
626 std::string* l) {
627 l->append("CompositorFrame(");
628 LogParam(p.metadata, l);
629 l->append(", ");
630 if (p.delegated_frame_data)
631 LogParam(*p.delegated_frame_data, l);
632 else if (p.gl_frame_data)
633 LogParam(*p.gl_frame_data, l);
634 else if (p.software_frame_data)
635 LogParam(*p.software_frame_data, l);
636 l->append(")");
639 void ParamTraits<cc::CompositorFrameAck>::Write(Message* m,
640 const param_type& p) {
641 WriteParam(m, p.resources);
642 WriteParam(m, p.last_software_frame_id);
643 if (p.gl_frame_data) {
644 WriteParam(m, static_cast<int>(GL_FRAME));
645 WriteParam(m, *p.gl_frame_data);
646 } else {
647 WriteParam(m, static_cast<int>(NO_FRAME));
651 bool ParamTraits<cc::CompositorFrameAck>::Read(const Message* m,
652 PickleIterator* iter,
653 param_type* p) {
654 if (!ReadParam(m, iter, &p->resources))
655 return false;
657 if (!ReadParam(m, iter, &p->last_software_frame_id))
658 return false;
660 int compositor_frame_type;
661 if (!ReadParam(m, iter, &compositor_frame_type))
662 return false;
664 switch (compositor_frame_type) {
665 case NO_FRAME:
666 break;
667 case GL_FRAME:
668 p->gl_frame_data.reset(new cc::GLFrameData());
669 if (!ReadParam(m, iter, p->gl_frame_data.get()))
670 return false;
671 break;
672 default:
673 return false;
675 return true;
678 void ParamTraits<cc::CompositorFrameAck>::Log(const param_type& p,
679 std::string* l) {
680 l->append("CompositorFrameAck(");
681 LogParam(p.resources, l);
682 l->append(", ");
683 LogParam(p.last_software_frame_id, l);
684 l->append(", ");
685 if (p.gl_frame_data)
686 LogParam(*p.gl_frame_data, l);
687 l->append(")");
690 void ParamTraits<cc::DelegatedFrameData>::Write(Message* m,
691 const param_type& p) {
692 DCHECK_NE(0u, p.render_pass_list.size());
694 size_t to_reserve = sizeof(p.device_scale_factor);
695 to_reserve += p.resource_list.size() * sizeof(cc::TransferableResource);
696 for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
697 const cc::RenderPass* pass = p.render_pass_list[i];
698 to_reserve += sizeof(size_t) * 2;
699 to_reserve += ReserveSizeForRenderPassWrite(*pass);
701 m->Reserve(to_reserve);
703 WriteParam(m, p.device_scale_factor);
704 WriteParam(m, p.resource_list);
705 WriteParam(m, p.render_pass_list.size());
706 for (const auto* pass : p.render_pass_list) {
707 WriteParam(m, pass->quad_list.size());
708 WriteParam(m, pass->shared_quad_state_list.size());
709 WriteParam(m, *pass);
713 bool ParamTraits<cc::DelegatedFrameData>::Read(const Message* m,
714 PickleIterator* iter,
715 param_type* p) {
716 if (!ReadParam(m, iter, &p->device_scale_factor))
717 return false;
719 const static size_t kMaxRenderPasses = 10000;
720 const static size_t kMaxSharedQuadStateListSize = 100000;
721 const static size_t kMaxQuadListSize = 1000000;
723 std::set<cc::RenderPassId> pass_set;
725 size_t num_render_passes;
726 if (!ReadParam(m, iter, &p->resource_list) ||
727 !ReadParam(m, iter, &num_render_passes) ||
728 num_render_passes > kMaxRenderPasses || num_render_passes == 0)
729 return false;
730 for (size_t i = 0; i < num_render_passes; ++i) {
731 size_t quad_list_size;
732 size_t shared_quad_state_list_size;
733 if (!ReadParam(m, iter, &quad_list_size) ||
734 !ReadParam(m, iter, &shared_quad_state_list_size) ||
735 quad_list_size > kMaxQuadListSize ||
736 shared_quad_state_list_size > kMaxSharedQuadStateListSize)
737 return false;
738 scoped_ptr<cc::RenderPass> render_pass =
739 cc::RenderPass::Create(shared_quad_state_list_size, quad_list_size);
740 if (!ReadParam(m, iter, render_pass.get()))
741 return false;
742 // Validate that each RenderPassDrawQuad points at a valid RenderPass
743 // earlier in the frame.
744 for (const auto* quad : render_pass->quad_list) {
745 if (quad->material != cc::DrawQuad::RENDER_PASS)
746 continue;
747 const cc::RenderPassDrawQuad* rpdq =
748 cc::RenderPassDrawQuad::MaterialCast(quad);
749 if (!pass_set.count(rpdq->render_pass_id))
750 return false;
752 pass_set.insert(render_pass->id);
753 p->render_pass_list.push_back(render_pass.Pass());
755 return true;
758 void ParamTraits<cc::DelegatedFrameData>::Log(const param_type& p,
759 std::string* l) {
760 l->append("DelegatedFrameData(");
761 LogParam(p.device_scale_factor, l);
762 LogParam(p.resource_list, l);
763 l->append(", [");
764 for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
765 if (i)
766 l->append(", ");
767 LogParam(*p.render_pass_list[i], l);
769 l->append("])");
772 void ParamTraits<cc::SoftwareFrameData>::Write(Message* m,
773 const param_type& p) {
774 DCHECK(cc::SharedBitmap::VerifySizeInBytes(p.size));
776 m->Reserve(sizeof(cc::SoftwareFrameData));
777 WriteParam(m, p.id);
778 WriteParam(m, p.size);
779 WriteParam(m, p.damage_rect);
780 WriteParam(m, p.bitmap_id);
783 bool ParamTraits<cc::SoftwareFrameData>::Read(const Message* m,
784 PickleIterator* iter,
785 param_type* p) {
786 if (!ReadParam(m, iter, &p->id))
787 return false;
788 if (!ReadParam(m, iter, &p->size) ||
789 !cc::SharedBitmap::VerifySizeInBytes(p->size))
790 return false;
791 if (!ReadParam(m, iter, &p->damage_rect))
792 return false;
793 if (!ReadParam(m, iter, &p->bitmap_id))
794 return false;
795 return true;
798 void ParamTraits<cc::SoftwareFrameData>::Log(const param_type& p,
799 std::string* l) {
800 l->append("SoftwareFrameData(");
801 LogParam(p.id, l);
802 l->append(", ");
803 LogParam(p.size, l);
804 l->append(", ");
805 LogParam(p.damage_rect, l);
806 l->append(", ");
807 LogParam(p.bitmap_id, l);
808 l->append(")");
811 } // namespace IPC