blob: ea3ed9f159fc7e375ff90761985d2440a0b79855 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/ipc/cc_param_traits.h"
#include <stddef.h>
#include <utility>
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/unguessable_token.h"
#include "cc/paint/filter_operations.h"
#include "cc/paint/paint_filter.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/paint_op_reader.h"
#include "cc/paint/paint_op_writer.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/debug_border_draw_quad.h"
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/common/quads/largest_draw_quad.h"
#include "components/viz/common/quads/render_pass_draw_quad.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/surface_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "ui/gfx/ipc/geometry/gfx_param_traits.h"
#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
namespace IPC {
void ParamTraits<cc::FilterOperation>::Write(base::Pickle* m,
const param_type& p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::FilterOperation::Write");
WriteParam(m, p.type());
switch (p.type()) {
case cc::FilterOperation::GRAYSCALE:
case cc::FilterOperation::SEPIA:
case cc::FilterOperation::SATURATE:
case cc::FilterOperation::HUE_ROTATE:
case cc::FilterOperation::INVERT:
case cc::FilterOperation::BRIGHTNESS:
case cc::FilterOperation::SATURATING_BRIGHTNESS:
case cc::FilterOperation::CONTRAST:
case cc::FilterOperation::OPACITY:
WriteParam(m, p.amount());
break;
case cc::FilterOperation::BLUR:
WriteParam(m, p.amount());
WriteParam(m, p.blur_tile_mode());
break;
case cc::FilterOperation::DROP_SHADOW:
WriteParam(m, p.drop_shadow_offset());
WriteParam(m, p.amount());
WriteParam(m, p.drop_shadow_color());
break;
case cc::FilterOperation::COLOR_MATRIX:
for (int i = 0; i < 20; ++i)
WriteParam(m, p.matrix()[i]);
break;
case cc::FilterOperation::ZOOM:
WriteParam(m, p.amount());
WriteParam(m, p.zoom_inset());
break;
case cc::FilterOperation::REFERENCE:
WriteParam(m, p.image_filter());
break;
case cc::FilterOperation::ALPHA_THRESHOLD:
WriteParam(m, p.amount());
WriteParam(m, p.outer_threshold());
WriteParam(m, p.shape());
break;
}
}
bool ParamTraits<cc::FilterOperation>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::FilterOperation::Read");
cc::FilterOperation::FilterType type;
float amount;
float outer_threshold;
gfx::Point drop_shadow_offset;
SkColor drop_shadow_color;
SkScalar matrix[20];
cc::FilterOperation::ShapeRects shape;
int zoom_inset;
SkBlurImageFilter::TileMode tile_mode;
if (!ReadParam(m, iter, &type))
return false;
r->set_type(type);
bool success = false;
switch (type) {
case cc::FilterOperation::GRAYSCALE:
case cc::FilterOperation::SEPIA:
case cc::FilterOperation::SATURATE:
case cc::FilterOperation::HUE_ROTATE:
case cc::FilterOperation::INVERT:
case cc::FilterOperation::BRIGHTNESS:
case cc::FilterOperation::SATURATING_BRIGHTNESS:
case cc::FilterOperation::CONTRAST:
case cc::FilterOperation::OPACITY:
if (ReadParam(m, iter, &amount)) {
r->set_amount(amount);
success = true;
}
break;
case cc::FilterOperation::BLUR:
if (ReadParam(m, iter, &amount) && ReadParam(m, iter, &tile_mode)) {
r->set_amount(amount);
r->set_blur_tile_mode(tile_mode);
success = true;
}
break;
case cc::FilterOperation::DROP_SHADOW:
if (ReadParam(m, iter, &drop_shadow_offset) &&
ReadParam(m, iter, &amount) &&
ReadParam(m, iter, &drop_shadow_color)) {
r->set_drop_shadow_offset(drop_shadow_offset);
r->set_amount(amount);
r->set_drop_shadow_color(drop_shadow_color);
success = true;
}
break;
case cc::FilterOperation::COLOR_MATRIX: {
int i;
for (i = 0; i < 20; ++i) {
if (!ReadParam(m, iter, &matrix[i]))
break;
}
if (i == 20) {
r->set_matrix(matrix);
success = true;
}
break;
}
case cc::FilterOperation::ZOOM:
if (ReadParam(m, iter, &amount) && ReadParam(m, iter, &zoom_inset) &&
amount >= 0.f && zoom_inset >= 0) {
r->set_amount(amount);
r->set_zoom_inset(zoom_inset);
success = true;
}
break;
case cc::FilterOperation::REFERENCE: {
sk_sp<cc::PaintFilter> filter;
if (!ReadParam(m, iter, &filter)) {
success = false;
break;
}
r->set_image_filter(std::move(filter));
success = true;
break;
}
case cc::FilterOperation::ALPHA_THRESHOLD:
if (ReadParam(m, iter, &amount) && ReadParam(m, iter, &outer_threshold) &&
ReadParam(m, iter, &shape) && amount >= 0.f &&
outer_threshold >= 0.f) {
r->set_amount(amount);
r->set_outer_threshold(amount);
r->set_shape(shape);
success = true;
}
break;
}
return success;
}
void ParamTraits<cc::FilterOperation>::Log(const param_type& p,
std::string* l) {
l->append("(");
LogParam(static_cast<unsigned>(p.type()), l);
l->append(", ");
switch (p.type()) {
case cc::FilterOperation::GRAYSCALE:
case cc::FilterOperation::SEPIA:
case cc::FilterOperation::SATURATE:
case cc::FilterOperation::HUE_ROTATE:
case cc::FilterOperation::INVERT:
case cc::FilterOperation::BRIGHTNESS:
case cc::FilterOperation::SATURATING_BRIGHTNESS:
case cc::FilterOperation::CONTRAST:
case cc::FilterOperation::OPACITY:
LogParam(p.amount(), l);
break;
case cc::FilterOperation::BLUR:
LogParam(p.amount(), l);
l->append(", ");
LogParam(static_cast<int>(p.blur_tile_mode()), l);
break;
case cc::FilterOperation::DROP_SHADOW:
LogParam(p.drop_shadow_offset(), l);
l->append(", ");
LogParam(p.amount(), l);
l->append(", ");
LogParam(p.drop_shadow_color(), l);
break;
case cc::FilterOperation::COLOR_MATRIX:
for (int i = 0; i < 20; ++i) {
if (i)
l->append(", ");
LogParam(p.matrix()[i], l);
}
break;
case cc::FilterOperation::ZOOM:
LogParam(p.amount(), l);
l->append(", ");
LogParam(p.zoom_inset(), l);
break;
case cc::FilterOperation::REFERENCE:
LogParam(p.image_filter(), l);
break;
case cc::FilterOperation::ALPHA_THRESHOLD:
LogParam(p.amount(), l);
l->append(", ");
LogParam(p.outer_threshold(), l);
l->append(", ");
LogParam(p.shape(), l);
break;
}
l->append(")");
}
void ParamTraits<cc::FilterOperations>::Write(base::Pickle* m,
const param_type& p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::FilterOperations::Write");
WriteParam(m, base::checked_cast<uint32_t>(p.size()));
for (std::size_t i = 0; i < p.size(); ++i) {
WriteParam(m, p.at(i));
}
}
bool ParamTraits<cc::FilterOperations>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::FilterOperations::Read");
uint32_t count;
if (!ReadParam(m, iter, &count))
return false;
for (std::size_t i = 0; i < count; ++i) {
cc::FilterOperation op = cc::FilterOperation::CreateEmptyFilter();
if (!ReadParam(m, iter, &op))
return false;
r->Append(op);
}
return true;
}
void ParamTraits<cc::FilterOperations>::Log(const param_type& p,
std::string* l) {
l->append("(");
for (std::size_t i = 0; i < p.size(); ++i) {
if (i)
l->append(", ");
LogParam(p.at(i), l);
}
l->append(")");
}
void ParamTraits<sk_sp<cc::PaintFilter>>::Write(base::Pickle* m,
const param_type& p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::PaintFilter::Write");
std::vector<uint8_t> memory;
memory.resize(cc::PaintOpWriter::HeaderBytes() +
cc::PaintFilter::GetFilterSize(p.get()));
cc::PaintOpWriter writer(memory.data(), memory.size(), nullptr, nullptr,
true /* enable_security_constraints */);
writer.Write(p.get());
if (writer.size() == 0u)
m->WriteData(nullptr, 0);
else
m->WriteData(reinterpret_cast<const char*>(memory.data()), writer.size());
}
bool ParamTraits<sk_sp<cc::PaintFilter>>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::PaintFilter::Read");
const char* data = nullptr;
int length = 0;
if (!iter->ReadData(&data, &length))
return false;
if (length <= 0) {
r->reset();
return true;
}
cc::PaintOpReader reader(data, length, nullptr,
true /* enable_security_constraints */);
sk_sp<cc::PaintFilter> filter;
reader.Read(&filter);
if (!filter)
return false;
*r = std::move(filter);
return true;
}
void ParamTraits<sk_sp<cc::PaintFilter>>::Log(const param_type& p,
std::string* l) {
l->append("(");
auto type = p ? p->type() : cc::PaintFilter::Type::kNullFilter;
LogParam(cc::PaintFilter::TypeToString(type), l);
l->append(")");
}
void ParamTraits<viz::RenderPass>::Write(base::Pickle* m, const param_type& p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::RenderPass::Write");
WriteParam(m, p.id);
WriteParam(m, p.output_rect);
WriteParam(m, p.damage_rect);
WriteParam(m, p.transform_to_root_target);
WriteParam(m, p.filters);
WriteParam(m, p.background_filters);
WriteParam(m, p.color_space);
WriteParam(m, p.has_transparent_background);
WriteParam(m, p.cache_render_pass);
WriteParam(m, p.has_damage_from_contributing_content);
WriteParam(m, p.generate_mipmap);
WriteParam(m, base::checked_cast<uint32_t>(p.quad_list.size()));
auto shared_quad_state_iter = p.shared_quad_state_list.cbegin();
auto last_shared_quad_state_iter = p.shared_quad_state_list.cend();
for (auto* quad : p.quad_list) {
DCHECK(quad->rect.Contains(quad->visible_rect))
<< quad->material << " rect: " << quad->rect.ToString()
<< " visible_rect: " << quad->visible_rect.ToString();
switch (quad->material) {
case viz::DrawQuad::DEBUG_BORDER:
WriteParam(m, *viz::DebugBorderDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::PICTURE_CONTENT:
NOTREACHED();
break;
case viz::DrawQuad::TEXTURE_CONTENT:
WriteParam(m, *viz::TextureDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::RENDER_PASS:
WriteParam(m, *viz::RenderPassDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::SOLID_COLOR:
WriteParam(m, *viz::SolidColorDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::SURFACE_CONTENT:
WriteParam(m, *viz::SurfaceDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::TILED_CONTENT:
WriteParam(m, *viz::TileDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::STREAM_VIDEO_CONTENT:
WriteParam(m, *viz::StreamVideoDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::YUV_VIDEO_CONTENT:
WriteParam(m, *viz::YUVVideoDrawQuad::MaterialCast(quad));
break;
case viz::DrawQuad::INVALID:
break;
}
// Null shared quad states should not occur.
DCHECK(quad->shared_quad_state);
// SharedQuadStates should appear in the order they are used by DrawQuads.
// Find the SharedQuadState for this DrawQuad.
while (shared_quad_state_iter != p.shared_quad_state_list.end() &&
quad->shared_quad_state != *shared_quad_state_iter) {
++shared_quad_state_iter;
}
DCHECK(shared_quad_state_iter != p.shared_quad_state_list.end());
if (shared_quad_state_iter != last_shared_quad_state_iter) {
WriteParam(m, true);
WriteParam(m, **shared_quad_state_iter);
last_shared_quad_state_iter = shared_quad_state_iter;
} else {
WriteParam(m, false);
}
}
}
static size_t ReserveSizeForRenderPassWrite(const viz::RenderPass& p) {
size_t to_reserve = sizeof(viz::RenderPass);
// Whether the quad points to a new shared quad state for each quad.
to_reserve += p.quad_list.size() * sizeof(bool);
// Shared quad state is only written when a quad contains a shared quad state
// that has not been written.
to_reserve += p.shared_quad_state_list.size() * sizeof(viz::SharedQuadState);
// The largest quad type, verified by a unit test.
to_reserve += p.quad_list.size() * viz::LargestDrawQuadSize();
to_reserve +=
sizeof(uint32_t) + p.filters.size() * sizeof(cc::FilterOperation);
to_reserve += sizeof(uint32_t) +
p.background_filters.size() * sizeof(cc::FilterOperation);
return to_reserve;
}
template <typename QuadType>
static viz::DrawQuad* ReadDrawQuad(const base::Pickle* m,
base::PickleIterator* iter,
viz::RenderPass* render_pass) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::ReadDrawQuad");
QuadType* quad = render_pass->CreateAndAppendDrawQuad<QuadType>();
if (!ReadParam(m, iter, quad))
return nullptr;
return quad;
}
bool ParamTraits<viz::RenderPass>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::RenderPass::Read");
uint64_t id;
gfx::Rect output_rect;
gfx::Rect damage_rect;
gfx::Transform transform_to_root_target;
cc::FilterOperations filters;
cc::FilterOperations background_filters;
gfx::ColorSpace color_space;
bool has_transparent_background;
bool cache_render_pass;
bool has_damage_from_contributing_content;
bool generate_mipmap;
uint32_t quad_list_size;
if (!ReadParam(m, iter, &id) || !ReadParam(m, iter, &output_rect) ||
!ReadParam(m, iter, &damage_rect) ||
!ReadParam(m, iter, &transform_to_root_target) ||
!ReadParam(m, iter, &filters) ||
!ReadParam(m, iter, &background_filters) ||
!ReadParam(m, iter, &color_space) ||
!ReadParam(m, iter, &has_transparent_background) ||
!ReadParam(m, iter, &cache_render_pass) ||
!ReadParam(m, iter, &has_damage_from_contributing_content) ||
!ReadParam(m, iter, &generate_mipmap) ||
!ReadParam(m, iter, &quad_list_size))
return false;
p->SetAll(id, output_rect, damage_rect, transform_to_root_target, filters,
background_filters, color_space, has_transparent_background,
cache_render_pass, has_damage_from_contributing_content,
generate_mipmap);
for (uint32_t i = 0; i < quad_list_size; ++i) {
viz::DrawQuad::Material material;
base::PickleIterator temp_iter = *iter;
if (!ReadParam(m, &temp_iter, &material))
return false;
viz::DrawQuad* draw_quad = nullptr;
switch (material) {
case viz::DrawQuad::DEBUG_BORDER:
draw_quad = ReadDrawQuad<viz::DebugBorderDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::PICTURE_CONTENT:
NOTREACHED();
return false;
case viz::DrawQuad::SURFACE_CONTENT:
draw_quad = ReadDrawQuad<viz::SurfaceDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::TEXTURE_CONTENT:
draw_quad = ReadDrawQuad<viz::TextureDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::RENDER_PASS:
draw_quad = ReadDrawQuad<viz::RenderPassDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::SOLID_COLOR:
draw_quad = ReadDrawQuad<viz::SolidColorDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::TILED_CONTENT:
draw_quad = ReadDrawQuad<viz::TileDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::STREAM_VIDEO_CONTENT:
draw_quad = ReadDrawQuad<viz::StreamVideoDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::YUV_VIDEO_CONTENT:
draw_quad = ReadDrawQuad<viz::YUVVideoDrawQuad>(m, iter, p);
break;
case viz::DrawQuad::INVALID:
break;
}
if (!draw_quad)
return false;
if (!draw_quad->rect.Contains(draw_quad->visible_rect)) {
LOG(ERROR) << "Quad with invalid visible rect " << draw_quad->material
<< " rect: " << draw_quad->rect.ToString()
<< " visible_rect: " << draw_quad->visible_rect.ToString();
return false;
}
bool has_new_shared_quad_state;
if (!ReadParam(m, iter, &has_new_shared_quad_state))
return false;
// If the quad has a new shared quad state, read it in.
if (has_new_shared_quad_state) {
viz::SharedQuadState* state = p->CreateAndAppendSharedQuadState();
if (!ReadParam(m, iter, state))
return false;
}
draw_quad->shared_quad_state = p->shared_quad_state_list.back();
}
return true;
}
void ParamTraits<viz::RenderPass>::Log(const param_type& p, std::string* l) {
l->append("RenderPass((");
LogParam(p.id, l);
l->append("), ");
LogParam(p.output_rect, l);
l->append(", ");
LogParam(p.damage_rect, l);
l->append(", ");
LogParam(p.transform_to_root_target, l);
l->append(", ");
LogParam(p.filters, l);
l->append(", ");
LogParam(p.background_filters, l);
l->append(", ");
LogParam(p.color_space, l);
l->append(", ");
LogParam(p.has_transparent_background, l);
l->append(", ");
LogParam(p.cache_render_pass, l);
l->append(", ");
LogParam(p.has_damage_from_contributing_content, l);
l->append(", ");
l->append("[");
for (auto* shared_quad_state : p.shared_quad_state_list) {
if (shared_quad_state != p.shared_quad_state_list.front())
l->append(", ");
LogParam(*shared_quad_state, l);
}
l->append("], [");
for (auto* quad : p.quad_list) {
if (quad != p.quad_list.front())
l->append(", ");
switch (quad->material) {
case viz::DrawQuad::DEBUG_BORDER:
LogParam(*viz::DebugBorderDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::PICTURE_CONTENT:
NOTREACHED();
break;
case viz::DrawQuad::TEXTURE_CONTENT:
LogParam(*viz::TextureDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::RENDER_PASS:
LogParam(*viz::RenderPassDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::SOLID_COLOR:
LogParam(*viz::SolidColorDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::SURFACE_CONTENT:
LogParam(*viz::SurfaceDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::TILED_CONTENT:
LogParam(*viz::TileDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::STREAM_VIDEO_CONTENT:
LogParam(*viz::StreamVideoDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::YUV_VIDEO_CONTENT:
LogParam(*viz::YUVVideoDrawQuad::MaterialCast(quad), l);
break;
case viz::DrawQuad::INVALID:
break;
}
}
l->append("])");
}
void ParamTraits<viz::FrameSinkId>::Write(base::Pickle* m,
const param_type& p) {
DCHECK(p.is_valid());
WriteParam(m, p.client_id());
WriteParam(m, p.sink_id());
}
bool ParamTraits<viz::FrameSinkId>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
uint32_t client_id;
if (!ReadParam(m, iter, &client_id))
return false;
uint32_t sink_id;
if (!ReadParam(m, iter, &sink_id))
return false;
*p = viz::FrameSinkId(client_id, sink_id);
return p->is_valid();
}
void ParamTraits<viz::FrameSinkId>::Log(const param_type& p, std::string* l) {
l->append("viz::FrameSinkId(");
LogParam(p.client_id(), l);
l->append(", ");
LogParam(p.sink_id(), l);
l->append(")");
}
void ParamTraits<viz::LocalSurfaceId>::Write(base::Pickle* m,
const param_type& p) {
DCHECK(p.is_valid());
WriteParam(m, p.parent_sequence_number());
WriteParam(m, p.child_sequence_number());
WriteParam(m, p.nonce());
}
bool ParamTraits<viz::LocalSurfaceId>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
uint32_t parent_sequence_number;
if (!ReadParam(m, iter, &parent_sequence_number))
return false;
uint32_t child_sequence_number;
if (!ReadParam(m, iter, &child_sequence_number))
return false;
base::UnguessableToken nonce;
if (!ReadParam(m, iter, &nonce))
return false;
*p =
viz::LocalSurfaceId(parent_sequence_number, child_sequence_number, nonce);
return p->is_valid();
}
void ParamTraits<viz::LocalSurfaceId>::Log(const param_type& p,
std::string* l) {
l->append("viz::LocalSurfaceId(");
LogParam(p.parent_sequence_number(), l);
l->append(", ");
LogParam(p.child_sequence_number(), l);
l->append(", ");
LogParam(p.nonce(), l);
l->append(")");
}
void ParamTraits<viz::SurfaceId>::Write(base::Pickle* m, const param_type& p) {
WriteParam(m, p.frame_sink_id());
WriteParam(m, p.local_surface_id());
}
bool ParamTraits<viz::SurfaceId>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
viz::FrameSinkId frame_sink_id;
if (!ReadParam(m, iter, &frame_sink_id))
return false;
viz::LocalSurfaceId local_surface_id;
if (!ReadParam(m, iter, &local_surface_id))
return false;
*p = viz::SurfaceId(frame_sink_id, local_surface_id);
return true;
}
void ParamTraits<viz::SurfaceId>::Log(const param_type& p, std::string* l) {
l->append("viz::SurfaceId(");
LogParam(p.frame_sink_id(), l);
l->append(", ");
LogParam(p.local_surface_id(), l);
l->append(")");
}
void ParamTraits<viz::SurfaceInfo>::Write(base::Pickle* m,
const param_type& p) {
WriteParam(m, p.id());
WriteParam(m, p.device_scale_factor());
WriteParam(m, p.size_in_pixels());
}
bool ParamTraits<viz::SurfaceInfo>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
viz::SurfaceId surface_id;
if (!ReadParam(m, iter, &surface_id))
return false;
float device_scale_factor;
if (!ReadParam(m, iter, &device_scale_factor))
return false;
gfx::Size size_in_pixels;
if (!ReadParam(m, iter, &size_in_pixels))
return false;
*p = viz::SurfaceInfo(surface_id, device_scale_factor, size_in_pixels);
return p->is_valid();
}
void ParamTraits<viz::SurfaceInfo>::Log(const param_type& p, std::string* l) {
l->append("viz::SurfaceInfo(");
LogParam(p.id(), l);
l->append(", ");
LogParam(p.device_scale_factor(), l);
l->append(", ");
LogParam(p.size_in_pixels(), l);
l->append(")");
}
void ParamTraits<viz::CompositorFrame>::Write(base::Pickle* m,
const param_type& p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::CompositorFrame::Write");
WriteParam(m, p.metadata);
size_t to_reserve = 0u;
to_reserve += p.resource_list.size() * sizeof(viz::TransferableResource);
for (const auto& pass : p.render_pass_list) {
to_reserve += sizeof(size_t) * 2;
to_reserve += ReserveSizeForRenderPassWrite(*pass);
}
m->Reserve(to_reserve);
WriteParam(m, p.resource_list);
WriteParam(m, base::checked_cast<uint32_t>(p.render_pass_list.size()));
for (const auto& pass : p.render_pass_list) {
WriteParam(m, base::checked_cast<uint32_t>(pass->quad_list.size()));
WriteParam(
m, base::checked_cast<uint32_t>(pass->shared_quad_state_list.size()));
WriteParam(m, *pass);
}
}
bool ParamTraits<viz::CompositorFrame>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::CompositorFrame::Read");
if (!ReadParam(m, iter, &p->metadata))
return false;
const size_t kMaxRenderPasses = 10000;
const size_t kMaxSharedQuadStateListSize = 100000;
const size_t kMaxQuadListSize = 1000000;
std::set<viz::RenderPassId> pass_id_set;
uint32_t num_render_passes;
if (!ReadParam(m, iter, &p->resource_list) ||
!ReadParam(m, iter, &num_render_passes) || num_render_passes == 0 ||
num_render_passes > kMaxRenderPasses)
return false;
for (uint32_t i = 0; i < num_render_passes; ++i) {
uint32_t quad_list_size;
uint32_t shared_quad_state_list_size;
if (!ReadParam(m, iter, &quad_list_size) ||
!ReadParam(m, iter, &shared_quad_state_list_size) ||
quad_list_size > kMaxQuadListSize ||
shared_quad_state_list_size > kMaxSharedQuadStateListSize)
return false;
std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(
static_cast<size_t>(shared_quad_state_list_size),
static_cast<size_t>(quad_list_size));
if (!ReadParam(m, iter, render_pass.get()))
return false;
// Validate that each viz::RenderPassDrawQuad points at a valid RenderPass
// earlier in the frame.
for (const auto* quad : render_pass->quad_list) {
if (quad->material != viz::DrawQuad::RENDER_PASS)
continue;
const viz::RenderPassDrawQuad* rpdq =
viz::RenderPassDrawQuad::MaterialCast(quad);
if (!pass_id_set.count(rpdq->render_pass_id))
return false;
}
pass_id_set.insert(render_pass->id);
p->render_pass_list.push_back(std::move(render_pass));
}
return true;
}
void ParamTraits<viz::CompositorFrame>::Log(const param_type& p,
std::string* l) {
l->append("CompositorFrame(");
LogParam(p.metadata, l);
l->append(", ");
LogParam(p.resource_list, l);
l->append(", [");
for (size_t i = 0; i < p.render_pass_list.size(); ++i) {
if (i)
l->append(", ");
LogParam(*p.render_pass_list[i], l);
}
l->append("])");
}
void ParamTraits<viz::DrawQuad::Resources>::Write(base::Pickle* m,
const param_type& p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::DrawQuad::Resources::Write");
DCHECK_LE(p.count, viz::DrawQuad::Resources::kMaxResourceIdCount);
WriteParam(m, p.count);
for (size_t i = 0; i < p.count; ++i)
WriteParam(m, p.ids[i]);
}
bool ParamTraits<viz::DrawQuad::Resources>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
"ParamTraits::DrawQuad::Resources::Read");
if (!ReadParam(m, iter, &p->count))
return false;
if (p->count > viz::DrawQuad::Resources::kMaxResourceIdCount)
return false;
for (size_t i = 0; i < p->count; ++i) {
if (!ReadParam(m, iter, &p->ids[i]))
return false;
}
return true;
}
void ParamTraits<viz::DrawQuad::Resources>::Log(const param_type& p,
std::string* l) {
l->append("DrawQuad::Resources(");
LogParam(p.count, l);
l->append(", [");
if (p.count > viz::DrawQuad::Resources::kMaxResourceIdCount) {
l->append("])");
return;
}
for (size_t i = 0; i < p.count; ++i) {
LogParam(p.ids[i], l);
if (i < (p.count - 1))
l->append(", ");
}
l->append("])");
}
void ParamTraits<viz::YUVVideoDrawQuad>::Write(base::Pickle* m,
const param_type& p) {
ParamTraits<viz::DrawQuad>::Write(m, p);
WriteParam(m, p.ya_tex_coord_rect);
WriteParam(m, p.uv_tex_coord_rect);
WriteParam(m, p.ya_tex_size);
WriteParam(m, p.uv_tex_size);
WriteParam(m, p.video_color_space);
WriteParam(m, p.resource_offset);
WriteParam(m, p.resource_multiplier);
WriteParam(m, p.bits_per_channel);
}
bool ParamTraits<viz::YUVVideoDrawQuad>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
return ParamTraits<viz::DrawQuad>::Read(m, iter, p) &&
ReadParam(m, iter, &p->ya_tex_coord_rect) &&
ReadParam(m, iter, &p->uv_tex_coord_rect) &&
ReadParam(m, iter, &p->ya_tex_size) &&
ReadParam(m, iter, &p->uv_tex_size) &&
ReadParam(m, iter, &p->video_color_space) &&
ReadParam(m, iter, &p->resource_offset) &&
ReadParam(m, iter, &p->resource_multiplier) &&
ReadParam(m, iter, &p->bits_per_channel) &&
p->bits_per_channel >= viz::YUVVideoDrawQuad::kMinBitsPerChannel &&
p->bits_per_channel <= viz::YUVVideoDrawQuad::kMaxBitsPerChannel;
}
void ParamTraits<viz::YUVVideoDrawQuad>::Log(const param_type& p,
std::string* l) {
l->append("(");
ParamTraits<viz::DrawQuad>::Log(p, l);
l->append(", ");
LogParam(p.ya_tex_coord_rect, l);
l->append(", ");
LogParam(p.uv_tex_coord_rect, l);
l->append(", ");
LogParam(p.ya_tex_size, l);
l->append(", ");
LogParam(p.uv_tex_size, l);
l->append(", ");
LogParam(p.video_color_space, l);
l->append(", ");
LogParam(p.resource_offset, l);
l->append(", ");
LogParam(p.resource_multiplier, l);
l->append(", ");
LogParam(p.bits_per_channel, l);
l->append("])");
}
void ParamTraits<viz::BeginFrameAck>::Write(base::Pickle* m,
const param_type& p) {
m->WriteUInt64(p.sequence_number);
m->WriteUInt64(p.source_id);
// |has_damage| is implicit through IPC message name, so not transmitted.
}
bool ParamTraits<viz::BeginFrameAck>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
return iter->ReadUInt64(&p->sequence_number) &&
p->sequence_number >= viz::BeginFrameArgs::kStartingFrameNumber &&
iter->ReadUInt64(&p->source_id);
}
void ParamTraits<viz::BeginFrameAck>::Log(const param_type& p, std::string* l) {
l->append("(");
LogParam(p.sequence_number, l);
l->append(", ");
LogParam(p.source_id, l);
l->append(")");
}
} // namespace IPC
// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
#include "cc/ipc/cc_param_traits_macros.h"
} // namespace IPC
// Generate param traits read methods.
#include "ipc/param_traits_read_macros.h"
namespace IPC {
#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
#include "cc/ipc/cc_param_traits_macros.h"
} // namespace IPC
// Generate param traits log methods.
#include "ipc/param_traits_log_macros.h"
namespace IPC {
#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
#include "cc/ipc/cc_param_traits_macros.h"
} // namespace IPC