1 // Copyright 2016 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 "services/viz/public/cpp/compositing/quads_mojom_traits.h"
6 
7 #include "services/viz/public/cpp/compositing/compositor_render_pass_id_mojom_traits.h"
8 #include "services/viz/public/cpp/crash_keys.h"
9 #include "ui/gfx/mojom/color_space_mojom_traits.h"
10 #include "ui/gfx/mojom/transform_mojom_traits.h"
11 
12 namespace mojo {
13 
AllocateAndConstruct(viz::mojom::DrawQuadStateDataView::Tag material,viz::QuadList * list)14 viz::DrawQuad* AllocateAndConstruct(
15     viz::mojom::DrawQuadStateDataView::Tag material,
16     viz::QuadList* list) {
17   viz::DrawQuad* quad = nullptr;
18   switch (material) {
19     case viz::mojom::DrawQuadStateDataView::Tag::DEBUG_BORDER_QUAD_STATE:
20       quad = list->AllocateAndConstruct<viz::DebugBorderDrawQuad>();
21       quad->material = viz::DrawQuad::Material::kDebugBorder;
22       return quad;
23     case viz::mojom::DrawQuadStateDataView::Tag::RENDER_PASS_QUAD_STATE:
24       quad = list->AllocateAndConstruct<viz::CompositorRenderPassDrawQuad>();
25       quad->material = viz::DrawQuad::Material::kCompositorRenderPass;
26       return quad;
27     case viz::mojom::DrawQuadStateDataView::Tag::SOLID_COLOR_QUAD_STATE:
28       quad = list->AllocateAndConstruct<viz::SolidColorDrawQuad>();
29       quad->material = viz::DrawQuad::Material::kSolidColor;
30       return quad;
31     case viz::mojom::DrawQuadStateDataView::Tag::STREAM_VIDEO_QUAD_STATE:
32       quad = list->AllocateAndConstruct<viz::StreamVideoDrawQuad>();
33       quad->material = viz::DrawQuad::Material::kStreamVideoContent;
34       return quad;
35     case viz::mojom::DrawQuadStateDataView::Tag::SURFACE_QUAD_STATE:
36       quad = list->AllocateAndConstruct<viz::SurfaceDrawQuad>();
37       quad->material = viz::DrawQuad::Material::kSurfaceContent;
38       return quad;
39     case viz::mojom::DrawQuadStateDataView::Tag::TEXTURE_QUAD_STATE:
40       quad = list->AllocateAndConstruct<viz::TextureDrawQuad>();
41       quad->material = viz::DrawQuad::Material::kTextureContent;
42       return quad;
43     case viz::mojom::DrawQuadStateDataView::Tag::TILE_QUAD_STATE:
44       quad = list->AllocateAndConstruct<viz::TileDrawQuad>();
45       quad->material = viz::DrawQuad::Material::kTiledContent;
46       return quad;
47     case viz::mojom::DrawQuadStateDataView::Tag::VIDEO_HOLE_QUAD_STATE:
48       quad = list->AllocateAndConstruct<viz::VideoHoleDrawQuad>();
49       quad->material = viz::DrawQuad::Material::kVideoHole;
50       return quad;
51     case viz::mojom::DrawQuadStateDataView::Tag::YUV_VIDEO_QUAD_STATE:
52       quad = list->AllocateAndConstruct<viz::YUVVideoDrawQuad>();
53       quad->material = viz::DrawQuad::Material::kYuvVideoContent;
54       return quad;
55   }
56   NOTREACHED();
57   return nullptr;
58 }
59 
60 // static
61 bool StructTraits<viz::mojom::DebugBorderQuadStateDataView, viz::DrawQuad>::
Read(viz::mojom::DebugBorderQuadStateDataView data,viz::DrawQuad * out)62     Read(viz::mojom::DebugBorderQuadStateDataView data, viz::DrawQuad* out) {
63   viz::DebugBorderDrawQuad* quad = static_cast<viz::DebugBorderDrawQuad*>(out);
64   quad->color = data.color();
65   quad->width = data.width();
66   return true;
67 }
68 
69 // static
70 bool StructTraits<
71     viz::mojom::CompositorRenderPassQuadStateDataView,
Read(viz::mojom::CompositorRenderPassQuadStateDataView data,viz::DrawQuad * out)72     viz::DrawQuad>::Read(viz::mojom::CompositorRenderPassQuadStateDataView data,
73                          viz::DrawQuad* out) {
74   auto* quad = static_cast<viz::CompositorRenderPassDrawQuad*>(out);
75   quad->resources.ids[viz::CompositorRenderPassDrawQuad::kMaskResourceIdIndex] =
76       data.mask_resource_id();
77   quad->resources.count = data.mask_resource_id() ? 1 : 0;
78   if (!data.ReadMaskUvRect(&quad->mask_uv_rect) ||
79       !data.ReadMaskTextureSize(&quad->mask_texture_size) ||
80       !data.ReadFiltersScale(&quad->filters_scale) ||
81       !data.ReadFiltersOrigin(&quad->filters_origin) ||
82       !data.ReadTexCoordRect(&quad->tex_coord_rect) ||
83       !data.ReadRenderPassId(&quad->render_pass_id)) {
84     return false;
85   }
86   // CompositorRenderPass ids are never zero.
87   if (!quad->render_pass_id) {
88     viz::SetDeserializationCrashKeyString("Draw quad invalid render pass ID");
89     return false;
90   }
91   quad->force_anti_aliasing_off = data.force_anti_aliasing_off();
92   quad->backdrop_filter_quality = data.backdrop_filter_quality();
93   quad->can_use_backdrop_filter_cache = data.can_use_backdrop_filter_cache();
94   return true;
95 }
96 
97 // static
Read(viz::mojom::SolidColorQuadStateDataView data,viz::DrawQuad * out)98 bool StructTraits<viz::mojom::SolidColorQuadStateDataView, viz::DrawQuad>::Read(
99     viz::mojom::SolidColorQuadStateDataView data,
100     viz::DrawQuad* out) {
101   viz::SolidColorDrawQuad* quad = static_cast<viz::SolidColorDrawQuad*>(out);
102   quad->force_anti_aliasing_off = data.force_anti_aliasing_off();
103   quad->color = data.color();
104   return true;
105 }
106 
107 // static
108 bool StructTraits<viz::mojom::StreamVideoQuadStateDataView, viz::DrawQuad>::
Read(viz::mojom::StreamVideoQuadStateDataView data,viz::DrawQuad * out)109     Read(viz::mojom::StreamVideoQuadStateDataView data, viz::DrawQuad* out) {
110   auto* quad = static_cast<viz::StreamVideoDrawQuad*>(out);
111   quad->resources.ids[viz::StreamVideoDrawQuad::kResourceIdIndex] =
112       data.resource_id();
113   quad->resources.count = 1;
114   return data.ReadResourceSizeInPixels(
115              &quad->overlay_resources.size_in_pixels) &&
116          data.ReadUvTopLeft(&quad->uv_top_left) &&
117          data.ReadUvBottomRight(&quad->uv_bottom_right);
118 }
119 
120 // static
Read(viz::mojom::SurfaceQuadStateDataView data,viz::DrawQuad * out)121 bool StructTraits<viz::mojom::SurfaceQuadStateDataView, viz::DrawQuad>::Read(
122     viz::mojom::SurfaceQuadStateDataView data,
123     viz::DrawQuad* out) {
124   viz::SurfaceDrawQuad* quad = static_cast<viz::SurfaceDrawQuad*>(out);
125   quad->default_background_color = data.default_background_color();
126   quad->stretch_content_to_fill_bounds = data.stretch_content_to_fill_bounds();
127   quad->is_reflection = data.is_reflection();
128   quad->allow_merge = data.allow_merge();
129   return data.ReadSurfaceRange(&quad->surface_range);
130 }
131 
132 // static
Read(viz::mojom::TextureQuadStateDataView data,viz::DrawQuad * out)133 bool StructTraits<viz::mojom::TextureQuadStateDataView, viz::DrawQuad>::Read(
134     viz::mojom::TextureQuadStateDataView data,
135     viz::DrawQuad* out) {
136   auto* quad = static_cast<viz::TextureDrawQuad*>(out);
137 
138   quad->resources.ids[viz::TextureDrawQuad::kResourceIdIndex] =
139       data.resource_id();
140   if (!data.ReadResourceSizeInPixels(&quad->overlay_resources.size_in_pixels)) {
141     return false;
142   }
143 
144   quad->resources.count = 1;
145   quad->premultiplied_alpha = data.premultiplied_alpha();
146   gfx::ProtectedVideoType protected_video_type =
147       gfx::ProtectedVideoType::kClear;
148   if (!data.ReadUvTopLeft(&quad->uv_top_left) ||
149       !data.ReadUvBottomRight(&quad->uv_bottom_right) ||
150       !data.ReadProtectedVideoType(&protected_video_type)) {
151     return false;
152   }
153   quad->protected_video_type = protected_video_type;
154   quad->background_color = data.background_color();
155   base::span<float> vertex_opacity_array(quad->vertex_opacity);
156   if (!data.ReadVertexOpacity(&vertex_opacity_array))
157     return false;
158 
159   quad->y_flipped = data.y_flipped();
160   quad->nearest_neighbor = data.nearest_neighbor();
161   quad->secure_output_only = data.secure_output_only();
162   quad->is_video_frame = data.is_video_frame();
163   return true;
164 }
165 
166 // static
Read(viz::mojom::TileQuadStateDataView data,viz::DrawQuad * out)167 bool StructTraits<viz::mojom::TileQuadStateDataView, viz::DrawQuad>::Read(
168     viz::mojom::TileQuadStateDataView data,
169     viz::DrawQuad* out) {
170   viz::TileDrawQuad* quad = static_cast<viz::TileDrawQuad*>(out);
171   if (!data.ReadTexCoordRect(&quad->tex_coord_rect) ||
172       !data.ReadTextureSize(&quad->texture_size)) {
173     return false;
174   }
175 
176   quad->is_premultiplied = data.is_premultiplied();
177   quad->nearest_neighbor = data.nearest_neighbor();
178   quad->force_anti_aliasing_off = data.force_anti_aliasing_off();
179   quad->resources.ids[viz::TileDrawQuad::kResourceIdIndex] = data.resource_id();
180   quad->resources.count = 1;
181   return true;
182 }
183 
184 // static
Read(viz::mojom::VideoHoleQuadStateDataView data,viz::DrawQuad * out)185 bool StructTraits<viz::mojom::VideoHoleQuadStateDataView, viz::DrawQuad>::Read(
186     viz::mojom::VideoHoleQuadStateDataView data,
187     viz::DrawQuad* out) {
188   viz::VideoHoleDrawQuad* video_hole_quad =
189       static_cast<viz::VideoHoleDrawQuad*>(out);
190   return data.ReadOverlayPlaneId(&video_hole_quad->overlay_plane_id);
191 }
192 
193 // static
Read(viz::mojom::YUVVideoQuadStateDataView data,viz::DrawQuad * out)194 bool StructTraits<viz::mojom::YUVVideoQuadStateDataView, viz::DrawQuad>::Read(
195     viz::mojom::YUVVideoQuadStateDataView data,
196     viz::DrawQuad* out) {
197   viz::YUVVideoDrawQuad* quad = static_cast<viz::YUVVideoDrawQuad*>(out);
198   if (!data.ReadYaTexCoordRect(&quad->ya_tex_coord_rect) ||
199       !data.ReadUvTexCoordRect(&quad->uv_tex_coord_rect) ||
200       !data.ReadYaTexSize(&quad->ya_tex_size) ||
201       !data.ReadUvTexSize(&quad->uv_tex_size) ||
202       !data.ReadVideoColorSpace(&quad->video_color_space) ||
203       !data.ReadProtectedVideoType(&quad->protected_video_type) ||
204       !data.ReadHdrMetadata(&quad->hdr_metadata)) {
205     return false;
206   }
207   quad->resources.ids[viz::YUVVideoDrawQuad::kYPlaneResourceIdIndex] =
208       data.y_plane_resource_id();
209   quad->resources.ids[viz::YUVVideoDrawQuad::kUPlaneResourceIdIndex] =
210       data.u_plane_resource_id();
211   quad->resources.ids[viz::YUVVideoDrawQuad::kVPlaneResourceIdIndex] =
212       data.v_plane_resource_id();
213   quad->resources.ids[viz::YUVVideoDrawQuad::kAPlaneResourceIdIndex] =
214       data.a_plane_resource_id();
215   static_assert(viz::YUVVideoDrawQuad::kAPlaneResourceIdIndex ==
216                     viz::DrawQuad::Resources::kMaxResourceIdCount - 1,
217                 "The A plane resource should be the last resource ID.");
218   quad->resources.count = data.a_plane_resource_id() ? 4 : 3;
219 
220   quad->resource_offset = data.resource_offset();
221   quad->resource_multiplier = data.resource_multiplier();
222   quad->bits_per_channel = data.bits_per_channel();
223   if (quad->bits_per_channel < viz::YUVVideoDrawQuad::kMinBitsPerChannel) {
224     viz::SetDeserializationCrashKeyString("Bits per channel too small");
225     return false;
226   }
227   if (quad->bits_per_channel > viz::YUVVideoDrawQuad::kMaxBitsPerChannel) {
228     viz::SetDeserializationCrashKeyString("Bits per channel too big");
229     return false;
230   }
231   return true;
232 }
233 
234 // static
Read(viz::mojom::DrawQuadDataView data,viz::DrawQuad * out)235 bool StructTraits<viz::mojom::DrawQuadDataView, viz::DrawQuad>::Read(
236     viz::mojom::DrawQuadDataView data,
237     viz::DrawQuad* out) {
238   if (!data.ReadRect(&out->rect) || !data.ReadVisibleRect(&out->visible_rect)) {
239     return false;
240   }
241   if (!out->rect.Contains(out->visible_rect)) {
242     viz::SetDeserializationCrashKeyString("Rect does not contain visible rect");
243     return false;
244   }
245 
246   out->needs_blending = data.needs_blending();
247   return data.ReadDrawQuadState(out);
248 }
249 
250 }  // namespace mojo
251