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 "cc/quads/draw_quad.h" 6 7 #include <algorithm> 8 9 #include "base/bind.h" 10 #include "base/compiler_specific.h" 11 #include "cc/base/math_util.h" 12 #include "cc/output/filter_operations.h" 13 #include "cc/quads/checkerboard_draw_quad.h" 14 #include "cc/quads/debug_border_draw_quad.h" 15 #include "cc/quads/io_surface_draw_quad.h" 16 #include "cc/quads/picture_draw_quad.h" 17 #include "cc/quads/render_pass_draw_quad.h" 18 #include "cc/quads/solid_color_draw_quad.h" 19 #include "cc/quads/stream_video_draw_quad.h" 20 #include "cc/quads/texture_draw_quad.h" 21 #include "cc/quads/tile_draw_quad.h" 22 #include "cc/quads/yuv_video_draw_quad.h" 23 #include "cc/resources/picture_pile_impl.h" 24 #include "cc/test/geometry_test_utils.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 #include "third_party/skia/include/effects/SkBlurImageFilter.h" 27 #include "ui/gfx/transform.h" 28 29 namespace cc { 30 namespace { 31 32 TEST(DrawQuadTest, CopySharedQuadState) { 33 gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0); 34 gfx::Size content_bounds(26, 28); 35 gfx::Rect visible_content_rect(10, 12, 14, 16); 36 gfx::Rect clip_rect(19, 21, 23, 25); 37 bool is_clipped = true; 38 float opacity = 0.25f; 39 40 scoped_ptr<SharedQuadState> state(SharedQuadState::Create()); 41 state->SetAll(quad_transform, 42 content_bounds, 43 visible_content_rect, 44 clip_rect, 45 is_clipped, 46 opacity); 47 48 scoped_ptr<SharedQuadState> copy(state->Copy()); 49 EXPECT_EQ(quad_transform, copy->content_to_target_transform); 50 EXPECT_RECT_EQ(visible_content_rect, copy->visible_content_rect); 51 EXPECT_EQ(opacity, copy->opacity); 52 EXPECT_RECT_EQ(clip_rect, copy->clip_rect); 53 EXPECT_EQ(is_clipped, copy->is_clipped); 54 } 55 56 scoped_ptr<SharedQuadState> CreateSharedQuadState() { 57 gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0); 58 gfx::Size content_bounds(26, 28); 59 gfx::Rect visible_content_rect(10, 12, 14, 16); 60 gfx::Rect clip_rect(19, 21, 23, 25); 61 bool is_clipped = false; 62 float opacity = 1.f; 63 64 scoped_ptr<SharedQuadState> state(SharedQuadState::Create()); 65 state->SetAll(quad_transform, 66 content_bounds, 67 visible_content_rect, 68 clip_rect, 69 is_clipped, 70 opacity); 71 return state.Pass(); 72 } 73 74 void CompareDrawQuad(DrawQuad* quad, 75 DrawQuad* copy, 76 SharedQuadState* copy_shared_state) { 77 EXPECT_EQ(quad->material, copy->material); 78 EXPECT_RECT_EQ(quad->rect, copy->rect); 79 EXPECT_RECT_EQ(quad->visible_rect, copy->visible_rect); 80 EXPECT_RECT_EQ(quad->opaque_rect, copy->opaque_rect); 81 EXPECT_EQ(quad->needs_blending, copy->needs_blending); 82 EXPECT_EQ(copy_shared_state, copy->shared_quad_state); 83 } 84 85 #define CREATE_SHARED_STATE() \ 86 scoped_ptr<SharedQuadState> shared_state(CreateSharedQuadState()); \ 87 scoped_ptr<SharedQuadState> copy_shared_state(shared_state->Copy()); \ 88 89 #define QUAD_DATA \ 90 gfx::Rect quad_rect(30, 40, 50, 60); \ 91 gfx::Rect quad_visible_rect(40, 50, 30, 20); \ 92 gfx::Rect ALLOW_UNUSED quad_opaque_rect(60, 55, 10, 10); \ 93 bool ALLOW_UNUSED needs_blending = true; 94 95 #define SETUP_AND_COPY_QUAD_NEW(Type, quad) \ 96 scoped_ptr<DrawQuad> copy_new(quad_new->Copy(copy_shared_state.get())); \ 97 CompareDrawQuad(quad_new.get(), copy_new.get(), copy_shared_state.get()); \ 98 const Type* ALLOW_UNUSED copy_quad = Type::MaterialCast(copy_new.get()); 99 100 #define SETUP_AND_COPY_QUAD_ALL(Type, quad) \ 101 scoped_ptr<DrawQuad> copy_all(quad_all->Copy(copy_shared_state.get())); \ 102 CompareDrawQuad(quad_all.get(), copy_all.get(), copy_shared_state.get()); \ 103 copy_quad = Type::MaterialCast(copy_all.get()); 104 105 #define SETUP_AND_COPY_QUAD_NEW_1(Type, quad, a) \ 106 scoped_ptr<DrawQuad> copy_new(quad_new->Copy(copy_shared_state.get(), a)); \ 107 CompareDrawQuad(quad_new.get(), copy_new.get(), copy_shared_state.get()); \ 108 const Type* ALLOW_UNUSED copy_quad = Type::MaterialCast(copy_new.get()); 109 110 #define SETUP_AND_COPY_QUAD_ALL_1(Type, quad, a) \ 111 scoped_ptr<DrawQuad> copy_all(quad_all->Copy(copy_shared_state.get(), a)); \ 112 CompareDrawQuad(quad_all.get(), copy_all.get(), copy_shared_state.get()); \ 113 copy_quad = Type::MaterialCast(copy_all.get()); 114 115 #define CREATE_QUAD_1_NEW(Type, a) \ 116 scoped_ptr<Type> quad_new(Type::Create()); \ 117 { \ 118 QUAD_DATA \ 119 quad_new->SetNew(shared_state.get(), quad_rect, a); \ 120 } \ 121 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 122 123 #define CREATE_QUAD_1_ALL(Type, a) \ 124 scoped_ptr<Type> quad_all(Type::Create()); \ 125 { \ 126 QUAD_DATA \ 127 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 128 quad_visible_rect, needs_blending, a); \ 129 } \ 130 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 131 132 #define CREATE_QUAD_2_NEW(Type, a, b) \ 133 scoped_ptr<Type> quad_new(Type::Create()); \ 134 { \ 135 QUAD_DATA \ 136 quad_new->SetNew(shared_state.get(), quad_rect, a, b); \ 137 } \ 138 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 139 140 #define CREATE_QUAD_2_ALL(Type, a, b) \ 141 scoped_ptr<Type> quad_all(Type::Create()); \ 142 { \ 143 QUAD_DATA \ 144 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 145 quad_visible_rect, needs_blending, a, b); \ 146 } \ 147 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 148 149 #define CREATE_QUAD_3_NEW(Type, a, b, c) \ 150 scoped_ptr<Type> quad_new(Type::Create()); \ 151 { \ 152 QUAD_DATA \ 153 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c); \ 154 } \ 155 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 156 157 #define CREATE_QUAD_3_ALL(Type, a, b, c) \ 158 scoped_ptr<Type> quad_all(Type::Create()); \ 159 { \ 160 QUAD_DATA \ 161 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 162 quad_visible_rect, needs_blending, a, b, c); \ 163 } \ 164 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 165 166 #define CREATE_QUAD_4_NEW(Type, a, b, c, d) \ 167 scoped_ptr<Type> quad_new(Type::Create()); \ 168 { \ 169 QUAD_DATA \ 170 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d); \ 171 } \ 172 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 173 174 #define CREATE_QUAD_4_ALL(Type, a, b, c, d) \ 175 scoped_ptr<Type> quad_all(Type::Create()); \ 176 { \ 177 QUAD_DATA \ 178 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 179 quad_visible_rect, needs_blending, a, b, c, d); \ 180 } \ 181 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 182 183 #define CREATE_QUAD_5_NEW(Type, a, b, c, d, e) \ 184 scoped_ptr<Type> quad_new(Type::Create()); \ 185 { \ 186 QUAD_DATA \ 187 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e); \ 188 } \ 189 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 190 191 #define CREATE_QUAD_5_ALL(Type, a, b, c, d, e) \ 192 scoped_ptr<Type> quad_all(Type::Create()); \ 193 { \ 194 QUAD_DATA \ 195 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 196 quad_visible_rect, needs_blending, a, b, c, d, e); \ 197 } \ 198 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 199 200 #define CREATE_QUAD_5_NEW_1(Type, a, b, c, d, e, copy_a) \ 201 scoped_ptr<Type> quad_new(Type::Create()); \ 202 { \ 203 QUAD_DATA \ 204 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e); \ 205 } \ 206 SETUP_AND_COPY_QUAD_NEW_1(Type, quad_new, copy_a); 207 208 #define CREATE_QUAD_5_ALL_1(Type, a, b, c, d, e, copy_a) \ 209 scoped_ptr<Type> quad_all(Type::Create()); \ 210 { \ 211 QUAD_DATA \ 212 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 213 quad_visible_rect, needs_blending, a, b, c, d, e); \ 214 } \ 215 SETUP_AND_COPY_QUAD_ALL_1(Type, quad_all, copy_a); 216 217 #define CREATE_QUAD_6_NEW(Type, a, b, c, d, e, f) \ 218 scoped_ptr<Type> quad_new(Type::Create()); \ 219 { \ 220 QUAD_DATA \ 221 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f); \ 222 } \ 223 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 224 225 #define CREATE_QUAD_6_ALL(Type, a, b, c, d, e, f) \ 226 scoped_ptr<Type> quad_all(Type::Create()); \ 227 { \ 228 QUAD_DATA \ 229 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 230 quad_visible_rect, needs_blending, a, b, c, d, e, f); \ 231 } \ 232 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 233 234 #define CREATE_QUAD_7_NEW(Type, a, b, c, d, e, f, g) \ 235 scoped_ptr<Type> quad_new(Type::Create()); \ 236 { \ 237 QUAD_DATA \ 238 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f, g); \ 239 } \ 240 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 241 242 #define CREATE_QUAD_7_ALL(Type, a, b, c, d, e, f, g) \ 243 scoped_ptr<Type> quad_all(Type::Create()); \ 244 { \ 245 QUAD_DATA \ 246 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 247 quad_visible_rect, needs_blending, \ 248 a, b, c, d, e, f, g); \ 249 } \ 250 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 251 252 #define CREATE_QUAD_8_NEW(Type, a, b, c, d, e, f, g, h) \ 253 scoped_ptr<Type> quad_new(Type::Create()); \ 254 { \ 255 QUAD_DATA \ 256 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f, g, h); \ 257 } \ 258 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 259 260 #define CREATE_QUAD_8_ALL(Type, a, b, c, d, e, f, g, h) \ 261 scoped_ptr<Type> quad_all(Type::Create()); \ 262 { \ 263 QUAD_DATA \ 264 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 265 quad_visible_rect, needs_blending, \ 266 a, b, c, d, e, f, g, h); \ 267 } \ 268 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 269 270 #define CREATE_QUAD_8_NEW_1(Type, a, b, c, d, e, f, g, h, copy_a) \ 271 scoped_ptr<Type> quad_new(Type::Create()); \ 272 { \ 273 QUAD_DATA \ 274 quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f, g, h); \ 275 } \ 276 SETUP_AND_COPY_QUAD_NEW_1(Type, quad_new, copy_a); 277 278 #define CREATE_QUAD_8_ALL_1(Type, a, b, c, d, e, f, g, h, copy_a) \ 279 scoped_ptr<Type> quad_all(Type::Create()); \ 280 { \ 281 QUAD_DATA \ 282 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 283 quad_visible_rect, needs_blending, \ 284 a, b, c, d, e, f, g, h); \ 285 } \ 286 SETUP_AND_COPY_QUAD_ALL_1(Type, quad_all, copy_a); 287 288 #define CREATE_QUAD_9_NEW(Type, a, b, c, d, e, f, g, h, i) \ 289 scoped_ptr<Type> quad_new(Type::Create()); \ 290 { \ 291 QUAD_DATA \ 292 quad_new->SetNew(shared_state.get(), quad_rect, \ 293 a, b, c, d, e, f, g, h, i); \ 294 } \ 295 SETUP_AND_COPY_QUAD_NEW(Type, quad_new); 296 297 #define CREATE_QUAD_9_ALL(Type, a, b, c, d, e, f, g, h, i) \ 298 scoped_ptr<Type> quad_all(Type::Create()); \ 299 { \ 300 QUAD_DATA \ 301 quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \ 302 quad_visible_rect, needs_blending, \ 303 a, b, c, d, e, f, g, h, i); \ 304 } \ 305 SETUP_AND_COPY_QUAD_ALL(Type, quad_all); 306 307 TEST(DrawQuadTest, CopyCheckerboardDrawQuad) { 308 SkColor color = 0xfabb0011; 309 CREATE_SHARED_STATE(); 310 311 CREATE_QUAD_1_NEW(CheckerboardDrawQuad, color); 312 EXPECT_EQ(DrawQuad::CHECKERBOARD, copy_quad->material); 313 EXPECT_EQ(color, copy_quad->color); 314 315 CREATE_QUAD_1_ALL(CheckerboardDrawQuad, color); 316 EXPECT_EQ(DrawQuad::CHECKERBOARD, copy_quad->material); 317 EXPECT_EQ(color, copy_quad->color); 318 } 319 320 TEST(DrawQuadTest, CopyDebugBorderDrawQuad) { 321 SkColor color = 0xfabb0011; 322 int width = 99; 323 CREATE_SHARED_STATE(); 324 325 CREATE_QUAD_2_NEW(DebugBorderDrawQuad, color, width); 326 EXPECT_EQ(DrawQuad::DEBUG_BORDER, copy_quad->material); 327 EXPECT_EQ(color, copy_quad->color); 328 EXPECT_EQ(width, copy_quad->width); 329 330 CREATE_QUAD_2_ALL(DebugBorderDrawQuad, color, width); 331 EXPECT_EQ(DrawQuad::DEBUG_BORDER, copy_quad->material); 332 EXPECT_EQ(color, copy_quad->color); 333 EXPECT_EQ(width, copy_quad->width); 334 } 335 336 TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) { 337 gfx::Rect opaque_rect(3, 7, 10, 12); 338 gfx::Size size(58, 95); 339 ResourceProvider::ResourceId resource_id = 72; 340 IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED; 341 CREATE_SHARED_STATE(); 342 343 CREATE_QUAD_4_NEW( 344 IOSurfaceDrawQuad, opaque_rect, size, resource_id, orientation); 345 EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material); 346 EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect); 347 EXPECT_EQ(size, copy_quad->io_surface_size); 348 EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id); 349 EXPECT_EQ(orientation, copy_quad->orientation); 350 351 CREATE_QUAD_3_ALL(IOSurfaceDrawQuad, size, resource_id, orientation); 352 EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material); 353 EXPECT_EQ(size, copy_quad->io_surface_size); 354 EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id); 355 EXPECT_EQ(orientation, copy_quad->orientation); 356 } 357 358 TEST(DrawQuadTest, CopyRenderPassDrawQuad) { 359 RenderPass::Id render_pass_id(22, 64); 360 bool is_replica = true; 361 ResourceProvider::ResourceId mask_resource_id = 78; 362 gfx::Rect contents_changed_since_last_frame(42, 11, 74, 24); 363 gfx::RectF mask_u_v_rect(-45.f, -21.f, 33.f, 19.f); 364 FilterOperations filters; 365 filters.Append(FilterOperation::CreateBlurFilter(1.f)); 366 FilterOperations background_filters; 367 background_filters.Append( 368 FilterOperation::CreateGrayscaleFilter(1.f)); 369 skia::RefPtr<SkImageFilter> filter = 370 skia::AdoptRef(new SkBlurImageFilter(SK_Scalar1, SK_Scalar1)); 371 372 RenderPass::Id copied_render_pass_id(235, 11); 373 CREATE_SHARED_STATE(); 374 375 CREATE_QUAD_8_NEW_1(RenderPassDrawQuad, 376 render_pass_id, 377 is_replica, 378 mask_resource_id, 379 contents_changed_since_last_frame, 380 mask_u_v_rect, 381 filters, 382 filter, 383 background_filters, 384 copied_render_pass_id); 385 EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material); 386 EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id); 387 EXPECT_EQ(is_replica, copy_quad->is_replica); 388 EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id); 389 EXPECT_RECT_EQ(contents_changed_since_last_frame, 390 copy_quad->contents_changed_since_last_frame); 391 EXPECT_EQ(mask_u_v_rect.ToString(), copy_quad->mask_uv_rect.ToString()); 392 EXPECT_EQ(filters, copy_quad->filters); 393 EXPECT_EQ(filter, copy_quad->filter); 394 EXPECT_EQ(background_filters, copy_quad->background_filters); 395 396 CREATE_QUAD_8_ALL_1(RenderPassDrawQuad, 397 render_pass_id, 398 is_replica, 399 mask_resource_id, 400 contents_changed_since_last_frame, 401 mask_u_v_rect, 402 filters, 403 filter, 404 background_filters, 405 copied_render_pass_id); 406 EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material); 407 EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id); 408 EXPECT_EQ(is_replica, copy_quad->is_replica); 409 EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id); 410 EXPECT_RECT_EQ(contents_changed_since_last_frame, 411 copy_quad->contents_changed_since_last_frame); 412 EXPECT_EQ(mask_u_v_rect.ToString(), copy_quad->mask_uv_rect.ToString()); 413 EXPECT_EQ(filters, copy_quad->filters); 414 EXPECT_EQ(filter, copy_quad->filter); 415 EXPECT_EQ(background_filters, copy_quad->background_filters); 416 } 417 418 TEST(DrawQuadTest, CopySolidColorDrawQuad) { 419 SkColor color = 0x49494949; 420 bool force_anti_aliasing_off = false; 421 CREATE_SHARED_STATE(); 422 423 CREATE_QUAD_2_NEW(SolidColorDrawQuad, color, force_anti_aliasing_off); 424 EXPECT_EQ(DrawQuad::SOLID_COLOR, copy_quad->material); 425 EXPECT_EQ(color, copy_quad->color); 426 EXPECT_EQ(force_anti_aliasing_off, copy_quad->force_anti_aliasing_off); 427 428 CREATE_QUAD_2_ALL(SolidColorDrawQuad, color, force_anti_aliasing_off); 429 EXPECT_EQ(DrawQuad::SOLID_COLOR, copy_quad->material); 430 EXPECT_EQ(color, copy_quad->color); 431 EXPECT_EQ(force_anti_aliasing_off, copy_quad->force_anti_aliasing_off); 432 } 433 434 TEST(DrawQuadTest, CopyStreamVideoDrawQuad) { 435 gfx::Rect opaque_rect(3, 7, 10, 12); 436 ResourceProvider::ResourceId resource_id = 64; 437 gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1); 438 CREATE_SHARED_STATE(); 439 440 CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, resource_id, matrix); 441 EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material); 442 EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect); 443 EXPECT_EQ(resource_id, copy_quad->resource_id); 444 EXPECT_EQ(matrix, copy_quad->matrix); 445 446 CREATE_QUAD_2_ALL(StreamVideoDrawQuad, resource_id, matrix); 447 EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material); 448 EXPECT_EQ(resource_id, copy_quad->resource_id); 449 EXPECT_EQ(matrix, copy_quad->matrix); 450 } 451 452 TEST(DrawQuadTest, CopyTextureDrawQuad) { 453 gfx::Rect opaque_rect(3, 7, 10, 12); 454 unsigned resource_id = 82; 455 bool premultiplied_alpha = true; 456 gfx::PointF uv_top_left(0.5f, 224.f); 457 gfx::PointF uv_bottom_right(51.5f, 260.f); 458 const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 459 bool flipped = true; 460 CREATE_SHARED_STATE(); 461 462 CREATE_QUAD_8_NEW(TextureDrawQuad, 463 opaque_rect, 464 resource_id, 465 premultiplied_alpha, 466 uv_top_left, 467 uv_bottom_right, 468 SK_ColorTRANSPARENT, 469 vertex_opacity, 470 flipped); 471 EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material); 472 EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect); 473 EXPECT_EQ(resource_id, copy_quad->resource_id); 474 EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha); 475 EXPECT_EQ(uv_top_left, copy_quad->uv_top_left); 476 EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right); 477 EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4); 478 EXPECT_EQ(flipped, copy_quad->flipped); 479 480 CREATE_QUAD_7_ALL(TextureDrawQuad, 481 resource_id, 482 premultiplied_alpha, 483 uv_top_left, 484 uv_bottom_right, 485 SK_ColorTRANSPARENT, 486 vertex_opacity, 487 flipped); 488 EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material); 489 EXPECT_EQ(resource_id, copy_quad->resource_id); 490 EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha); 491 EXPECT_EQ(uv_top_left, copy_quad->uv_top_left); 492 EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right); 493 EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4); 494 EXPECT_EQ(flipped, copy_quad->flipped); 495 } 496 497 TEST(DrawQuadTest, ClipTextureDrawQuad) { 498 gfx::Rect opaque_rect(3, 7, 10, 12); 499 unsigned resource_id = 82; 500 bool premultiplied_alpha = true; 501 bool flipped = true; 502 CREATE_SHARED_STATE(); 503 // The original quad position is (30, 40) its size is 50*60. 504 shared_state->content_to_target_transform = 505 gfx::Transform(1.f, 0.f, 0.f, 1.f, 10.f, 20.f); 506 // After transformation, the quad position is (40, 60) its size is 50*60. 507 shared_state->clip_rect = gfx::Rect(50, 70, 30, 20); 508 509 // The original quad is 'ABCD', the clipped quad is 'abcd': 510 // 40 50 90 511 // B--:-------C 60 512 // | b----c -|-70 513 // | | | | 514 // | a----d -|-90 515 // | | 516 // A----------D 120 517 // UV and vertex opacity are stored per vertex on the parent rectangle 'ABCD'. 518 519 // This is the UV value for vertex 'B'. 520 gfx::PointF uv_top_left(0.1f, 0.2f); 521 // This is the UV value for vertex 'D'. 522 gfx::PointF uv_bottom_right(0.9f, 0.8f); 523 // This the vertex opacity for the vertices 'ABCD'. 524 const float vertex_opacity[] = { 0.3f, 0.4f, 0.7f, 0.8f }; 525 { 526 CREATE_QUAD_8_NEW(TextureDrawQuad, 527 opaque_rect, 528 resource_id, 529 premultiplied_alpha, 530 uv_top_left, 531 uv_bottom_right, 532 SK_ColorTRANSPARENT, 533 vertex_opacity, 534 flipped); 535 CREATE_QUAD_7_ALL(TextureDrawQuad, 536 resource_id, 537 premultiplied_alpha, 538 uv_top_left, 539 uv_bottom_right, 540 SK_ColorTRANSPARENT, 541 vertex_opacity, 542 flipped); 543 EXPECT_TRUE(quad_all->PerformClipping()); 544 545 // This is the expected UV value for vertex 'b'. 546 // uv(b) = uv(B) + (Bb / BD) * (uv(D) - uv(B)) 547 // 0.3 = 0.2 + (10 / 60) * (0.8 - 0.2) 548 gfx::PointF uv_top_left_clipped(0.26f, 0.3f); 549 // This is the expected UV value for vertex 'd'. 550 // uv(d) = uv(B) + (Bd / BD) * (uv(D) - uv(B)) 551 gfx::PointF uv_bottom_right_clipped(0.74f, 0.5f); 552 // This the expected vertex opacity for the vertices 'abcd'. 553 // They are computed with a bilinear interpolation of the corner values. 554 const float vertex_opacity_clipped[] = { 0.43f, 0.45f, 0.65f, 0.67f }; 555 556 EXPECT_EQ(uv_top_left_clipped, quad_all->uv_top_left); 557 EXPECT_EQ(uv_bottom_right_clipped, quad_all->uv_bottom_right); 558 EXPECT_FLOAT_ARRAY_EQ(vertex_opacity_clipped, quad_all->vertex_opacity, 4); 559 } 560 561 uv_top_left = gfx::PointF(0.8f, 0.7f); 562 uv_bottom_right = gfx::PointF(0.2f, 0.1f); 563 { 564 CREATE_QUAD_8_NEW(TextureDrawQuad, 565 opaque_rect, 566 resource_id, 567 premultiplied_alpha, 568 uv_top_left, 569 uv_bottom_right, 570 SK_ColorTRANSPARENT, 571 vertex_opacity, 572 flipped); 573 CREATE_QUAD_7_ALL(TextureDrawQuad, 574 resource_id, 575 premultiplied_alpha, 576 uv_top_left, 577 uv_bottom_right, 578 SK_ColorTRANSPARENT, 579 vertex_opacity, 580 flipped); 581 EXPECT_TRUE(quad_all->PerformClipping()); 582 583 // This is the expected UV value for vertex 'b'. 584 gfx::PointF uv_top_left_clipped(0.68f, 0.6f); 585 // This is the expected UV value for vertex 'd'. 586 gfx::PointF uv_bottom_right_clipped(0.32f, 0.4f); 587 588 EXPECT_EQ(uv_top_left_clipped, quad_all->uv_top_left); 589 EXPECT_EQ(uv_bottom_right_clipped, quad_all->uv_bottom_right); 590 } 591 } 592 593 TEST(DrawQuadTest, CopyTileDrawQuad) { 594 gfx::Rect opaque_rect(33, 44, 22, 33); 595 unsigned resource_id = 104; 596 gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f); 597 gfx::Size texture_size(85, 32); 598 bool swizzle_contents = true; 599 CREATE_SHARED_STATE(); 600 601 CREATE_QUAD_5_NEW(TileDrawQuad, 602 opaque_rect, 603 resource_id, 604 tex_coord_rect, 605 texture_size, 606 swizzle_contents); 607 EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material); 608 EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect); 609 EXPECT_EQ(resource_id, copy_quad->resource_id); 610 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect); 611 EXPECT_EQ(texture_size, copy_quad->texture_size); 612 EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents); 613 614 CREATE_QUAD_4_ALL(TileDrawQuad, 615 resource_id, 616 tex_coord_rect, 617 texture_size, 618 swizzle_contents); 619 EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material); 620 EXPECT_EQ(resource_id, copy_quad->resource_id); 621 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect); 622 EXPECT_EQ(texture_size, copy_quad->texture_size); 623 EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents); 624 } 625 626 TEST(DrawQuadTest, CopyYUVVideoDrawQuad) { 627 gfx::Rect opaque_rect(3, 7, 10, 12); 628 gfx::SizeF tex_scale(0.75f, 0.5f); 629 ResourceProvider::ResourceId y_plane_resource_id = 45; 630 ResourceProvider::ResourceId u_plane_resource_id = 532; 631 ResourceProvider::ResourceId v_plane_resource_id = 4; 632 ResourceProvider::ResourceId a_plane_resource_id = 63; 633 CREATE_SHARED_STATE(); 634 635 CREATE_QUAD_6_NEW(YUVVideoDrawQuad, 636 opaque_rect, 637 tex_scale, 638 y_plane_resource_id, 639 u_plane_resource_id, 640 v_plane_resource_id, 641 a_plane_resource_id); 642 EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material); 643 EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect); 644 EXPECT_EQ(tex_scale, copy_quad->tex_scale); 645 EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id); 646 EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id); 647 EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id); 648 EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id); 649 650 CREATE_QUAD_5_ALL(YUVVideoDrawQuad, 651 tex_scale, 652 y_plane_resource_id, 653 u_plane_resource_id, 654 v_plane_resource_id, 655 a_plane_resource_id); 656 EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material); 657 EXPECT_EQ(tex_scale, copy_quad->tex_scale); 658 EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id); 659 EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id); 660 EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id); 661 EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id); 662 } 663 664 TEST(DrawQuadTest, CopyPictureDrawQuad) { 665 gfx::Rect opaque_rect(33, 44, 22, 33); 666 gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f); 667 gfx::Size texture_size(85, 32); 668 bool swizzle_contents = true; 669 gfx::Rect content_rect(30, 40, 20, 30); 670 float contents_scale = 3.141592f; 671 bool can_draw_direct_to_backbuffer = true; 672 scoped_refptr<PicturePileImpl> picture_pile = PicturePileImpl::Create(); 673 CREATE_SHARED_STATE(); 674 675 CREATE_QUAD_8_NEW(PictureDrawQuad, 676 opaque_rect, 677 tex_coord_rect, 678 texture_size, 679 swizzle_contents, 680 content_rect, 681 contents_scale, 682 can_draw_direct_to_backbuffer, 683 picture_pile); 684 EXPECT_EQ(DrawQuad::PICTURE_CONTENT, copy_quad->material); 685 EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect); 686 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect); 687 EXPECT_EQ(texture_size, copy_quad->texture_size); 688 EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents); 689 EXPECT_RECT_EQ(content_rect, copy_quad->content_rect); 690 EXPECT_EQ(contents_scale, copy_quad->contents_scale); 691 EXPECT_EQ(can_draw_direct_to_backbuffer, 692 copy_quad->can_draw_direct_to_backbuffer); 693 EXPECT_EQ(picture_pile, copy_quad->picture_pile); 694 695 CREATE_QUAD_7_ALL(PictureDrawQuad, 696 tex_coord_rect, 697 texture_size, 698 swizzle_contents, 699 content_rect, 700 contents_scale, 701 can_draw_direct_to_backbuffer, 702 picture_pile); 703 EXPECT_EQ(DrawQuad::PICTURE_CONTENT, copy_quad->material); 704 EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect); 705 EXPECT_EQ(texture_size, copy_quad->texture_size); 706 EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents); 707 EXPECT_RECT_EQ(content_rect, copy_quad->content_rect); 708 EXPECT_EQ(contents_scale, copy_quad->contents_scale); 709 EXPECT_EQ(can_draw_direct_to_backbuffer, 710 copy_quad->can_draw_direct_to_backbuffer); 711 EXPECT_EQ(picture_pile, copy_quad->picture_pile); 712 } 713 714 class DrawQuadIteratorTest : public testing::Test { 715 protected: 716 ResourceProvider::ResourceId IncrementResourceId( 717 ResourceProvider::ResourceId id) { 718 ++num_resources_; 719 return id + 1; 720 } 721 722 int IterateAndCount(DrawQuad* quad) { 723 num_resources_ = 0; 724 quad->IterateResources(base::Bind( 725 &DrawQuadIteratorTest::IncrementResourceId, base::Unretained(this))); 726 return num_resources_; 727 } 728 729 private: 730 int num_resources_; 731 }; 732 733 TEST_F(DrawQuadIteratorTest, CheckerboardDrawQuad) { 734 SkColor color = 0xfabb0011; 735 736 CREATE_SHARED_STATE(); 737 CREATE_QUAD_1_NEW(CheckerboardDrawQuad, color); 738 EXPECT_EQ(0, IterateAndCount(quad_new.get())); 739 } 740 741 TEST_F(DrawQuadIteratorTest, DebugBorderDrawQuad) { 742 SkColor color = 0xfabb0011; 743 int width = 99; 744 745 CREATE_SHARED_STATE(); 746 CREATE_QUAD_2_NEW(DebugBorderDrawQuad, color, width); 747 EXPECT_EQ(0, IterateAndCount(quad_new.get())); 748 } 749 750 TEST_F(DrawQuadIteratorTest, IOSurfaceDrawQuad) { 751 gfx::Rect opaque_rect(3, 7, 10, 12); 752 gfx::Size size(58, 95); 753 ResourceProvider::ResourceId resource_id = 72; 754 IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED; 755 756 CREATE_SHARED_STATE(); 757 CREATE_QUAD_4_NEW( 758 IOSurfaceDrawQuad, opaque_rect, size, resource_id, orientation); 759 EXPECT_EQ(resource_id, quad_new->io_surface_resource_id); 760 EXPECT_EQ(1, IterateAndCount(quad_new.get())); 761 EXPECT_EQ(resource_id + 1, quad_new->io_surface_resource_id); 762 } 763 764 TEST_F(DrawQuadIteratorTest, RenderPassDrawQuad) { 765 RenderPass::Id render_pass_id(22, 64); 766 bool is_replica = true; 767 ResourceProvider::ResourceId mask_resource_id = 78; 768 gfx::Rect contents_changed_since_last_frame(42, 11, 74, 24); 769 gfx::RectF mask_u_v_rect(-45.f, -21.f, 33.f, 19.f); 770 FilterOperations filters; 771 filters.Append(FilterOperation::CreateBlurFilter(1.f)); 772 FilterOperations background_filters; 773 background_filters.Append( 774 FilterOperation::CreateGrayscaleFilter(1.f)); 775 skia::RefPtr<SkImageFilter> filter = 776 skia::AdoptRef(new SkBlurImageFilter(SK_Scalar1, SK_Scalar1)); 777 778 RenderPass::Id copied_render_pass_id(235, 11); 779 780 CREATE_SHARED_STATE(); 781 CREATE_QUAD_8_NEW_1(RenderPassDrawQuad, 782 render_pass_id, 783 is_replica, 784 mask_resource_id, 785 contents_changed_since_last_frame, 786 mask_u_v_rect, 787 filters, 788 filter, 789 background_filters, 790 copied_render_pass_id); 791 EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id); 792 EXPECT_EQ(1, IterateAndCount(quad_new.get())); 793 EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id); 794 quad_new->mask_resource_id = 0; 795 EXPECT_EQ(0, IterateAndCount(quad_new.get())); 796 EXPECT_EQ(0u, quad_new->mask_resource_id); 797 } 798 799 TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) { 800 SkColor color = 0x49494949; 801 bool force_anti_aliasing_off = false; 802 803 CREATE_SHARED_STATE(); 804 CREATE_QUAD_2_NEW(SolidColorDrawQuad, color, force_anti_aliasing_off); 805 EXPECT_EQ(0, IterateAndCount(quad_new.get())); 806 } 807 808 TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) { 809 gfx::Rect opaque_rect(3, 7, 10, 12); 810 ResourceProvider::ResourceId resource_id = 64; 811 gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1); 812 813 CREATE_SHARED_STATE(); 814 CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, resource_id, matrix); 815 EXPECT_EQ(resource_id, quad_new->resource_id); 816 EXPECT_EQ(1, IterateAndCount(quad_new.get())); 817 EXPECT_EQ(resource_id + 1, quad_new->resource_id); 818 } 819 820 TEST_F(DrawQuadIteratorTest, TextureDrawQuad) { 821 gfx::Rect opaque_rect(3, 7, 10, 12); 822 unsigned resource_id = 82; 823 bool premultiplied_alpha = true; 824 gfx::PointF uv_top_left(0.5f, 224.f); 825 gfx::PointF uv_bottom_right(51.5f, 260.f); 826 const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 827 bool flipped = true; 828 829 CREATE_SHARED_STATE(); 830 CREATE_QUAD_8_NEW(TextureDrawQuad, 831 opaque_rect, 832 resource_id, 833 premultiplied_alpha, 834 uv_top_left, 835 uv_bottom_right, 836 SK_ColorTRANSPARENT, 837 vertex_opacity, 838 flipped); 839 EXPECT_EQ(resource_id, quad_new->resource_id); 840 EXPECT_EQ(1, IterateAndCount(quad_new.get())); 841 EXPECT_EQ(resource_id + 1, quad_new->resource_id); 842 } 843 844 TEST_F(DrawQuadIteratorTest, TileDrawQuad) { 845 gfx::Rect opaque_rect(33, 44, 22, 33); 846 unsigned resource_id = 104; 847 gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f); 848 gfx::Size texture_size(85, 32); 849 bool swizzle_contents = true; 850 851 CREATE_SHARED_STATE(); 852 CREATE_QUAD_5_NEW(TileDrawQuad, 853 opaque_rect, 854 resource_id, 855 tex_coord_rect, 856 texture_size, 857 swizzle_contents); 858 EXPECT_EQ(resource_id, quad_new->resource_id); 859 EXPECT_EQ(1, IterateAndCount(quad_new.get())); 860 EXPECT_EQ(resource_id + 1, quad_new->resource_id); 861 } 862 863 TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) { 864 gfx::Rect opaque_rect(3, 7, 10, 12); 865 gfx::SizeF tex_scale(0.75f, 0.5f); 866 ResourceProvider::ResourceId y_plane_resource_id = 45; 867 ResourceProvider::ResourceId u_plane_resource_id = 532; 868 ResourceProvider::ResourceId v_plane_resource_id = 4; 869 ResourceProvider::ResourceId a_plane_resource_id = 63; 870 871 CREATE_SHARED_STATE(); 872 CREATE_QUAD_6_NEW(YUVVideoDrawQuad, 873 opaque_rect, 874 tex_scale, 875 y_plane_resource_id, 876 u_plane_resource_id, 877 v_plane_resource_id, 878 a_plane_resource_id); 879 EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material); 880 EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id); 881 EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id); 882 EXPECT_EQ(v_plane_resource_id, quad_new->v_plane_resource_id); 883 EXPECT_EQ(a_plane_resource_id, quad_new->a_plane_resource_id); 884 EXPECT_EQ(4, IterateAndCount(quad_new.get())); 885 EXPECT_EQ(y_plane_resource_id + 1, quad_new->y_plane_resource_id); 886 EXPECT_EQ(u_plane_resource_id + 1, quad_new->u_plane_resource_id); 887 EXPECT_EQ(v_plane_resource_id + 1, quad_new->v_plane_resource_id); 888 EXPECT_EQ(a_plane_resource_id + 1, quad_new->a_plane_resource_id); 889 } 890 891 // Disabled until picture draw quad is supported for ubercomp: crbug.com/231715 892 TEST_F(DrawQuadIteratorTest, DISABLED_PictureDrawQuad) { 893 gfx::Rect opaque_rect(33, 44, 22, 33); 894 gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f); 895 gfx::Size texture_size(85, 32); 896 bool swizzle_contents = true; 897 gfx::Rect content_rect(30, 40, 20, 30); 898 float contents_scale = 3.141592f; 899 bool can_draw_direct_to_backbuffer = true; 900 scoped_refptr<PicturePileImpl> picture_pile = PicturePileImpl::Create(); 901 902 CREATE_SHARED_STATE(); 903 CREATE_QUAD_8_NEW(PictureDrawQuad, 904 opaque_rect, 905 tex_coord_rect, 906 texture_size, 907 swizzle_contents, 908 content_rect, 909 contents_scale, 910 can_draw_direct_to_backbuffer, 911 picture_pile); 912 EXPECT_EQ(0, IterateAndCount(quad_new.get())); 913 } 914 915 } // namespace 916 } // namespace cc 917