1 // Copyright 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 "components/viz/common/quads/draw_quad.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <memory>
11
12 #include "base/bind.h"
13 #include "base/compiler_specific.h"
14 #include "base/logging.h"
15 #include "base/unguessable_token.h"
16 #include "cc/base/math_util.h"
17 #include "cc/paint/filter_operations.h"
18 #include "cc/test/fake_raster_source.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "components/viz/common/quads/aggregated_render_pass.h"
21 #include "components/viz/common/quads/aggregated_render_pass_draw_quad.h"
22 #include "components/viz/common/quads/compositor_render_pass.h"
23 #include "components/viz/common/quads/compositor_render_pass_draw_quad.h"
24 #include "components/viz/common/quads/debug_border_draw_quad.h"
25 #include "components/viz/common/quads/largest_draw_quad.h"
26 #include "components/viz/common/quads/picture_draw_quad.h"
27 #include "components/viz/common/quads/solid_color_draw_quad.h"
28 #include "components/viz/common/quads/stream_video_draw_quad.h"
29 #include "components/viz/common/quads/surface_draw_quad.h"
30 #include "components/viz/common/quads/texture_draw_quad.h"
31 #include "components/viz/common/quads/tile_draw_quad.h"
32 #include "components/viz/common/quads/video_hole_draw_quad.h"
33 #include "components/viz/common/quads/yuv_video_draw_quad.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
36 #include "ui/gfx/hdr_metadata.h"
37 #include "ui/gfx/transform.h"
38
39 namespace viz {
40 namespace {
41
42 static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
43
TEST(DrawQuadTest,CopySharedQuadState)44 TEST(DrawQuadTest, CopySharedQuadState) {
45 gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
46 gfx::Rect layer_rect(26, 28);
47 gfx::Rect visible_layer_rect(10, 12, 14, 16);
48 gfx::Rect clip_rect(19, 21, 23, 25);
49 bool is_clipped = true;
50 bool are_contents_opaque = true;
51 float opacity = 0.25f;
52 SkBlendMode blend_mode = SkBlendMode::kMultiply;
53 int sorting_context_id = 65536;
54
55 auto state = std::make_unique<SharedQuadState>();
56 state->SetAll(quad_transform, layer_rect, visible_layer_rect,
57 gfx::MaskFilterInfo(), clip_rect, is_clipped,
58 are_contents_opaque, opacity, blend_mode, sorting_context_id);
59
60 auto copy = std::make_unique<SharedQuadState>(*state);
61 EXPECT_EQ(quad_transform, copy->quad_to_target_transform);
62 EXPECT_EQ(visible_layer_rect, copy->visible_quad_layer_rect);
63 EXPECT_EQ(opacity, copy->opacity);
64 EXPECT_EQ(clip_rect, copy->clip_rect);
65 EXPECT_EQ(is_clipped, copy->is_clipped);
66 EXPECT_EQ(are_contents_opaque, copy->are_contents_opaque);
67 EXPECT_EQ(blend_mode, copy->blend_mode);
68 }
69
CreateSharedQuadState(CompositorRenderPass * render_pass)70 SharedQuadState* CreateSharedQuadState(CompositorRenderPass* render_pass) {
71 gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
72 gfx::Rect layer_rect(26, 28);
73 gfx::Rect visible_layer_rect(10, 12, 14, 16);
74 gfx::Rect clip_rect(19, 21, 23, 25);
75 bool is_clipped = false;
76 bool are_contents_opaque = true;
77 float opacity = 1.f;
78 int sorting_context_id = 65536;
79 SkBlendMode blend_mode = SkBlendMode::kSrcOver;
80
81 SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState();
82 state->SetAll(quad_transform, layer_rect, visible_layer_rect,
83 gfx::MaskFilterInfo(), clip_rect, is_clipped,
84 are_contents_opaque, opacity, blend_mode, sorting_context_id);
85 return state;
86 }
87
CompareSharedQuadState(const SharedQuadState * source_sqs,const SharedQuadState * copy_sqs)88 void CompareSharedQuadState(const SharedQuadState* source_sqs,
89 const SharedQuadState* copy_sqs) {
90 EXPECT_EQ(source_sqs->quad_to_target_transform,
91 copy_sqs->quad_to_target_transform);
92 EXPECT_EQ(source_sqs->quad_layer_rect, copy_sqs->quad_layer_rect);
93 EXPECT_EQ(source_sqs->visible_quad_layer_rect,
94 copy_sqs->visible_quad_layer_rect);
95 EXPECT_EQ(source_sqs->clip_rect, copy_sqs->clip_rect);
96 EXPECT_EQ(source_sqs->is_clipped, copy_sqs->is_clipped);
97 EXPECT_EQ(source_sqs->opacity, copy_sqs->opacity);
98 EXPECT_EQ(source_sqs->blend_mode, copy_sqs->blend_mode);
99 EXPECT_EQ(source_sqs->sorting_context_id, copy_sqs->sorting_context_id);
100 }
101
CompareDrawQuad(DrawQuad * quad,DrawQuad * copy)102 void CompareDrawQuad(DrawQuad* quad, DrawQuad* copy) {
103 EXPECT_EQ(quad->material, copy->material);
104 EXPECT_EQ(quad->rect, copy->rect);
105 EXPECT_EQ(quad->visible_rect, copy->visible_rect);
106 EXPECT_EQ(quad->needs_blending, copy->needs_blending);
107 CompareSharedQuadState(quad->shared_quad_state, copy->shared_quad_state);
108 }
109
110 #define CREATE_SHARED_STATE() \
111 auto render_pass = CompositorRenderPass::Create(); \
112 SharedQuadState* shared_state(CreateSharedQuadState(render_pass.get())); \
113 SharedQuadState* copy_shared_state = \
114 render_pass->CreateAndAppendSharedQuadState(); \
115 *copy_shared_state = *shared_state;
116
117 #define QUAD_DATA \
118 gfx::Rect quad_rect(30, 40, 50, 60); \
119 gfx::Rect quad_visible_rect(40, 50, 30, 20); \
120 ALLOW_UNUSED_LOCAL(quad_visible_rect); \
121 bool needs_blending = true; \
122 ALLOW_UNUSED_LOCAL(needs_blending);
123
124 #define SETUP_AND_COPY_QUAD_NEW(Type, quad) \
125 DrawQuad* copy_new = render_pass->CopyFromAndAppendDrawQuad(quad_new); \
126 CompareDrawQuad(quad_new, copy_new); \
127 const Type* copy_quad = Type::MaterialCast(copy_new); \
128 ALLOW_UNUSED_LOCAL(copy_quad);
129
130 #define SETUP_AND_COPY_QUAD_ALL(Type, quad) \
131 DrawQuad* copy_all = render_pass->CopyFromAndAppendDrawQuad(quad_all); \
132 CompareDrawQuad(quad_all, copy_all); \
133 copy_quad = Type::MaterialCast(copy_all);
134
135 #define SETUP_AND_COPY_QUAD_NEW_RP(Type, quad, a) \
136 DrawQuad* copy_new = \
137 render_pass->CopyFromAndAppendRenderPassDrawQuad(quad_new, a); \
138 CompareDrawQuad(quad_new, copy_new); \
139 const Type* copy_quad = Type::MaterialCast(copy_new); \
140 ALLOW_UNUSED_LOCAL(copy_quad);
141
142 #define SETUP_AND_COPY_QUAD_ALL_RP(Type, quad, a) \
143 DrawQuad* copy_all = \
144 render_pass->CopyFromAndAppendRenderPassDrawQuad(quad_all, a); \
145 CompareDrawQuad(quad_all, copy_all); \
146 const Type* copy_quad = Type::MaterialCast(copy_all);
147
148 #define CREATE_QUAD_ALL(Type, ...) \
149 Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
150 { \
151 QUAD_DATA quad_all->SetAll(shared_state, quad_rect, quad_visible_rect, \
152 needs_blending, __VA_ARGS__); \
153 } \
154 SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
155
156 #define CREATE_QUAD_NEW(Type, ...) \
157 Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
158 { QUAD_DATA quad_new->SetNew(shared_state, quad_rect, __VA_ARGS__); } \
159 SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
160
161 #define CREATE_QUAD_ALL_RP(Type, a, b, c, d, e, f, g, h, i, j, k, copy_a) \
162 Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
163 { \
164 QUAD_DATA quad_all->SetAll(shared_state, quad_rect, a, needs_blending, b, \
165 c, d, e, f, g, h, i, j, k); \
166 } \
167 SETUP_AND_COPY_QUAD_ALL_RP(Type, quad_all, copy_a);
168
169 #define CREATE_QUAD_NEW_RP(Type, a, b, c, d, e, f, g, h, i, j, copy_a) \
170 Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
171 { \
172 QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c, d, e, f, g, \
173 h, i, j); \
174 } \
175 SETUP_AND_COPY_QUAD_NEW_RP(Type, quad_new, copy_a);
176
TEST(DrawQuadTest,CopyDebugBorderDrawQuad)177 TEST(DrawQuadTest, CopyDebugBorderDrawQuad) {
178 gfx::Rect visible_rect(40, 50, 30, 20);
179 SkColor color = 0xfabb0011;
180 int width = 99;
181 CREATE_SHARED_STATE();
182
183 CREATE_QUAD_NEW(DebugBorderDrawQuad, visible_rect, color, width);
184 EXPECT_EQ(DrawQuad::Material::kDebugBorder, copy_quad->material);
185 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
186 EXPECT_EQ(color, copy_quad->color);
187 EXPECT_EQ(width, copy_quad->width);
188
189 CREATE_QUAD_ALL(DebugBorderDrawQuad, color, width);
190 EXPECT_EQ(DrawQuad::Material::kDebugBorder, copy_quad->material);
191 EXPECT_EQ(color, copy_quad->color);
192 EXPECT_EQ(width, copy_quad->width);
193 }
194
TEST(DrawQuadTest,CopyRenderPassDrawQuad)195 TEST(DrawQuadTest, CopyRenderPassDrawQuad) {
196 gfx::Rect visible_rect(40, 50, 30, 20);
197 CompositorRenderPassId render_pass_id{61};
198 ResourceId mask_resource_id = 78;
199 gfx::RectF mask_uv_rect(0, 0, 33.f, 19.f);
200 gfx::Size mask_texture_size(128, 134);
201 gfx::Vector2dF filters_scale;
202 gfx::PointF filters_origin;
203 gfx::RectF tex_coord_rect(1, 1, 255, 254);
204 bool force_anti_aliasing_off = false;
205 float backdrop_filter_quality = 1.0f;
206 bool can_use_backdrop_filter_cache = true;
207
208 CompositorRenderPassId copied_render_pass_id{235};
209 CREATE_SHARED_STATE();
210
211 CREATE_QUAD_ALL_RP(CompositorRenderPassDrawQuad, visible_rect, render_pass_id,
212 mask_resource_id, mask_uv_rect, mask_texture_size,
213 filters_scale, filters_origin, tex_coord_rect,
214 force_anti_aliasing_off, backdrop_filter_quality,
215 can_use_backdrop_filter_cache, copied_render_pass_id);
216 EXPECT_EQ(DrawQuad::Material::kCompositorRenderPass, copy_quad->material);
217 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
218 EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id);
219 EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id());
220 EXPECT_EQ(mask_uv_rect.ToString(), copy_quad->mask_uv_rect.ToString());
221 EXPECT_EQ(mask_texture_size.ToString(),
222 copy_quad->mask_texture_size.ToString());
223 EXPECT_EQ(filters_scale, copy_quad->filters_scale);
224 EXPECT_EQ(filters_origin, copy_quad->filters_origin);
225 EXPECT_EQ(tex_coord_rect.ToString(), copy_quad->tex_coord_rect.ToString());
226 EXPECT_EQ(force_anti_aliasing_off, copy_quad->force_anti_aliasing_off);
227 EXPECT_EQ(backdrop_filter_quality, copy_quad->backdrop_filter_quality);
228 EXPECT_EQ(can_use_backdrop_filter_cache,
229 copy_quad->can_use_backdrop_filter_cache);
230 }
231
TEST(DrawQuadTest,CopySolidColorDrawQuad)232 TEST(DrawQuadTest, CopySolidColorDrawQuad) {
233 gfx::Rect visible_rect(40, 50, 30, 20);
234 SkColor color = 0x49494949;
235 bool force_anti_aliasing_off = false;
236 CREATE_SHARED_STATE();
237
238 CREATE_QUAD_NEW(SolidColorDrawQuad, visible_rect, color,
239 force_anti_aliasing_off);
240 EXPECT_EQ(DrawQuad::Material::kSolidColor, copy_quad->material);
241 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
242 EXPECT_EQ(color, copy_quad->color);
243 EXPECT_EQ(force_anti_aliasing_off, copy_quad->force_anti_aliasing_off);
244
245 CREATE_QUAD_ALL(SolidColorDrawQuad, color, force_anti_aliasing_off);
246 EXPECT_EQ(DrawQuad::Material::kSolidColor, copy_quad->material);
247 EXPECT_EQ(color, copy_quad->color);
248 EXPECT_EQ(force_anti_aliasing_off, copy_quad->force_anti_aliasing_off);
249 }
250
TEST(DrawQuadTest,CopyStreamVideoDrawQuad)251 TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
252 gfx::Rect visible_rect(40, 50, 30, 20);
253 bool needs_blending = true;
254 ResourceId resource_id = 64;
255 gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
256 gfx::PointF uv_top_left(0.25f, 0.3f);
257 gfx::PointF uv_bottom_right(0.75f, 0.7f);
258 CREATE_SHARED_STATE();
259
260 CREATE_QUAD_NEW(StreamVideoDrawQuad, visible_rect, needs_blending,
261 resource_id, resource_size_in_pixels, uv_top_left,
262 uv_bottom_right);
263 EXPECT_EQ(DrawQuad::Material::kStreamVideoContent, copy_quad->material);
264 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
265 EXPECT_EQ(needs_blending, copy_quad->needs_blending);
266 EXPECT_EQ(resource_id, copy_quad->resource_id());
267 EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
268 EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
269 EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
270
271 CREATE_QUAD_ALL(StreamVideoDrawQuad, resource_id, resource_size_in_pixels,
272 uv_top_left, uv_bottom_right);
273 EXPECT_EQ(DrawQuad::Material::kStreamVideoContent, copy_quad->material);
274 EXPECT_EQ(resource_id, copy_quad->resource_id());
275 EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
276 EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
277 EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
278 }
279
TEST(DrawQuadTest,CopySurfaceDrawQuad)280 TEST(DrawQuadTest, CopySurfaceDrawQuad) {
281 gfx::Rect visible_rect(40, 50, 30, 20);
282 SurfaceId primary_surface_id(
283 kArbitraryFrameSinkId,
284 LocalSurfaceId(1234, base::UnguessableToken::Create()));
285 SurfaceId fallback_surface_id(
286 kArbitraryFrameSinkId,
287 LocalSurfaceId(5678, base::UnguessableToken::Create()));
288 CREATE_SHARED_STATE();
289
290 CREATE_QUAD_NEW(SurfaceDrawQuad, visible_rect,
291 SurfaceRange(fallback_surface_id, primary_surface_id),
292 SK_ColorWHITE, /*stretch_content_to_fill_bounds=*/true);
293 EXPECT_EQ(DrawQuad::Material::kSurfaceContent, copy_quad->material);
294 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
295 EXPECT_EQ(primary_surface_id, copy_quad->surface_range.end());
296 EXPECT_EQ(fallback_surface_id, *copy_quad->surface_range.start());
297 EXPECT_TRUE(copy_quad->stretch_content_to_fill_bounds);
298
299 CREATE_QUAD_ALL(SurfaceDrawQuad,
300 SurfaceRange(fallback_surface_id, primary_surface_id),
301 SK_ColorWHITE, /*stretch_content_to_fill_bounds=*/false,
302 /*is_reflection=*/false, /*allow_merge=*/true);
303 EXPECT_EQ(DrawQuad::Material::kSurfaceContent, copy_quad->material);
304 EXPECT_EQ(primary_surface_id, copy_quad->surface_range.end());
305 EXPECT_EQ(fallback_surface_id, *copy_quad->surface_range.start());
306 EXPECT_FALSE(copy_quad->stretch_content_to_fill_bounds);
307 EXPECT_FALSE(copy_quad->is_reflection);
308 }
309
TEST(DrawQuadTest,CopyTextureDrawQuad)310 TEST(DrawQuadTest, CopyTextureDrawQuad) {
311 gfx::Rect visible_rect(40, 50, 30, 20);
312 bool needs_blending = true;
313 unsigned resource_id = 82;
314 gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
315 bool premultiplied_alpha = true;
316 gfx::PointF uv_top_left(0.5f, 224.f);
317 gfx::PointF uv_bottom_right(51.5f, 260.f);
318 const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
319 bool y_flipped = true;
320 bool nearest_neighbor = true;
321 bool secure_output_only = true;
322 gfx::ProtectedVideoType protected_video_type =
323 gfx::ProtectedVideoType::kSoftwareProtected;
324 CREATE_SHARED_STATE();
325
326 CREATE_QUAD_NEW(TextureDrawQuad, visible_rect, needs_blending, resource_id,
327 premultiplied_alpha, uv_top_left, uv_bottom_right,
328 SK_ColorTRANSPARENT, vertex_opacity, y_flipped,
329 nearest_neighbor, secure_output_only, protected_video_type);
330 EXPECT_EQ(DrawQuad::Material::kTextureContent, copy_quad->material);
331 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
332 EXPECT_EQ(needs_blending, copy_quad->needs_blending);
333 EXPECT_EQ(resource_id, copy_quad->resource_id());
334 EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
335 EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
336 EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
337 EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4);
338 EXPECT_EQ(y_flipped, copy_quad->y_flipped);
339 EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
340 EXPECT_EQ(secure_output_only, copy_quad->secure_output_only);
341 EXPECT_EQ(protected_video_type, copy_quad->protected_video_type);
342
343 CREATE_QUAD_ALL(TextureDrawQuad, resource_id, resource_size_in_pixels,
344 premultiplied_alpha, uv_top_left, uv_bottom_right,
345 SK_ColorTRANSPARENT, vertex_opacity, y_flipped,
346 nearest_neighbor, secure_output_only, protected_video_type);
347 EXPECT_EQ(DrawQuad::Material::kTextureContent, copy_quad->material);
348 EXPECT_EQ(resource_id, copy_quad->resource_id());
349 EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
350 EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
351 EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
352 EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
353 EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4);
354 EXPECT_EQ(y_flipped, copy_quad->y_flipped);
355 EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
356 EXPECT_EQ(secure_output_only, copy_quad->secure_output_only);
357 EXPECT_EQ(protected_video_type, copy_quad->protected_video_type);
358 }
359
TEST(DrawQuadTest,CopyTileDrawQuad)360 TEST(DrawQuadTest, CopyTileDrawQuad) {
361 gfx::Rect visible_rect(40, 50, 30, 20);
362 bool needs_blending = true;
363 unsigned resource_id = 104;
364 gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
365 gfx::Size texture_size(85, 32);
366 bool contents_premultiplied = true;
367 bool nearest_neighbor = true;
368 bool force_anti_aliasing_off = false;
369 CREATE_SHARED_STATE();
370
371 CREATE_QUAD_NEW(TileDrawQuad, visible_rect, needs_blending, resource_id,
372 tex_coord_rect, texture_size, contents_premultiplied,
373 nearest_neighbor, force_anti_aliasing_off);
374 EXPECT_EQ(DrawQuad::Material::kTiledContent, copy_quad->material);
375 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
376 EXPECT_EQ(needs_blending, copy_quad->needs_blending);
377 EXPECT_EQ(resource_id, copy_quad->resource_id());
378 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
379 EXPECT_EQ(texture_size, copy_quad->texture_size);
380 EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
381
382 CREATE_QUAD_ALL(TileDrawQuad, resource_id, tex_coord_rect, texture_size,
383 contents_premultiplied, nearest_neighbor,
384 force_anti_aliasing_off);
385 EXPECT_EQ(DrawQuad::Material::kTiledContent, copy_quad->material);
386 EXPECT_EQ(resource_id, copy_quad->resource_id());
387 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
388 EXPECT_EQ(texture_size, copy_quad->texture_size);
389 EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
390 }
391
TEST(DrawQuadTest,CopyVideoHoleDrawQuad)392 TEST(DrawQuadTest, CopyVideoHoleDrawQuad) {
393 gfx::Rect visible_rect(40, 50, 30, 20);
394 base::UnguessableToken overlay_plane_id = base::UnguessableToken::Create();
395 CREATE_SHARED_STATE();
396
397 CREATE_QUAD_NEW(VideoHoleDrawQuad, visible_rect, overlay_plane_id);
398 EXPECT_EQ(DrawQuad::Material::kVideoHole, copy_quad->material);
399 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
400 EXPECT_EQ(overlay_plane_id, copy_quad->overlay_plane_id);
401
402 CREATE_QUAD_ALL(VideoHoleDrawQuad, overlay_plane_id);
403 EXPECT_EQ(DrawQuad::Material::kVideoHole, copy_quad->material);
404 EXPECT_EQ(overlay_plane_id, copy_quad->overlay_plane_id);
405 }
406
TEST(DrawQuadTest,CopyYUVVideoDrawQuad)407 TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
408 gfx::Rect visible_rect(40, 50, 30, 20);
409 bool needs_blending = true;
410 gfx::RectF ya_tex_coord_rect(40, 50, 30, 20);
411 gfx::RectF uv_tex_coord_rect(20, 25, 15, 10);
412 gfx::Size ya_tex_size(32, 68);
413 gfx::Size uv_tex_size(41, 51);
414 ResourceId y_plane_resource_id = 45;
415 ResourceId u_plane_resource_id = 532;
416 ResourceId v_plane_resource_id = 4;
417 ResourceId a_plane_resource_id = 63;
418 float resource_offset = 0.5f;
419 float resource_multiplier = 2.001f;
420 uint32_t bits_per_channel = 5;
421 gfx::ProtectedVideoType protected_video_type =
422 gfx::ProtectedVideoType::kHardwareProtected;
423 gfx::ColorSpace video_color_space = gfx::ColorSpace::CreateJpeg();
424 gfx::HDRMetadata hdr_metadata = gfx::HDRMetadata();
425 hdr_metadata.max_content_light_level = 1000;
426 hdr_metadata.max_frame_average_light_level = 100;
427
428 CREATE_SHARED_STATE();
429
430 CREATE_QUAD_NEW(YUVVideoDrawQuad, visible_rect, needs_blending,
431 ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
432 uv_tex_size, y_plane_resource_id, u_plane_resource_id,
433 v_plane_resource_id, a_plane_resource_id, video_color_space,
434 resource_offset, resource_multiplier, bits_per_channel);
435 EXPECT_EQ(DrawQuad::Material::kYuvVideoContent, copy_quad->material);
436 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
437 EXPECT_EQ(needs_blending, copy_quad->needs_blending);
438 EXPECT_EQ(ya_tex_coord_rect, copy_quad->ya_tex_coord_rect);
439 EXPECT_EQ(uv_tex_coord_rect, copy_quad->uv_tex_coord_rect);
440 EXPECT_EQ(ya_tex_size, copy_quad->ya_tex_size);
441 EXPECT_EQ(uv_tex_size, copy_quad->uv_tex_size);
442 EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id());
443 EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id());
444 EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id());
445 EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id());
446 EXPECT_EQ(resource_offset, copy_quad->resource_offset);
447 EXPECT_EQ(resource_multiplier, copy_quad->resource_multiplier);
448 EXPECT_EQ(bits_per_channel, copy_quad->bits_per_channel);
449 EXPECT_EQ(gfx::ProtectedVideoType::kClear, copy_quad->protected_video_type);
450 EXPECT_EQ(gfx::HDRMetadata(), copy_quad->hdr_metadata);
451
452 CREATE_QUAD_ALL(YUVVideoDrawQuad, ya_tex_coord_rect, uv_tex_coord_rect,
453 ya_tex_size, uv_tex_size, y_plane_resource_id,
454 u_plane_resource_id, v_plane_resource_id, a_plane_resource_id,
455 video_color_space, resource_offset, resource_multiplier,
456 bits_per_channel, protected_video_type, hdr_metadata);
457 EXPECT_EQ(DrawQuad::Material::kYuvVideoContent, copy_quad->material);
458 EXPECT_EQ(ya_tex_coord_rect, copy_quad->ya_tex_coord_rect);
459 EXPECT_EQ(uv_tex_coord_rect, copy_quad->uv_tex_coord_rect);
460 EXPECT_EQ(ya_tex_size, copy_quad->ya_tex_size);
461 EXPECT_EQ(uv_tex_size, copy_quad->uv_tex_size);
462 EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id());
463 EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id());
464 EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id());
465 EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id());
466 EXPECT_EQ(resource_offset, copy_quad->resource_offset);
467 EXPECT_EQ(resource_multiplier, copy_quad->resource_multiplier);
468 EXPECT_EQ(bits_per_channel, copy_quad->bits_per_channel);
469 EXPECT_EQ(protected_video_type, copy_quad->protected_video_type);
470 EXPECT_EQ(hdr_metadata, copy_quad->hdr_metadata);
471 }
472
TEST(DrawQuadTest,CopyPictureDrawQuad)473 TEST(DrawQuadTest, CopyPictureDrawQuad) {
474 gfx::Rect visible_rect(40, 50, 30, 20);
475 bool needs_blending = true;
476 gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
477 gfx::Size texture_size(85, 32);
478 bool nearest_neighbor = true;
479 ResourceFormat texture_format = RGBA_8888;
480 gfx::Rect content_rect(30, 40, 20, 30);
481 float contents_scale = 3.141592f;
482 scoped_refptr<cc::DisplayItemList> display_item_list =
483 cc::FakeRasterSource::CreateEmpty(gfx::Size(100, 100))
484 ->GetDisplayItemList();
485 CREATE_SHARED_STATE();
486
487 CREATE_QUAD_NEW(PictureDrawQuad, visible_rect, needs_blending, tex_coord_rect,
488 texture_size, nearest_neighbor, texture_format, content_rect,
489 contents_scale, {}, display_item_list);
490 EXPECT_EQ(DrawQuad::Material::kPictureContent, copy_quad->material);
491 EXPECT_EQ(visible_rect, copy_quad->visible_rect);
492 EXPECT_EQ(needs_blending, copy_quad->needs_blending);
493 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
494 EXPECT_EQ(texture_size, copy_quad->texture_size);
495 EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
496 EXPECT_EQ(texture_format, copy_quad->texture_format);
497 EXPECT_EQ(content_rect, copy_quad->content_rect);
498 EXPECT_EQ(contents_scale, copy_quad->contents_scale);
499 EXPECT_EQ(display_item_list, copy_quad->display_item_list);
500
501 CREATE_QUAD_ALL(PictureDrawQuad, tex_coord_rect, texture_size,
502 nearest_neighbor, texture_format, content_rect,
503 contents_scale, {}, display_item_list);
504 EXPECT_EQ(DrawQuad::Material::kPictureContent, copy_quad->material);
505 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
506 EXPECT_EQ(texture_size, copy_quad->texture_size);
507 EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
508 EXPECT_EQ(texture_format, copy_quad->texture_format);
509 EXPECT_EQ(content_rect, copy_quad->content_rect);
510 EXPECT_EQ(contents_scale, copy_quad->contents_scale);
511 EXPECT_EQ(display_item_list, copy_quad->display_item_list);
512 }
513
514 class DrawQuadIteratorTest : public testing::Test {
515 protected:
IterateAndCount(DrawQuad * quad)516 int IterateAndCount(DrawQuad* quad) {
517 num_resources_ = 0;
518 for (ResourceId& resource_id : quad->resources) {
519 ++num_resources_;
520 ++resource_id;
521 }
522 return num_resources_;
523 }
524
525 private:
526 int num_resources_;
527 };
528
TEST_F(DrawQuadIteratorTest,DebugBorderDrawQuad)529 TEST_F(DrawQuadIteratorTest, DebugBorderDrawQuad) {
530 gfx::Rect visible_rect(40, 50, 30, 20);
531 SkColor color = 0xfabb0011;
532 int width = 99;
533
534 CREATE_SHARED_STATE();
535 CREATE_QUAD_NEW(DebugBorderDrawQuad, visible_rect, color, width);
536 EXPECT_EQ(0, IterateAndCount(quad_new));
537 }
538
TEST_F(DrawQuadIteratorTest,CompositorRenderPassDrawQuad)539 TEST_F(DrawQuadIteratorTest, CompositorRenderPassDrawQuad) {
540 gfx::Rect visible_rect(40, 50, 30, 20);
541 CompositorRenderPassId render_pass_id{61};
542 ResourceId mask_resource_id = 78;
543 gfx::RectF mask_uv_rect(0.f, 0.f, 33.f, 19.f);
544 gfx::Size mask_texture_size(128, 134);
545 gfx::Vector2dF filters_scale(2.f, 3.f);
546 gfx::PointF filters_origin(0.f, 0.f);
547 gfx::RectF tex_coord_rect(1.f, 1.f, 33.f, 19.f);
548 bool force_anti_aliasing_off = false;
549 float backdrop_filter_quality = 1.0f;
550 CompositorRenderPassId copied_render_pass_id{235};
551
552 CREATE_SHARED_STATE();
553 CREATE_QUAD_NEW_RP(CompositorRenderPassDrawQuad, visible_rect, render_pass_id,
554 mask_resource_id, mask_uv_rect, mask_texture_size,
555 filters_scale, filters_origin, tex_coord_rect,
556 force_anti_aliasing_off, backdrop_filter_quality,
557 copied_render_pass_id);
558 EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id());
559 EXPECT_EQ(1, IterateAndCount(quad_new));
560 EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id());
561
562 ResourceId new_mask_resource_id = 0;
563 gfx::Rect quad_rect(30, 40, 50, 60);
564 quad_new->SetNew(shared_state, quad_rect, visible_rect, render_pass_id,
565 new_mask_resource_id, mask_uv_rect, mask_texture_size,
566 filters_scale, filters_origin, tex_coord_rect,
567 force_anti_aliasing_off, backdrop_filter_quality);
568 EXPECT_EQ(0, IterateAndCount(quad_new));
569 EXPECT_EQ(0u, quad_new->mask_resource_id());
570 }
571
TEST_F(DrawQuadIteratorTest,SolidColorDrawQuad)572 TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) {
573 gfx::Rect visible_rect(40, 50, 30, 20);
574 SkColor color = 0x49494949;
575 bool force_anti_aliasing_off = false;
576
577 CREATE_SHARED_STATE();
578 CREATE_QUAD_NEW(SolidColorDrawQuad, visible_rect, color,
579 force_anti_aliasing_off);
580 EXPECT_EQ(0, IterateAndCount(quad_new));
581 }
582
TEST_F(DrawQuadIteratorTest,StreamVideoDrawQuad)583 TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
584 gfx::Rect visible_rect(40, 50, 30, 20);
585 ResourceId resource_id = 64;
586 gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
587 gfx::PointF uv_top_left(0.25f, 0.3f);
588 gfx::PointF uv_bottom_right(0.75f, 0.7f);
589
590 CREATE_SHARED_STATE();
591 CREATE_QUAD_NEW(StreamVideoDrawQuad, visible_rect, needs_blending,
592 resource_id, resource_size_in_pixels, uv_top_left,
593 uv_bottom_right);
594 EXPECT_EQ(resource_id, quad_new->resource_id());
595 EXPECT_EQ(resource_size_in_pixels, quad_new->resource_size_in_pixels());
596 EXPECT_EQ(1, IterateAndCount(quad_new));
597 EXPECT_EQ(resource_id + 1, quad_new->resource_id());
598 }
599
TEST_F(DrawQuadIteratorTest,SurfaceDrawQuad)600 TEST_F(DrawQuadIteratorTest, SurfaceDrawQuad) {
601 gfx::Rect visible_rect(40, 50, 30, 20);
602 SurfaceId surface_id(kArbitraryFrameSinkId,
603 LocalSurfaceId(4321, base::UnguessableToken::Create()));
604
605 CREATE_SHARED_STATE();
606 CREATE_QUAD_NEW(SurfaceDrawQuad, visible_rect,
607 SurfaceRange(base::nullopt, surface_id), SK_ColorWHITE,
608 /*stretch_content_to_fill_bounds=*/false);
609 EXPECT_EQ(0, IterateAndCount(quad_new));
610 }
611
TEST_F(DrawQuadIteratorTest,TextureDrawQuad)612 TEST_F(DrawQuadIteratorTest, TextureDrawQuad) {
613 gfx::Rect visible_rect(40, 50, 30, 20);
614 unsigned resource_id = 82;
615 bool premultiplied_alpha = true;
616 gfx::PointF uv_top_left(0.5f, 224.f);
617 gfx::PointF uv_bottom_right(51.5f, 260.f);
618 const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
619 bool y_flipped = true;
620 bool nearest_neighbor = true;
621 bool secure_output_only = true;
622 gfx::ProtectedVideoType protected_video_type =
623 gfx::ProtectedVideoType::kClear;
624
625 CREATE_SHARED_STATE();
626 CREATE_QUAD_NEW(TextureDrawQuad, visible_rect, needs_blending, resource_id,
627 premultiplied_alpha, uv_top_left, uv_bottom_right,
628 SK_ColorTRANSPARENT, vertex_opacity, y_flipped,
629 nearest_neighbor, secure_output_only, protected_video_type);
630 EXPECT_EQ(resource_id, quad_new->resource_id());
631 EXPECT_EQ(1, IterateAndCount(quad_new));
632 EXPECT_EQ(resource_id + 1, quad_new->resource_id());
633 }
634
TEST_F(DrawQuadIteratorTest,TileDrawQuad)635 TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
636 gfx::Rect visible_rect(40, 50, 30, 20);
637 unsigned resource_id = 104;
638 gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
639 gfx::Size texture_size(85, 32);
640 bool contents_premultiplied = true;
641 bool nearest_neighbor = true;
642 bool force_anti_aliasing_off = false;
643
644 CREATE_SHARED_STATE();
645 CREATE_QUAD_NEW(TileDrawQuad, visible_rect, needs_blending, resource_id,
646 tex_coord_rect, texture_size, contents_premultiplied,
647 nearest_neighbor, force_anti_aliasing_off);
648 EXPECT_EQ(resource_id, quad_new->resource_id());
649 EXPECT_EQ(1, IterateAndCount(quad_new));
650 EXPECT_EQ(resource_id + 1, quad_new->resource_id());
651 }
652
TEST_F(DrawQuadIteratorTest,VideoHoleDrawQuad)653 TEST_F(DrawQuadIteratorTest, VideoHoleDrawQuad) {
654 gfx::Rect visible_rect(40, 50, 30, 20);
655 base::UnguessableToken overlay_plane_id = base::UnguessableToken::Create();
656
657 CREATE_SHARED_STATE();
658 CREATE_QUAD_NEW(VideoHoleDrawQuad, visible_rect, overlay_plane_id);
659 EXPECT_EQ(0, IterateAndCount(quad_new));
660 }
661
TEST_F(DrawQuadIteratorTest,YUVVideoDrawQuad)662 TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
663 gfx::Rect visible_rect(40, 50, 30, 20);
664 gfx::RectF ya_tex_coord_rect(0.0f, 0.0f, 0.75f, 0.5f);
665 gfx::RectF uv_tex_coord_rect(0.0f, 0.0f, 0.375f, 0.25f);
666 gfx::Size ya_tex_size(32, 68);
667 gfx::Size uv_tex_size(41, 51);
668 ResourceId y_plane_resource_id = 45;
669 ResourceId u_plane_resource_id = 532;
670 ResourceId v_plane_resource_id = 4;
671 ResourceId a_plane_resource_id = 63;
672 gfx::ColorSpace video_color_space = gfx::ColorSpace::CreateJpeg();
673
674 CREATE_SHARED_STATE();
675 CREATE_QUAD_NEW(YUVVideoDrawQuad, visible_rect, needs_blending,
676 ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
677 uv_tex_size, y_plane_resource_id, u_plane_resource_id,
678 v_plane_resource_id, a_plane_resource_id, video_color_space,
679 0.0, 1.0, 5);
680 EXPECT_EQ(DrawQuad::Material::kYuvVideoContent, copy_quad->material);
681 EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id());
682 EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id());
683 EXPECT_EQ(v_plane_resource_id, quad_new->v_plane_resource_id());
684 EXPECT_EQ(a_plane_resource_id, quad_new->a_plane_resource_id());
685 EXPECT_EQ(4, IterateAndCount(quad_new));
686 EXPECT_EQ(y_plane_resource_id + 1, quad_new->y_plane_resource_id());
687 EXPECT_EQ(u_plane_resource_id + 1, quad_new->u_plane_resource_id());
688 EXPECT_EQ(v_plane_resource_id + 1, quad_new->v_plane_resource_id());
689 EXPECT_EQ(a_plane_resource_id + 1, quad_new->a_plane_resource_id());
690 }
691
TEST(DrawQuadTest,LargestQuadType)692 TEST(DrawQuadTest, LargestQuadType) {
693 size_t largest = 0;
694
695 for (int i = 0; i <= static_cast<int>(DrawQuad::Material::kMaxValue); ++i) {
696 switch (static_cast<DrawQuad::Material>(i)) {
697 case DrawQuad::Material::kAggregatedRenderPass:
698 largest = std::max(largest, sizeof(AggregatedRenderPassDrawQuad));
699 break;
700 case DrawQuad::Material::kDebugBorder:
701 largest = std::max(largest, sizeof(DebugBorderDrawQuad));
702 break;
703 case DrawQuad::Material::kPictureContent:
704 largest = std::max(largest, sizeof(PictureDrawQuad));
705 break;
706 case DrawQuad::Material::kTextureContent:
707 largest = std::max(largest, sizeof(TextureDrawQuad));
708 break;
709 case DrawQuad::Material::kCompositorRenderPass:
710 largest = std::max(largest, sizeof(CompositorRenderPassDrawQuad));
711 break;
712 case DrawQuad::Material::kSolidColor:
713 largest = std::max(largest, sizeof(SolidColorDrawQuad));
714 break;
715 case DrawQuad::Material::kSurfaceContent:
716 largest = std::max(largest, sizeof(SurfaceDrawQuad));
717 break;
718 case DrawQuad::Material::kTiledContent:
719 largest = std::max(largest, sizeof(TileDrawQuad));
720 break;
721 case DrawQuad::Material::kStreamVideoContent:
722 largest = std::max(largest, sizeof(StreamVideoDrawQuad));
723 break;
724 case DrawQuad::Material::kYuvVideoContent:
725 largest = std::max(largest, sizeof(YUVVideoDrawQuad));
726 break;
727 case DrawQuad::Material::kVideoHole:
728 largest = std::max(largest, sizeof(VideoHoleDrawQuad));
729 break;
730 case DrawQuad::Material::kInvalid:
731 break;
732 }
733 }
734 EXPECT_EQ(LargestDrawQuadSize(), largest);
735
736 if (!HasFailure())
737 return;
738
739 // On failure, output the size of all quads for debugging.
740 LOG(ERROR) << "largest " << largest;
741 LOG(ERROR) << "kLargestDrawQuad " << LargestDrawQuadSize();
742 for (int i = 0; i <= static_cast<int>(DrawQuad::Material::kMaxValue); ++i) {
743 switch (static_cast<DrawQuad::Material>(i)) {
744 case DrawQuad::Material::kAggregatedRenderPass:
745 LOG(ERROR) << "AggregatedRenderPass " << sizeof(AggregatedRenderPass);
746 break;
747 case DrawQuad::Material::kDebugBorder:
748 LOG(ERROR) << "DebugBorderDrawQuad " << sizeof(DebugBorderDrawQuad);
749 break;
750 case DrawQuad::Material::kPictureContent:
751 LOG(ERROR) << "PictureDrawQuad " << sizeof(PictureDrawQuad);
752 break;
753 case DrawQuad::Material::kTextureContent:
754 LOG(ERROR) << "TextureDrawQuad " << sizeof(TextureDrawQuad);
755 break;
756 case DrawQuad::Material::kCompositorRenderPass:
757 LOG(ERROR) << "CompositorRenderPassDrawQuad "
758 << sizeof(CompositorRenderPassDrawQuad);
759 break;
760 case DrawQuad::Material::kSolidColor:
761 LOG(ERROR) << "SolidColorDrawQuad " << sizeof(SolidColorDrawQuad);
762 break;
763 case DrawQuad::Material::kSurfaceContent:
764 LOG(ERROR) << "SurfaceDrawQuad " << sizeof(SurfaceDrawQuad);
765 break;
766 case DrawQuad::Material::kTiledContent:
767 LOG(ERROR) << "TileDrawQuad " << sizeof(TileDrawQuad);
768 break;
769 case DrawQuad::Material::kStreamVideoContent:
770 LOG(ERROR) << "StreamVideoDrawQuad " << sizeof(StreamVideoDrawQuad);
771 break;
772 case DrawQuad::Material::kYuvVideoContent:
773 LOG(ERROR) << "YUVVideoDrawQuad " << sizeof(YUVVideoDrawQuad);
774 break;
775 case DrawQuad::Material::kVideoHole:
776 LOG(ERROR) << "VideoHoleDrawQuad " << sizeof(VideoHoleDrawQuad);
777 break;
778 case DrawQuad::Material::kInvalid:
779 break;
780 }
781 }
782 }
783
784 } // namespace
785 } // namespace viz
786