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 "content/public/common/common_param_traits.h" 10 #include "content/public/common/content_switches.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::RenderPassDrawQuad); 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 = QuadType::Create(); 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 805