Home | History | Annotate | Download | only in quads
      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