1// Copyright 2013 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/layers/picture_image_layer_impl.h"
6
7#include "cc/layers/append_quads_data.h"
8#include "cc/quads/draw_quad.h"
9#include "cc/resources/tile_priority.h"
10#include "cc/test/fake_impl_proxy.h"
11#include "cc/test/fake_layer_tree_host_impl.h"
12#include "cc/test/fake_output_surface.h"
13#include "cc/test/fake_picture_layer_tiling_client.h"
14#include "cc/test/impl_side_painting_settings.h"
15#include "cc/test/mock_occlusion_tracker.h"
16#include "cc/test/test_shared_bitmap_manager.h"
17#include "cc/trees/layer_tree_impl.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20namespace cc {
21namespace {
22
23class TestablePictureImageLayerImpl : public PictureImageLayerImpl {
24 public:
25  TestablePictureImageLayerImpl(LayerTreeImpl* tree_impl, int id)
26      : PictureImageLayerImpl(tree_impl, id) {
27  }
28  using PictureLayerImpl::UpdateIdealScales;
29  using PictureLayerImpl::MaximumTilingContentsScale;
30  using PictureLayerImpl::DoPostCommitInitializationIfNeeded;
31
32  PictureLayerTilingSet* tilings() { return tilings_.get(); }
33
34  friend class PictureImageLayerImplTest;
35};
36
37class PictureImageLayerImplTest : public testing::Test {
38 public:
39  PictureImageLayerImplTest()
40      : proxy_(base::MessageLoopProxy::current()),
41        host_impl_(ImplSidePaintingSettings(),
42                   &proxy_,
43                   &shared_bitmap_manager_) {
44    tiling_client_.SetTileSize(ImplSidePaintingSettings().default_tile_size);
45    host_impl_.CreatePendingTree();
46    host_impl_.InitializeRenderer(
47        FakeOutputSurface::Create3d().PassAs<OutputSurface>());
48  }
49
50  scoped_ptr<TestablePictureImageLayerImpl> CreateLayer(int id,
51                                                        WhichTree which_tree) {
52    LayerTreeImpl* tree = NULL;
53    switch (which_tree) {
54      case ACTIVE_TREE:
55        tree = host_impl_.active_tree();
56        break;
57      case PENDING_TREE:
58        tree = host_impl_.pending_tree();
59        break;
60      case NUM_TREES:
61        NOTREACHED();
62        break;
63    }
64    TestablePictureImageLayerImpl* layer =
65        new TestablePictureImageLayerImpl(tree, id);
66    layer->SetBounds(gfx::Size(100, 200));
67    layer->SetContentBounds(gfx::Size(100, 200));
68    layer->tilings_.reset(new PictureLayerTilingSet(&tiling_client_,
69                                                    layer->bounds()));
70    layer->pile_ = tiling_client_.GetPile();
71    return make_scoped_ptr(layer);
72  }
73
74  void SetupDrawPropertiesAndUpdateTiles(TestablePictureImageLayerImpl* layer,
75                                         float ideal_contents_scale,
76                                         float device_scale_factor,
77                                         float page_scale_factor,
78                                         float maximum_animation_contents_scale,
79                                         bool animating_transform_to_screen) {
80    layer->draw_properties().ideal_contents_scale = ideal_contents_scale;
81    layer->draw_properties().device_scale_factor = device_scale_factor;
82    layer->draw_properties().page_scale_factor = page_scale_factor;
83    layer->draw_properties().maximum_animation_contents_scale =
84        maximum_animation_contents_scale;
85    layer->draw_properties().screen_space_transform_is_animating =
86        animating_transform_to_screen;
87    bool resourceless_software_draw = false;
88    layer->UpdateTiles(Occlusion(), resourceless_software_draw);
89  }
90
91 protected:
92  FakeImplProxy proxy_;
93  FakeLayerTreeHostImpl host_impl_;
94  TestSharedBitmapManager shared_bitmap_manager_;
95  FakePictureLayerTilingClient tiling_client_;
96};
97
98TEST_F(PictureImageLayerImplTest, CalculateContentsScale) {
99  scoped_ptr<TestablePictureImageLayerImpl> layer(CreateLayer(1, PENDING_TREE));
100  layer->SetDrawsContent(true);
101
102  SetupDrawPropertiesAndUpdateTiles(layer.get(), 2.f, 3.f, 4.f, 1.f, false);
103
104  EXPECT_FLOAT_EQ(1.f, layer->contents_scale_x());
105  EXPECT_FLOAT_EQ(1.f, layer->contents_scale_y());
106  EXPECT_FLOAT_EQ(1.f, layer->MaximumTilingContentsScale());
107}
108
109TEST_F(PictureImageLayerImplTest, IgnoreIdealContentScale) {
110  scoped_ptr<TestablePictureImageLayerImpl> pending_layer(
111      CreateLayer(1, PENDING_TREE));
112  pending_layer->SetDrawsContent(true);
113
114  // Set PictureLayerImpl::ideal_contents_scale_ to 2.f which is not equal
115  // to the content scale used by PictureImageLayerImpl.
116  const float suggested_ideal_contents_scale = 2.f;
117  const float device_scale_factor = 3.f;
118  const float page_scale_factor = 4.f;
119  const float maximum_animation_contents_scale = 1.f;
120  const bool animating_transform_to_screen = false;
121  SetupDrawPropertiesAndUpdateTiles(pending_layer.get(),
122                                    suggested_ideal_contents_scale,
123                                    device_scale_factor,
124                                    page_scale_factor,
125                                    maximum_animation_contents_scale,
126                                    animating_transform_to_screen);
127  EXPECT_EQ(1.f, pending_layer->tilings()->tiling_at(0)->contents_scale());
128
129  // Push to active layer.
130  host_impl_.pending_tree()->SetRootLayer(pending_layer.PassAs<LayerImpl>());
131  host_impl_.ActivateSyncTree();
132  TestablePictureImageLayerImpl* active_layer =
133      static_cast<TestablePictureImageLayerImpl*>(
134          host_impl_.active_tree()->root_layer());
135  SetupDrawPropertiesAndUpdateTiles(active_layer,
136                                    suggested_ideal_contents_scale,
137                                    device_scale_factor,
138                                    page_scale_factor,
139                                    maximum_animation_contents_scale,
140                                    animating_transform_to_screen);
141  EXPECT_EQ(1.f, active_layer->tilings()->tiling_at(0)->contents_scale());
142
143  // Create tile and resource.
144  active_layer->tilings()->tiling_at(0)->CreateAllTilesForTesting();
145  host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(
146      active_layer->tilings()->tiling_at(0)->AllTilesForTesting());
147
148  // Draw.
149  active_layer->draw_properties().visible_content_rect =
150      gfx::Rect(active_layer->bounds());
151  MockOcclusionTracker<LayerImpl> occlusion_tracker;
152  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
153  AppendQuadsData data;
154  active_layer->WillDraw(DRAW_MODE_SOFTWARE, NULL);
155  active_layer->AppendQuads(render_pass.get(), occlusion_tracker, &data);
156  active_layer->DidDraw(NULL);
157
158  EXPECT_EQ(DrawQuad::TILED_CONTENT, render_pass->quad_list.front()->material);
159
160  // Tiles are ready at correct scale, so should not set had_incomplete_tile.
161  EXPECT_EQ(0, data.num_incomplete_tiles);
162}
163
164}  // namespace
165}  // namespace cc
166