1// Copyright 2011 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#ifndef CC_TREES_LAYER_TREE_HOST_COMMON_H_
6#define CC_TREES_LAYER_TREE_HOST_COMMON_H_
7
8#include <limits>
9#include <vector>
10
11#include "base/bind.h"
12#include "base/memory/ref_counted.h"
13#include "cc/base/cc_export.h"
14#include "cc/base/scoped_ptr_vector.h"
15#include "cc/layers/layer_lists.h"
16#include "ui/gfx/rect.h"
17#include "ui/gfx/transform.h"
18#include "ui/gfx/vector2d.h"
19
20namespace cc {
21
22class LayerImpl;
23class Layer;
24
25class CC_EXPORT LayerTreeHostCommon {
26 public:
27  static gfx::Rect CalculateVisibleRect(gfx::Rect target_surface_rect,
28                                        gfx::Rect layer_bound_rect,
29                                        const gfx::Transform& transform);
30
31  template <typename LayerType, typename RenderSurfaceLayerListType>
32  struct CalcDrawPropsInputs {
33   public:
34    CalcDrawPropsInputs(LayerType* root_layer,
35                        gfx::Size device_viewport_size,
36                        const gfx::Transform& device_transform,
37                        float device_scale_factor,
38                        float page_scale_factor,
39                        const LayerType* page_scale_application_layer,
40                        int max_texture_size,
41                        bool can_use_lcd_text,
42                        bool can_render_to_separate_surface,
43                        bool can_adjust_raster_scales,
44                        RenderSurfaceLayerListType* render_surface_layer_list)
45        : root_layer(root_layer),
46          device_viewport_size(device_viewport_size),
47          device_transform(device_transform),
48          device_scale_factor(device_scale_factor),
49          page_scale_factor(page_scale_factor),
50          page_scale_application_layer(page_scale_application_layer),
51          max_texture_size(max_texture_size),
52          can_use_lcd_text(can_use_lcd_text),
53          can_render_to_separate_surface(can_render_to_separate_surface),
54          can_adjust_raster_scales(can_adjust_raster_scales),
55          render_surface_layer_list(render_surface_layer_list) {}
56
57    LayerType* root_layer;
58    gfx::Size device_viewport_size;
59    const gfx::Transform& device_transform;
60    float device_scale_factor;
61    float page_scale_factor;
62    const LayerType* page_scale_application_layer;
63    int max_texture_size;
64    bool can_use_lcd_text;
65    bool can_render_to_separate_surface;
66    bool can_adjust_raster_scales;
67    RenderSurfaceLayerListType* render_surface_layer_list;
68  };
69
70  template <typename LayerType, typename RenderSurfaceLayerListType>
71  struct CalcDrawPropsInputsForTesting
72      : public CalcDrawPropsInputs<LayerType, RenderSurfaceLayerListType> {
73    CalcDrawPropsInputsForTesting(
74        LayerType* root_layer,
75        gfx::Size device_viewport_size,
76        const gfx::Transform& device_transform,
77        RenderSurfaceLayerListType* render_surface_layer_list);
78    CalcDrawPropsInputsForTesting(
79        LayerType* root_layer,
80        gfx::Size device_viewport_size,
81        RenderSurfaceLayerListType* render_surface_layer_list);
82
83   private:
84    const gfx::Transform identity_transform_;
85  };
86
87  typedef CalcDrawPropsInputs<Layer, RenderSurfaceLayerList>
88      CalcDrawPropsMainInputs;
89  typedef CalcDrawPropsInputsForTesting<Layer, RenderSurfaceLayerList>
90      CalcDrawPropsMainInputsForTesting;
91  static void CalculateDrawProperties(CalcDrawPropsMainInputs* inputs);
92
93  typedef CalcDrawPropsInputs<LayerImpl, LayerImplList> CalcDrawPropsImplInputs;
94  typedef CalcDrawPropsInputsForTesting<LayerImpl, LayerImplList>
95      CalcDrawPropsImplInputsForTesting;
96  static void CalculateDrawProperties(CalcDrawPropsImplInputs* inputs);
97
98  // Performs hit testing for a given render_surface_layer_list.
99  static LayerImpl* FindLayerThatIsHitByPoint(
100      gfx::PointF screen_space_point,
101      const LayerImplList& render_surface_layer_list);
102
103  static LayerImpl* FindLayerThatIsHitByPointInTouchHandlerRegion(
104      gfx::PointF screen_space_point,
105      const LayerImplList& render_surface_layer_list);
106
107  static bool LayerHasTouchEventHandlersAt(gfx::PointF screen_space_point,
108                                           LayerImpl* layer_impl);
109
110  template <typename LayerType>
111  static bool RenderSurfaceContributesToTarget(LayerType*,
112                                               int target_surface_layer_id);
113
114  template <typename LayerType>
115  static void CallFunctionForSubtree(
116      LayerType* root_layer,
117      const base::Callback<void(LayerType* layer)>& function);
118
119  // Returns a layer with the given id if one exists in the subtree starting
120  // from the given root layer (including mask and replica layers).
121  template <typename LayerType>
122  static LayerType* FindLayerInSubtree(LayerType* root_layer, int layer_id);
123
124  static Layer* get_child_as_raw_ptr(
125      const LayerList& children,
126      size_t index) {
127    return children[index].get();
128  }
129
130  static LayerImpl* get_child_as_raw_ptr(
131      const OwnedLayerImplList& children,
132      size_t index) {
133    return children[index];
134  }
135
136  struct ScrollUpdateInfo {
137    int layer_id;
138    gfx::Vector2d scroll_delta;
139  };
140};
141
142struct CC_EXPORT ScrollAndScaleSet {
143  ScrollAndScaleSet();
144  ~ScrollAndScaleSet();
145
146  std::vector<LayerTreeHostCommon::ScrollUpdateInfo> scrolls;
147  float page_scale_delta;
148};
149
150template <typename LayerType>
151bool LayerTreeHostCommon::RenderSurfaceContributesToTarget(
152    LayerType* layer,
153    int target_surface_layer_id) {
154  // A layer will either contribute its own content, or its render surface's
155  // content, to the target surface. The layer contributes its surface's content
156  // when both the following are true:
157  //  (1) The layer actually has a render surface, and
158  //  (2) The layer's render surface is not the same as the target surface.
159  //
160  // Otherwise, the layer just contributes itself to the target surface.
161
162  return layer->render_surface() && layer->id() != target_surface_layer_id;
163}
164
165template <typename LayerType>
166LayerType* LayerTreeHostCommon::FindLayerInSubtree(LayerType* root_layer,
167                                                   int layer_id) {
168  if (!root_layer)
169    return NULL;
170
171  if (root_layer->id() == layer_id)
172    return root_layer;
173
174  if (root_layer->mask_layer() && root_layer->mask_layer()->id() == layer_id)
175    return root_layer->mask_layer();
176
177  if (root_layer->replica_layer() &&
178      root_layer->replica_layer()->id() == layer_id)
179    return root_layer->replica_layer();
180
181  for (size_t i = 0; i < root_layer->children().size(); ++i) {
182    if (LayerType* found = FindLayerInSubtree(
183            get_child_as_raw_ptr(root_layer->children(), i), layer_id))
184      return found;
185  }
186  return NULL;
187}
188
189template <typename LayerType>
190void LayerTreeHostCommon::CallFunctionForSubtree(
191    LayerType* root_layer,
192    const base::Callback<void(LayerType* layer)>& function) {
193  function.Run(root_layer);
194
195  if (LayerType* mask_layer = root_layer->mask_layer())
196    function.Run(mask_layer);
197  if (LayerType* replica_layer = root_layer->replica_layer()) {
198    function.Run(replica_layer);
199    if (LayerType* mask_layer = replica_layer->mask_layer())
200      function.Run(mask_layer);
201  }
202
203  for (size_t i = 0; i < root_layer->children().size(); ++i) {
204    CallFunctionForSubtree(get_child_as_raw_ptr(root_layer->children(), i),
205                           function);
206  }
207}
208
209template <typename LayerType, typename RenderSurfaceLayerListType>
210LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
211                                                   RenderSurfaceLayerListType>::
212    CalcDrawPropsInputsForTesting(
213        LayerType* root_layer,
214        gfx::Size device_viewport_size,
215        const gfx::Transform& device_transform,
216        RenderSurfaceLayerListType* render_surface_layer_list)
217    : CalcDrawPropsInputs<LayerType, RenderSurfaceLayerListType>(
218          root_layer,
219          device_viewport_size,
220          device_transform,
221          1.f,
222          1.f,
223          NULL,
224          std::numeric_limits<int>::max() / 2,
225          false,
226          true,
227          false,
228          render_surface_layer_list) {
229  DCHECK(root_layer);
230  DCHECK(render_surface_layer_list);
231}
232
233template <typename LayerType, typename RenderSurfaceLayerListType>
234LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
235                                                   RenderSurfaceLayerListType>::
236    CalcDrawPropsInputsForTesting(
237        LayerType* root_layer,
238        gfx::Size device_viewport_size,
239        RenderSurfaceLayerListType* render_surface_layer_list)
240    : CalcDrawPropsInputs<LayerType, RenderSurfaceLayerListType>(
241          root_layer,
242          device_viewport_size,
243          identity_transform_,
244          1.f,
245          1.f,
246          NULL,
247          std::numeric_limits<int>::max() / 2,
248          false,
249          true,
250          false,
251          render_surface_layer_list) {
252  DCHECK(root_layer);
253  DCHECK(render_surface_layer_list);
254}
255
256}  // namespace cc
257
258#endif  // CC_TREES_LAYER_TREE_HOST_COMMON_H_
259