Home | History | Annotate | Download | only in surfaces
      1 // Copyright 2014 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/output/compositor_frame.h"
      6 #include "cc/quads/render_pass.h"
      7 #include "cc/quads/solid_color_draw_quad.h"
      8 #include "cc/quads/surface_draw_quad.h"
      9 #include "cc/surfaces/surface.h"
     10 #include "cc/surfaces/surface_aggregator.h"
     11 #include "cc/surfaces/surface_factory.h"
     12 #include "cc/surfaces/surface_factory_client.h"
     13 #include "cc/surfaces/surface_id_allocator.h"
     14 #include "cc/surfaces/surface_manager.h"
     15 #include "cc/test/pixel_comparator.h"
     16 #include "cc/test/pixel_test.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 #if !defined(OS_ANDROID)
     20 
     21 namespace cc {
     22 namespace {
     23 
     24 class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
     25  public:
     26   virtual void ReturnResources(
     27       const ReturnedResourceArray& resources) OVERRIDE {}
     28 };
     29 
     30 class SurfacesPixelTest : public RendererPixelTest<GLRenderer> {
     31  public:
     32   SurfacesPixelTest() : allocator_(1u), factory_(&manager_, &client_) {}
     33 
     34  protected:
     35   SurfaceManager manager_;
     36   SurfaceIdAllocator allocator_;
     37   EmptySurfaceFactoryClient client_;
     38   SurfaceFactory factory_;
     39 };
     40 
     41 SharedQuadState* CreateAndAppendTestSharedQuadState(
     42     RenderPass* render_pass,
     43     const gfx::Transform& transform,
     44     const gfx::Size& size) {
     45   const gfx::Size content_bounds = size;
     46   const gfx::Rect visible_content_rect = gfx::Rect(size);
     47   const gfx::Rect clip_rect = gfx::Rect(size);
     48   bool is_clipped = false;
     49   float opacity = 1.f;
     50   const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
     51   SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
     52   shared_state->SetAll(transform,
     53                        content_bounds,
     54                        visible_content_rect,
     55                        clip_rect,
     56                        is_clipped,
     57                        opacity,
     58                        blend_mode,
     59                        0);
     60   return shared_state;
     61 }
     62 
     63 // Draws a very simple frame with no surface references.
     64 TEST_F(SurfacesPixelTest, DrawSimpleFrame) {
     65   gfx::Rect rect(device_viewport_size_);
     66   RenderPassId id(1, 1);
     67   scoped_ptr<RenderPass> pass = RenderPass::Create();
     68   pass->SetNew(id, rect, rect, gfx::Transform());
     69 
     70   CreateAndAppendTestSharedQuadState(
     71       pass.get(), gfx::Transform(), device_viewport_size_);
     72 
     73   SolidColorDrawQuad* color_quad =
     74       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
     75   bool force_anti_aliasing_off = false;
     76   color_quad->SetNew(pass->shared_quad_state_list.back(),
     77                      rect,
     78                      rect,
     79                      SK_ColorGREEN,
     80                      force_anti_aliasing_off);
     81 
     82   scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
     83   delegated_frame_data->render_pass_list.push_back(pass.Pass());
     84 
     85   scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
     86   root_frame->delegated_frame_data = delegated_frame_data.Pass();
     87 
     88   SurfaceId root_surface_id = allocator_.GenerateId();
     89   factory_.Create(root_surface_id, device_viewport_size_);
     90   factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure());
     91 
     92   SurfaceAggregator aggregator(&manager_, resource_provider_.get());
     93   scoped_ptr<CompositorFrame> aggregated_frame =
     94       aggregator.Aggregate(root_surface_id);
     95   factory_.Destroy(root_surface_id);
     96 
     97   bool discard_alpha = false;
     98   ExactPixelComparator pixel_comparator(discard_alpha);
     99   RenderPassList* pass_list =
    100       &aggregated_frame->delegated_frame_data->render_pass_list;
    101   EXPECT_TRUE(RunPixelTest(pass_list,
    102                            base::FilePath(FILE_PATH_LITERAL("green.png")),
    103                            pixel_comparator));
    104 }
    105 
    106 // Draws a frame with simple surface embedding.
    107 TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) {
    108   gfx::Size child_size(200, 100);
    109   SurfaceId child_surface_id = allocator_.GenerateId();
    110   SurfaceId root_surface_id = allocator_.GenerateId();
    111   factory_.Create(child_surface_id, child_size);
    112   factory_.Create(root_surface_id, device_viewport_size_);
    113   {
    114     gfx::Rect rect(device_viewport_size_);
    115     RenderPassId id(1, 1);
    116     scoped_ptr<RenderPass> pass = RenderPass::Create();
    117     pass->SetNew(id, rect, rect, gfx::Transform());
    118 
    119     CreateAndAppendTestSharedQuadState(
    120         pass.get(), gfx::Transform(), device_viewport_size_);
    121 
    122     SurfaceDrawQuad* surface_quad =
    123         pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
    124     surface_quad->SetNew(pass->shared_quad_state_list.back(),
    125                          gfx::Rect(child_size),
    126                          gfx::Rect(child_size),
    127                          child_surface_id);
    128 
    129     SolidColorDrawQuad* color_quad =
    130         pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    131     bool force_anti_aliasing_off = false;
    132     color_quad->SetNew(pass->shared_quad_state_list.back(),
    133                        rect,
    134                        rect,
    135                        SK_ColorYELLOW,
    136                        force_anti_aliasing_off);
    137 
    138     scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
    139     delegated_frame_data->render_pass_list.push_back(pass.Pass());
    140 
    141     scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
    142     root_frame->delegated_frame_data = delegated_frame_data.Pass();
    143 
    144     factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure());
    145   }
    146 
    147   {
    148     gfx::Rect rect(child_size);
    149     RenderPassId id(1, 1);
    150     scoped_ptr<RenderPass> pass = RenderPass::Create();
    151     pass->SetNew(id, rect, rect, gfx::Transform());
    152 
    153     CreateAndAppendTestSharedQuadState(
    154         pass.get(), gfx::Transform(), child_size);
    155 
    156     SolidColorDrawQuad* color_quad =
    157         pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    158     bool force_anti_aliasing_off = false;
    159     color_quad->SetNew(pass->shared_quad_state_list.back(),
    160                        rect,
    161                        rect,
    162                        SK_ColorBLUE,
    163                        force_anti_aliasing_off);
    164 
    165     scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
    166     delegated_frame_data->render_pass_list.push_back(pass.Pass());
    167 
    168     scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
    169     child_frame->delegated_frame_data = delegated_frame_data.Pass();
    170 
    171     factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure());
    172   }
    173 
    174   SurfaceAggregator aggregator(&manager_, resource_provider_.get());
    175   scoped_ptr<CompositorFrame> aggregated_frame =
    176       aggregator.Aggregate(root_surface_id);
    177 
    178   bool discard_alpha = false;
    179   ExactPixelComparator pixel_comparator(discard_alpha);
    180   RenderPassList* pass_list =
    181       &aggregated_frame->delegated_frame_data->render_pass_list;
    182   EXPECT_TRUE(RunPixelTest(pass_list,
    183                            base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
    184                            pixel_comparator));
    185   factory_.Destroy(root_surface_id);
    186   factory_.Destroy(child_surface_id);
    187 }
    188 
    189 // Tests a surface quad that has a non-identity transform into its pass.
    190 TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
    191   gfx::Size child_size(100, 200);
    192   gfx::Size quad_size(100, 100);
    193   // Structure:
    194   // root (200x200) -> left_child (100x200 @ 0x0,
    195   //                   right_child (100x200 @ 0x100)
    196   //   left_child -> top_green_quad (100x100 @ 0x0),
    197   //                 bottom_blue_quad (100x100 @ 0x100)
    198   //   right_child -> top_blue_quad (100x100 @ 0x0),
    199   //                  bottom_green_quad (100x100 @ 0x100)
    200   SurfaceId left_child_id = allocator_.GenerateId();
    201   SurfaceId right_child_id = allocator_.GenerateId();
    202   SurfaceId root_surface_id = allocator_.GenerateId();
    203   factory_.Create(left_child_id, child_size);
    204   factory_.Create(right_child_id, child_size);
    205   factory_.Create(root_surface_id, device_viewport_size_);
    206 
    207   {
    208     gfx::Rect rect(device_viewport_size_);
    209     RenderPassId id(1, 1);
    210     scoped_ptr<RenderPass> pass = RenderPass::Create();
    211     pass->SetNew(id, rect, rect, gfx::Transform());
    212 
    213     gfx::Transform surface_transform;
    214     CreateAndAppendTestSharedQuadState(
    215         pass.get(), surface_transform, device_viewport_size_);
    216 
    217     SurfaceDrawQuad* left_surface_quad =
    218         pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
    219     left_surface_quad->SetNew(pass->shared_quad_state_list.back(),
    220                               gfx::Rect(child_size),
    221                               gfx::Rect(child_size),
    222                               left_child_id);
    223 
    224     surface_transform.Translate(100, 0);
    225     CreateAndAppendTestSharedQuadState(
    226         pass.get(), surface_transform, device_viewport_size_);
    227 
    228     SurfaceDrawQuad* right_surface_quad =
    229         pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
    230     right_surface_quad->SetNew(pass->shared_quad_state_list.back(),
    231                                gfx::Rect(child_size),
    232                                gfx::Rect(child_size),
    233                                right_child_id);
    234 
    235     scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
    236     delegated_frame_data->render_pass_list.push_back(pass.Pass());
    237 
    238     scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
    239     root_frame->delegated_frame_data = delegated_frame_data.Pass();
    240 
    241     factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure());
    242   }
    243 
    244   {
    245     gfx::Rect rect(child_size);
    246     RenderPassId id(1, 1);
    247     scoped_ptr<RenderPass> pass = RenderPass::Create();
    248     pass->SetNew(id, rect, rect, gfx::Transform());
    249 
    250     CreateAndAppendTestSharedQuadState(
    251         pass.get(), gfx::Transform(), child_size);
    252 
    253     SolidColorDrawQuad* top_color_quad =
    254         pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    255     bool force_anti_aliasing_off = false;
    256     top_color_quad->SetNew(pass->shared_quad_state_list.back(),
    257                            gfx::Rect(quad_size),
    258                            gfx::Rect(quad_size),
    259                            SK_ColorGREEN,
    260                            force_anti_aliasing_off);
    261 
    262     SolidColorDrawQuad* bottom_color_quad =
    263         pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    264     bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
    265                               gfx::Rect(0, 100, 100, 100),
    266                               gfx::Rect(0, 100, 100, 100),
    267                               SK_ColorBLUE,
    268                               force_anti_aliasing_off);
    269 
    270     scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
    271     delegated_frame_data->render_pass_list.push_back(pass.Pass());
    272 
    273     scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
    274     child_frame->delegated_frame_data = delegated_frame_data.Pass();
    275 
    276     factory_.SubmitFrame(left_child_id, child_frame.Pass(), base::Closure());
    277   }
    278 
    279   {
    280     gfx::Rect rect(child_size);
    281     RenderPassId id(1, 1);
    282     scoped_ptr<RenderPass> pass = RenderPass::Create();
    283     pass->SetNew(id, rect, rect, gfx::Transform());
    284 
    285     CreateAndAppendTestSharedQuadState(
    286         pass.get(), gfx::Transform(), child_size);
    287 
    288     SolidColorDrawQuad* top_color_quad =
    289         pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    290     bool force_anti_aliasing_off = false;
    291     top_color_quad->SetNew(pass->shared_quad_state_list.back(),
    292                            gfx::Rect(quad_size),
    293                            gfx::Rect(quad_size),
    294                            SK_ColorBLUE,
    295                            force_anti_aliasing_off);
    296 
    297     SolidColorDrawQuad* bottom_color_quad =
    298         pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    299     bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
    300                               gfx::Rect(0, 100, 100, 100),
    301                               gfx::Rect(0, 100, 100, 100),
    302                               SK_ColorGREEN,
    303                               force_anti_aliasing_off);
    304 
    305     scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
    306     delegated_frame_data->render_pass_list.push_back(pass.Pass());
    307 
    308     scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
    309     child_frame->delegated_frame_data = delegated_frame_data.Pass();
    310 
    311     factory_.SubmitFrame(right_child_id, child_frame.Pass(), base::Closure());
    312   }
    313 
    314   SurfaceAggregator aggregator(&manager_, resource_provider_.get());
    315   scoped_ptr<CompositorFrame> aggregated_frame =
    316       aggregator.Aggregate(root_surface_id);
    317 
    318   bool discard_alpha = false;
    319   ExactPixelComparator pixel_comparator(discard_alpha);
    320   RenderPassList* pass_list =
    321       &aggregated_frame->delegated_frame_data->render_pass_list;
    322   EXPECT_TRUE(RunPixelTest(
    323       pass_list,
    324       base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
    325       pixel_comparator));
    326 
    327   factory_.Destroy(root_surface_id);
    328   factory_.Destroy(left_child_id);
    329   factory_.Destroy(right_child_id);
    330 }
    331 
    332 }  // namespace
    333 }  // namespace cc
    334 
    335 #endif  // !defined(OS_ANDROID)
    336