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.
5 #ifndef CC_TILES_PICTURE_LAYER_TILING_H_
6 #define CC_TILES_PICTURE_LAYER_TILING_H_
12 #include "base/basictypes.h"
13 #include "base/containers/scoped_ptr_hash_map.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "cc/base/cc_export.h"
16 #include "cc/base/region.h"
17 #include "cc/base/tiling_data.h"
18 #include "cc/tiles/tile.h"
19 #include "cc/tiles/tile_priority.h"
20 #include "cc/trees/occlusion.h"
21 #include "ui/gfx/geometry/rect.h"
24 namespace trace_event
{
31 class PictureLayerTiling
;
32 class PrioritizedTile
;
35 class CC_EXPORT PictureLayerTilingClient
{
37 // Create a tile at the given content_rect (in the contents scale of the
38 // tiling) This might return null if the client cannot create such a tile.
39 virtual ScopedTilePtr
CreateTile(float contents_scale
,
40 const gfx::Rect
& content_rect
) = 0;
41 virtual gfx::Size
CalculateTileSize(
42 const gfx::Size
& content_bounds
) const = 0;
43 // This invalidation region defines the area (if any, it can by null) that
44 // tiles can not be shared between pending and active trees.
45 virtual const Region
* GetPendingInvalidation() = 0;
46 virtual const PictureLayerTiling
* GetPendingOrActiveTwinTiling(
47 const PictureLayerTiling
* tiling
) const = 0;
48 virtual bool HasValidTilePriorities() const = 0;
49 virtual bool RequiresHighResToDraw() const = 0;
52 virtual ~PictureLayerTilingClient() {}
56 TileMapKey(int x
, int y
) : index_x(x
), index_y(y
) {}
57 explicit TileMapKey(const std::pair
<int, int>& index
)
58 : index_x(index
.first
), index_y(index
.second
) {}
60 bool operator==(const TileMapKey
& other
) const {
61 return index_x
== other
.index_x
&& index_y
== other
.index_y
;
70 namespace BASE_HASH_NAMESPACE
{
72 struct hash
<cc::TileMapKey
> {
73 size_t operator()(const cc::TileMapKey
& key
) const {
74 uint16 value1
= static_cast<uint16
>(key
.index_x
);
75 uint16 value2
= static_cast<uint16
>(key
.index_y
);
76 uint32 value1_32
= value1
;
77 return (value1_32
<< 16) | value2
;
80 } // namespace BASE_HASH_NAMESPACE
84 class CC_EXPORT PictureLayerTiling
{
86 static const int kBorderTexels
= 1;
88 PictureLayerTilingClient
* client() const { return client_
; }
89 ~PictureLayerTiling();
91 static float CalculateSoonBorderDistance(
92 const gfx::Rect
& visible_rect_in_content_space
,
93 float content_to_screen_scale
);
95 // Create a tiling with no tiles. CreateTile() must be called to add some.
96 static scoped_ptr
<PictureLayerTiling
> Create(
99 scoped_refptr
<RasterSource
> raster_source
,
100 PictureLayerTilingClient
* client
,
101 size_t max_tiles_for_interest_area
,
102 float skewport_target_time_in_seconds
,
103 int skewport_extrapolation_limit_in_content_pixels
);
105 void SetRasterSourceAndResize(scoped_refptr
<RasterSource
> raster_source
);
106 void Invalidate(const Region
& layer_invalidation
);
107 void CreateMissingTilesInLiveTilesRect();
108 void TakeTilesAndPropertiesFrom(PictureLayerTiling
* pending_twin
,
109 const Region
& layer_invalidation
);
111 bool IsTileRequiredForActivation(const Tile
* tile
) const;
112 bool IsTileRequiredForDraw(const Tile
* tile
) const;
114 void set_resolution(TileResolution resolution
) { resolution_
= resolution
; }
115 TileResolution
resolution() const { return resolution_
; }
116 void set_can_require_tiles_for_activation(bool can_require_tiles
) {
117 can_require_tiles_for_activation_
= can_require_tiles
;
120 RasterSource
* raster_source() const { return raster_source_
.get(); }
121 gfx::Size
tiling_size() const { return tiling_data_
.tiling_size(); }
122 gfx::Rect
live_tiles_rect() const { return live_tiles_rect_
; }
123 gfx::Size
tile_size() const { return tiling_data_
.max_texture_size(); }
124 float contents_scale() const { return contents_scale_
; }
125 const TilingData
* tiling_data() const { return &tiling_data_
; }
127 Tile
* TileAt(int i
, int j
) const {
128 TileMap::const_iterator iter
= tiles_
.find(TileMapKey(i
, j
));
129 return iter
== tiles_
.end() ? nullptr : iter
->second
;
132 bool has_tiles() const { return !tiles_
.empty(); }
133 // all_tiles_done() can return false negatives.
134 bool all_tiles_done() const { return all_tiles_done_
; }
135 void set_all_tiles_done(bool all_tiles_done
) {
136 all_tiles_done_
= all_tiles_done
;
139 void VerifyNoTileNeedsRaster() const {
141 for (const auto tile_pair
: tiles_
) {
142 DCHECK(!tile_pair
.second
->draw_info().NeedsRaster() ||
143 IsTileOccluded(tile_pair
.second
));
145 #endif // DCHECK_IS_ON()
148 // For testing functionality.
149 void CreateAllTilesForTesting() {
150 SetLiveTilesRect(gfx::Rect(tiling_data_
.tiling_size()));
152 const TilingData
& TilingDataForTesting() const { return tiling_data_
; }
153 std::vector
<Tile
*> AllTilesForTesting() const {
154 std::vector
<Tile
*> all_tiles
;
155 for (TileMap::const_iterator it
= tiles_
.begin(); it
!= tiles_
.end(); ++it
)
156 all_tiles
.push_back(it
->second
);
160 void UpdateAllRequiredStateForTesting() {
161 for (const auto& key_tile_pair
: tiles_
)
162 UpdateRequiredStatesOnTile(key_tile_pair
.second
);
164 std::map
<const Tile
*, PrioritizedTile
>
165 UpdateAndGetAllPrioritizedTilesForTesting() const;
167 void SetAllTilesOccludedForTesting() {
168 gfx::Rect viewport_in_layer_space
=
169 ScaleToEnclosingRect(current_visible_rect_
, 1.0f
/ contents_scale_
);
170 current_occlusion_in_layer_space_
=
171 Occlusion(gfx::Transform(),
172 SimpleEnclosedRegion(viewport_in_layer_space
),
173 SimpleEnclosedRegion(viewport_in_layer_space
));
175 const gfx::Rect
& GetCurrentVisibleRectForTesting() const {
176 return current_visible_rect_
;
178 void SetTilePriorityRectsForTesting(
179 const gfx::Rect
& visible_rect_in_content_space
,
180 const gfx::Rect
& skewport
,
181 const gfx::Rect
& soon_border_rect
,
182 const gfx::Rect
& eventually_rect
) {
183 SetTilePriorityRects(1.0f
, visible_rect_in_content_space
, skewport
,
184 soon_border_rect
, eventually_rect
, Occlusion());
187 // Iterate over all tiles to fill content_rect. Even if tiles are invalid
188 // (i.e. no valid resource) this tiling should still iterate over them.
189 // The union of all geometry_rect calls for each element iterated over should
190 // exactly equal content_rect and no two geometry_rects should intersect.
191 class CC_EXPORT CoverageIterator
{
194 CoverageIterator(const PictureLayerTiling
* tiling
,
196 const gfx::Rect
& rect
);
199 // Visible rect (no borders), always in the space of content_rect,
200 // regardless of the contents scale of the tiling.
201 gfx::Rect
geometry_rect() const;
202 // Texture rect (in texels) for geometry_rect
203 gfx::RectF
texture_rect() const;
205 Tile
* operator->() const { return current_tile_
; }
206 Tile
* operator*() const { return current_tile_
; }
208 CoverageIterator
& operator++();
209 operator bool() const { return tile_j_
<= bottom_
; }
211 int i() const { return tile_i_
; }
212 int j() const { return tile_j_
; }
215 const PictureLayerTiling
* tiling_
;
216 gfx::Rect dest_rect_
;
217 float dest_to_content_scale_
;
220 gfx::Rect current_geometry_rect_
;
228 friend class PictureLayerTiling
;
233 bool ComputeTilePriorityRects(const gfx::Rect
& viewport_in_layer_space
,
234 float ideal_contents_scale
,
235 double current_frame_time_in_seconds
,
236 const Occlusion
& occlusion_in_layer_space
);
238 void GetAllPrioritizedTilesForTracing(
239 std::vector
<PrioritizedTile
>* prioritized_tiles
) const;
240 void AsValueInto(base::trace_event::TracedValue
* array
) const;
241 size_t GPUMemoryUsageInBytes() const;
243 struct RectExpansionCache
{
244 RectExpansionCache();
246 gfx::Rect previous_start
;
247 gfx::Rect previous_bounds
;
248 gfx::Rect previous_result
;
249 int64 previous_target
;
253 gfx::Rect
ExpandRectEquallyToAreaBoundedBy(
254 const gfx::Rect
& starting_rect
,
256 const gfx::Rect
& bounding_rect
,
257 RectExpansionCache
* cache
);
260 friend class CoverageIterator
;
261 friend class PrioritizedTile
;
262 friend class TilingSetRasterQueueAll
;
263 friend class TilingSetRasterQueueRequired
;
264 friend class TilingSetEvictionQueue
;
266 // PENDING VISIBLE RECT refers to the visible rect that will become current
267 // upon activation (ie, the pending tree's visible rect). Tiles in this
268 // region that are not part of the current visible rect are all handled
269 // here. Note that when processing a pending tree, this rect is the same as
270 // the visible rect so no tiles are processed in this case.
271 enum PriorityRectType
{
273 PENDING_VISIBLE_RECT
,
279 using TileMap
= base::ScopedPtrHashMap
<TileMapKey
, ScopedTilePtr
>;
281 struct FrameVisibleRect
{
282 gfx::Rect visible_rect_in_content_space
;
283 double frame_time_in_seconds
= 0.0;
286 PictureLayerTiling(WhichTree tree
,
287 float contents_scale
,
288 scoped_refptr
<RasterSource
> raster_source
,
289 PictureLayerTilingClient
* client
,
290 size_t max_tiles_for_interest_area
,
291 float skewport_target_time_in_seconds
,
292 int skewport_extrapolation_limit_in_content_pixels
);
293 void SetLiveTilesRect(const gfx::Rect
& live_tiles_rect
);
294 void VerifyLiveTilesRect(bool is_on_recycle_tree
) const;
295 Tile
* CreateTile(int i
, int j
);
296 ScopedTilePtr
TakeTileAt(int i
, int j
);
297 // Returns true if the Tile existed and was removed from the tiling.
298 bool RemoveTileAt(int i
, int j
);
299 bool TilingMatchesTileIndices(const PictureLayerTiling
* twin
) const;
301 // Computes a skewport. The calculation extrapolates the last visible
302 // rect and the current visible rect to expand the skewport to where it
303 // would be in |skewport_target_time| seconds. Note that the skewport
304 // is guaranteed to contain the current visible rect.
305 gfx::Rect
ComputeSkewport(double current_frame_time_in_seconds
,
306 const gfx::Rect
& visible_rect_in_content_space
)
309 // Save the required data for computing tile priorities later.
310 void SetTilePriorityRects(float content_to_screen_scale_
,
311 const gfx::Rect
& visible_rect_in_content_space
,
312 const gfx::Rect
& skewport
,
313 const gfx::Rect
& soon_border_rect
,
314 const gfx::Rect
& eventually_rect
,
315 const Occlusion
& occlusion_in_layer_space
);
317 bool NeedsUpdateForFrameAtTimeAndViewport(
318 double frame_time_in_seconds
,
319 const gfx::Rect
& viewport_in_layer_space
) {
320 return frame_time_in_seconds
!=
321 visible_rect_history_
[0].frame_time_in_seconds
||
322 viewport_in_layer_space
!= last_viewport_in_layer_space_
;
324 void UpdateVisibleRectHistory(
325 double frame_time_in_seconds
,
326 const gfx::Rect
& visible_rect_in_content_space
) {
327 visible_rect_history_
[1] = visible_rect_history_
[0];
328 visible_rect_history_
[0].frame_time_in_seconds
= frame_time_in_seconds
;
329 visible_rect_history_
[0].visible_rect_in_content_space
=
330 visible_rect_in_content_space
;
331 // If we don't have a second history item, set it to the most recent one.
332 if (visible_rect_history_
[1].frame_time_in_seconds
== 0.0)
333 visible_rect_history_
[1] = visible_rect_history_
[0];
335 bool IsTileOccludedOnCurrentTree(const Tile
* tile
) const;
336 bool ShouldCreateTileAt(int i
, int j
) const;
337 bool IsTileOccluded(const Tile
* tile
) const;
338 void UpdateRequiredStatesOnTile(Tile
* tile
) const;
339 PrioritizedTile
MakePrioritizedTile(
341 PriorityRectType priority_rect_type
) const;
342 TilePriority
ComputePriorityForTile(
344 PriorityRectType priority_rect_type
) const;
345 PriorityRectType
ComputePriorityRectTypeForTile(const Tile
* tile
) const;
346 bool has_visible_rect_tiles() const { return has_visible_rect_tiles_
; }
347 bool has_skewport_rect_tiles() const { return has_skewport_rect_tiles_
; }
348 bool has_soon_border_rect_tiles() const {
349 return has_soon_border_rect_tiles_
;
351 bool has_eventually_rect_tiles() const { return has_eventually_rect_tiles_
; }
353 const gfx::Rect
& current_visible_rect() const {
354 return current_visible_rect_
;
356 gfx::Rect
pending_visible_rect() const {
357 const PictureLayerTiling
* pending_tiling
=
358 tree_
== ACTIVE_TREE
? client_
->GetPendingOrActiveTwinTiling(this)
361 return pending_tiling
->current_visible_rect();
364 const gfx::Rect
& current_skewport_rect() const {
365 return current_skewport_rect_
;
367 const gfx::Rect
& current_soon_border_rect() const {
368 return current_soon_border_rect_
;
370 const gfx::Rect
& current_eventually_rect() const {
371 return current_eventually_rect_
;
373 bool has_ever_been_updated() const {
374 return visible_rect_history_
[0].frame_time_in_seconds
!= 0.0;
376 void RemoveTilesInRegion(const Region
& layer_region
, bool recreate_tiles
);
378 const size_t max_tiles_for_interest_area_
;
379 const float skewport_target_time_in_seconds_
;
380 const int skewport_extrapolation_limit_in_content_pixels_
;
383 const float contents_scale_
;
384 PictureLayerTilingClient
* const client_
;
385 const WhichTree tree_
;
386 scoped_refptr
<RasterSource
> raster_source_
;
387 TileResolution resolution_
;
390 TilingData tiling_data_
;
391 TileMap tiles_
; // It is not legal to have a NULL tile in the tiles_ map.
392 gfx::Rect live_tiles_rect_
;
394 gfx::Rect last_viewport_in_layer_space_
;
395 // State saved for computing velocities based upon finite differences.
396 FrameVisibleRect visible_rect_history_
[2];
398 bool can_require_tiles_for_activation_
;
400 // Iteration rects in content space.
401 gfx::Rect current_visible_rect_
;
402 gfx::Rect current_skewport_rect_
;
403 gfx::Rect current_soon_border_rect_
;
404 gfx::Rect current_eventually_rect_
;
405 // Other properties used for tile iteration and prioritization.
406 float current_content_to_screen_scale_
;
407 Occlusion current_occlusion_in_layer_space_
;
409 bool has_visible_rect_tiles_
;
410 bool has_skewport_rect_tiles_
;
411 bool has_soon_border_rect_tiles_
;
412 bool has_eventually_rect_tiles_
;
413 bool all_tiles_done_
;
416 DISALLOW_ASSIGN(PictureLayerTiling
);
418 RectExpansionCache expansion_cache_
;
423 #endif // CC_TILES_PICTURE_LAYER_TILING_H_