12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/tiled_layer.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <algorithm> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "build/build_config.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/debug/overdraw_metrics.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer_impl.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/tiled_layer_impl.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/layer_updater.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/prioritized_resource.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/priority_calculator.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maximum predictive expansion of the visible area. 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kMaxPredictiveTilesCount = 2; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Number of rows/columns of tiles to pre-paint. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// We should increase these further as all textures are 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// prioritized and we insure performance doesn't suffer. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kPrepaintRows = 4; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kPrepaintColumns = 2; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UpdatableTile : public LayerTilingData::Tile { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static scoped_ptr<UpdatableTile> Create( 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerUpdater::Resource> updater_resource) { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr(new UpdatableTile(updater_resource.Pass())); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerUpdater::Resource* updater_resource() { return updater_resource_.get(); } 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrioritizedResource* managed_resource() { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return updater_resource_->texture(); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_dirty() const { return !dirty_rect.IsEmpty(); } 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reset update state for the current frame. This should occur before painting 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for all layers. Since painting one layer can invalidate another layer after 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it has already painted, mark all non-dirty tiles as valid before painting 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // such that invalidations during painting won't prevent them from being 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // pushed. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ResetUpdateState() { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_rect = gfx::Rect(); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) occluded = false; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) partial_update = false; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) valid_for_frame = !is_dirty(); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This promises to update the tile and therefore also guarantees the tile 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will be valid for this frame. dirty_rect is copied into update_rect so we 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // can continue to track re-entrant invalidations that occur during painting. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void MarkForUpdate() { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) valid_for_frame = true; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_rect = dirty_rect; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dirty_rect = gfx::Rect(); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect dirty_rect; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect update_rect; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool partial_update; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool valid_for_frame; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool occluded; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit UpdatableTile(scoped_ptr<LayerUpdater::Resource> updater_resource) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : partial_update(false), 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) valid_for_frame(false), 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) occluded(false), 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) updater_resource_(updater_resource.Pass()) {} 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<LayerUpdater::Resource> updater_resource_; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UpdatableTile); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TiledLayer::TiledLayer() 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : ContentsScalingLayer(), 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) texture_format_(GL_INVALID_ENUM), 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skips_draw_(false), 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) failed_update_(false), 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiling_option_(AUTO_TILE) { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_ = 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerTilingData::Create(gfx::Size(), LayerTilingData::HAS_BORDER_TEXELS); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TiledLayer::~TiledLayer() {} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> TiledLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TiledLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::UpdateTileSizeAndTilingOption() { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(layer_tree_host()); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size default_tile_size = layer_tree_host()->settings().default_tile_size; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size max_untiled_layer_size = 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer_tree_host()->settings().max_untiled_layer_size; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int layer_width = content_bounds().width(); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int layer_height = content_bounds().height(); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size tile_size(std::min(default_tile_size.width(), layer_width), 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::min(default_tile_size.height(), layer_height)); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Tile if both dimensions large, or any one dimension large and the other 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extends into a second tile but the total layer area isn't larger than that 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of the largest possible untiled layer. This heuristic allows for long 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // skinny layers (e.g. scrollbars) that are Nx1 tiles to minimize wasted 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // texture space but still avoids creating very large tiles. 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool any_dimension_large = layer_width > max_untiled_layer_size.width() || 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer_height > max_untiled_layer_size.height(); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool any_dimension_one_tile = 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (layer_width <= default_tile_size.width() || 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer_height <= default_tile_size.height()) && 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (layer_width * layer_height) <= (max_untiled_layer_size.width() * 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_untiled_layer_size.height()); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool auto_tiled = any_dimension_large && !any_dimension_one_tile; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_tiled; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tiling_option_ == ALWAYS_TILE) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_tiled = true; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (tiling_option_ == NEVER_TILE) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_tiled = false; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_tiled = auto_tiled; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size requested_size = is_tiled ? tile_size : content_bounds(); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int max_size = 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer_tree_host()->GetRendererCapabilities().max_texture_size; 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) requested_size.SetToMin(gfx::Size(max_size, max_size)); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetTileSize(requested_size); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::UpdateBounds() { 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size old_bounds = tiler_->bounds(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size new_bounds = content_bounds(); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (old_bounds == new_bounds) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->SetBounds(new_bounds); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invalidate any areas that the new bounds exposes. 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Region old_region = gfx::Rect(old_bounds); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Region new_region = gfx::Rect(new_bounds); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_region.Subtract(old_region); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Region::Iterator new_rects(new_region); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_rects.has_rect(); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_rects.next()) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InvalidateContentRect(new_rects.rect()); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::SetTileSize(gfx::Size size) { tiler_->SetTileSize(size); } 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::SetBorderTexelOption( 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerTilingData::BorderTexelOption border_texel_option) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->SetBorderTexelOption(border_texel_option); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TiledLayer::DrawsContent() const { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ContentsScalingLayer::DrawsContent()) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_more_than_one_tile = 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->num_tiles_x() > 1 || tiler_->num_tiles_y() > 1; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tiling_option_ == NEVER_TILE && has_more_than_one_tile) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TiledLayer::ReduceMemoryUsage() { 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (Updater()) 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Updater()->ReduceMemoryUsage(); 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::SetIsMask(bool is_mask) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_tiling_option(is_mask ? NEVER_TILE : AUTO_TILE); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::PushPropertiesTo(LayerImpl* layer) { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentsScalingLayer::PushPropertiesTo(layer); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TiledLayerImpl* tiled_layer = static_cast<TiledLayerImpl*>(layer); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiled_layer->set_skips_draw(skips_draw_); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiled_layer->SetTilingData(*tiler_); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<UpdatableTile*> invalid_tiles; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin(); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != tiler_->tiles().end(); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int i = iter->first.first; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int j = iter->first.second; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile->managed_resource()->have_backing_texture()) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Evicted tiles get deleted from both layers 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalid_tiles.push_back(tile); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile->valid_for_frame) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invalidated tiles are set so they can get different debug colors. 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiled_layer->PushInvalidTile(i, j); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiled_layer->PushTileProperties( 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i, 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) j, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()->resource_id(), 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->opaque_rect(), 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()->contents_swizzled()); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<UpdatableTile*>::const_iterator iter = invalid_tiles.begin(); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != invalid_tiles.end(); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->TakeTile((*iter)->i(), (*iter)->j()); 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // TiledLayer must push properties every frame, since viewport state and 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // occlusion from anywhere in the tree can change what the layer decides to 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // push to the impl tree. 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch needs_push_properties_ = true; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TiledLayer::BlocksPendingCommit() const { return true; } 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrioritizedResourceManager* TiledLayer::ResourceManager() const { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!layer_tree_host()) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return layer_tree_host()->contents_texture_manager(); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const PrioritizedResource* TiledLayer::ResourceAtForTesting(int i, 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int j) const { 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = TileAt(i, j); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tile->managed_resource(); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::SetLayerTreeHost(LayerTreeHost* host) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (host && host != layer_tree_host()) { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (LayerTilingData::TileMap::const_iterator 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter = tiler_->tiles().begin(); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != tiler_->tiles().end(); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()->SetTextureManager( 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host->contents_texture_manager()); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentsScalingLayer::SetLayerTreeHost(host); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UpdatableTile* TiledLayer::TileAt(int i, int j) const { 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<UpdatableTile*>(tiler_->TileAt(i, j)); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UpdatableTile* TiledLayer::CreateTile(int i, int j) { 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateUpdaterIfNeeded(); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UpdatableTile> tile( 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile::Create(Updater()->CreateResource(ResourceManager()))); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()->SetDimensions(tiler_->tile_size(), texture_format_); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* added_tile = tile.get(); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->AddTile(tile.PassAs<LayerTilingData::Tile>(), i, j); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) added_tile->dirty_rect = tiler_->TileRect(added_tile); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Temporary diagnostic crash. 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(added_tile); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(TileAt(i, j)); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return added_tile; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InvalidateContentRect(LayerRectToContentRect(dirty_rect)); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentsScalingLayer::SetNeedsDisplayRect(dirty_rect); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::InvalidateContentRect(gfx::Rect content_rect) { 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBounds(); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tiler_->is_empty() || content_rect.IsEmpty() || skips_draw_) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin(); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != tiler_->tiles().end(); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tile); 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bound = tiler_->TileRect(tile); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound.Intersect(content_rect); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->dirty_rect.Union(bound); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if tile is dirty and only part of it needs to be updated. 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TiledLayer::TileOnlyNeedsPartialUpdate(UpdatableTile* tile) { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !tile->dirty_rect.Contains(tiler_->TileRect(tile)) && 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()->have_backing_texture(); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TiledLayer::UpdateTiles(int left, 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top, 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int right, 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom, 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceUpdateQueue* queue, 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OcclusionTracker* occlusion, 330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool* updated) { 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateUpdaterIfNeeded(); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ignore_occlusions = !occlusion; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!HaveTexturesForTiles(left, top, right, bottom, ignore_occlusions)) { 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) failed_update_ = true; 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect paint_rect = 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MarkTilesForUpdate(left, top, right, bottom, ignore_occlusions); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (occlusion) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) occlusion->overdraw_metrics()->DidPaint(paint_rect); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (paint_rect.IsEmpty()) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *updated = true; 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateTileTextures( 350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch paint_rect, left, top, right, bottom, queue, occlusion); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::MarkOcclusionsAndRequestTextures( 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int left, 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top, 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int right, 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OcclusionTracker* occlusion) { 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There is some difficult dependancies between occlusions, recording 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // occlusion metrics and requesting memory so those are encapsulated in this 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // function: - We only want to call RequestLate on unoccluded textures (to 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // preserve memory for other layers when near OOM). - We only want to record 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // occlusion metrics if all memory requests succeed. 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int occluded_tile_count = 0; 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool succeeded = true; 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int j = top; j <= bottom; ++j) { 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = left; i <= right; ++i) { 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = TileAt(i, j); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tile); // Did SetTexturePriorities get skipped? 372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Did ResetUpdateState get skipped? Are we doing more than one occlusion 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // pass? 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!tile->occluded); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect visible_tile_rect = gfx::IntersectRects( 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->tile_bounds(i, j), visible_content_rect()); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (occlusion && occlusion->Occluded(render_target(), 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visible_tile_rect, 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) draw_transform(), 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) draw_transform_is_animating(), 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_clipped(), 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clip_rect(), 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL)) { 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->occluded = true; 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) occluded_tile_count++; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) succeeded &= tile->managed_resource()->RequestLate(); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!succeeded) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (occlusion) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) occlusion->overdraw_metrics()->DidCullTilesForUpload(occluded_tile_count); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TiledLayer::HaveTexturesForTiles(int left, 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top, 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int right, 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom, 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ignore_occlusions) { 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int j = top; j <= bottom; ++j) { 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = left; i <= right; ++i) { 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = TileAt(i, j); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tile); // Did SetTexturePriorites get skipped? 410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure the entire tile is dirty if we don't have the texture. 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile->managed_resource()->have_backing_texture()) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->dirty_rect = tiler_->TileRect(tile); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If using occlusion and the visible region of the tile is occluded, 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // don't reserve a texture or update the tile. 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tile->occluded && !ignore_occlusions) 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile->managed_resource()->can_acquire_backing_texture()) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect TiledLayer::MarkTilesForUpdate(int left, 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top, 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int right, 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom, 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ignore_occlusions) { 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect paint_rect; 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int j = top; j <= bottom; ++j) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = left; i <= right; ++i) { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = TileAt(i, j); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tile); // Did SetTexturePriorites get skipped? 440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tile->occluded && !ignore_occlusions) 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(reveman): Decide if partial update should be allowed based on cost 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of update. https://bugs.webkit.org/show_bug.cgi?id=77376 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tile->is_dirty() && layer_tree_host() && 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer_tree_host()->buffered_updates()) { 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we get a partial update, we use the same texture, otherwise return 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the current texture backing, so we don't update visible textures 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // non-atomically. If the current backing is in-use, it won't be 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // deleted until after the commit as the texture manager will not allow 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // deletion or recycling of in-use textures. 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (TileOnlyNeedsPartialUpdate(tile) && 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer_tree_host()->RequestPartialTextureUpdate()) { 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->partial_update = true; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->dirty_rect = tiler_->TileRect(tile); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()->ReturnBackingTexture(); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint_rect.Union(tile->dirty_rect); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->MarkForUpdate(); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return paint_rect; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::UpdateTileTextures(gfx::Rect paint_rect, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int left, 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top, 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int right, 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom, 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResourceUpdateQueue* queue, 476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const OcclusionTracker* occlusion) { 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The update_rect should be in layer space. So we have to convert the 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // paint_rect from content space to layer space. 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float width_scale = 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) paint_properties().bounds.width() / 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<float>(content_bounds().width()); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float height_scale = 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) paint_properties().bounds.height() / 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<float>(content_bounds().height()); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_rect_ = gfx::ScaleRect(paint_rect, width_scale, height_scale); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Calling PrepareToUpdate() calls into WebKit to paint, which may have the 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // side effect of disabling compositing, which causes our reference to the 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // texture updater to be deleted. However, we can't free the memory backing 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the SkCanvas until the paint finishes, so we grab a local reference here to 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // hold the updater alive until the paint completes. 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<LayerUpdater> protector(Updater()); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect painted_opaque_rect; 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Updater()->PrepareToUpdate(paint_rect, 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->tile_size(), 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1.f / width_scale, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1.f / height_scale, 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &painted_opaque_rect); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int j = top; j <= bottom; ++j) { 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = left; i <= right; ++i) { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = TileAt(i, j); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tile); // Did SetTexturePriorites get skipped? 504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect tile_rect = tiler_->tile_bounds(i, j); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use update_rect as the above loop copied the dirty rect for this frame 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to update_rect. 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect dirty_rect = tile->update_rect; 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dirty_rect.IsEmpty()) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Save what was painted opaque in the tile. Keep the old area if the 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // paint didn't touch it, and didn't paint some other part of the tile 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // opaque. 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect tile_painted_rect = gfx::IntersectRects(tile_rect, paint_rect); 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect tile_painted_opaque_rect = 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::IntersectRects(tile_rect, painted_opaque_rect); 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile_painted_rect.IsEmpty()) { 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect paint_inside_tile_opaque_rect = 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::IntersectRects(tile->opaque_rect(), tile_painted_rect); 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool paint_inside_tile_opaque_rect_is_non_opaque = 526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !paint_inside_tile_opaque_rect.IsEmpty() && 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !tile_painted_opaque_rect.Contains(paint_inside_tile_opaque_rect); 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool opaque_paint_not_inside_tile_opaque_rect = 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !tile_painted_opaque_rect.IsEmpty() && 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !tile->opaque_rect().Contains(tile_painted_opaque_rect); 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (paint_inside_tile_opaque_rect_is_non_opaque || 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) opaque_paint_not_inside_tile_opaque_rect) 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->set_opaque_rect(tile_painted_opaque_rect); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // source_rect starts as a full-sized tile with border texels included. 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect source_rect = tiler_->TileRect(tile); 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source_rect.Intersect(dirty_rect); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Paint rect not guaranteed to line up on tile boundaries, so 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // make sure that source_rect doesn't extend outside of it. 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source_rect.Intersect(paint_rect); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->update_rect = source_rect; 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (source_rect.IsEmpty()) 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Point anchor = tiler_->TileRect(tile).origin(); 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Calculate tile-space rectangle to upload into. 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d dest_offset = source_rect.origin() - anchor; 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GE(dest_offset.x(), 0); 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GE(dest_offset.y(), 0); 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Offset from paint rectangle to this tile's dirty rectangle. 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d paint_offset = source_rect.origin() - paint_rect.origin(); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GE(paint_offset.x(), 0); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_GE(paint_offset.y(), 0); 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_LE(paint_offset.x() + source_rect.width(), paint_rect.width()); 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_LE(paint_offset.y() + source_rect.height(), paint_rect.height()); 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->updater_resource()->Update( 564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch queue, source_rect, dest_offset, tile->partial_update); 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (occlusion) { 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) occlusion->overdraw_metrics()-> 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DidUpload(gfx::Transform(), source_rect, tile->opaque_rect()); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This picks a small animated layer to be anything less than one viewport. This 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is specifically for page transitions which are viewport-sized layers. The 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// extra tile of padding is due to these layers being slightly larger than the 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// viewport in some cases. 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TiledLayer::IsSmallAnimatedLayer() const { 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!draw_transform_is_animating() && !screen_space_transform_is_animating()) 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size viewport_size = 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layer_tree_host() ? layer_tree_host()->device_viewport_size() 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : gfx::Size(); 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect content_rect(content_bounds()); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return content_rect.width() <= 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) viewport_size.width() + tiler_->tile_size().width() && 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_rect.height() <= 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) viewport_size.height() + tiler_->tile_size().height(); 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(epenner): Remove this and make this based on distance once distance can 592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// be calculated for offscreen layers. For now, prioritize all small animated 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// layers after 512 pixels of pre-painting. 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetPriorityForTexture(gfx::Rect visible_rect, 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect tile_rect, 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool draws_to_root, 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_small_animated_layer, 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrioritizedResource* texture) { 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int priority = PriorityCalculator::LowestPriority(); 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!visible_rect.IsEmpty()) { 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority = PriorityCalculator::PriorityFromDistance( 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visible_rect, tile_rect, draws_to_root); 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_small_animated_layer) { 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority = PriorityCalculator::max_priority( 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority, PriorityCalculator::SmallAnimatedLayerMinPriority()); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (priority != PriorityCalculator::LowestPriority()) 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) texture->set_request_priority(priority); 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::SetTexturePriorities(const PriorityCalculator& priority_calc) { 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBounds(); 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResetUpdateState(); 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateScrollPrediction(); 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tiler_->has_empty_bounds()) 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool draws_to_root = !render_target()->parent(); 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool small_animated_layer = IsSmallAnimatedLayer(); 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Minimally create the tiles in the desired pre-paint rect. 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect create_tiles_rect = IdlePaintRect(); 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (small_animated_layer) 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) create_tiles_rect = gfx::Rect(content_bounds()); 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!create_tiles_rect.IsEmpty()) { 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int left, top, right, bottom; 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->ContentRectToTileIndices( 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) create_tiles_rect, &left, &top, &right, &bottom); 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int j = top; j <= bottom; ++j) { 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = left; i <= right; ++i) { 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!TileAt(i, j)) 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateTile(i, j); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now update priorities on all tiles we have in the layer, no matter where 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // they are. 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin(); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != tiler_->tiles().end(); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect tile_rect = tiler_->TileRect(tile); 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetPriorityForTexture(predicted_visible_rect_, 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile_rect, 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) draws_to_root, 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) small_animated_layer, 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()); 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Region TiledLayer::VisibleContentOpaqueRegion() const { 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (skips_draw_) 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Region(); 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (contents_opaque()) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return visible_content_rect(); 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tiler_->OpaqueRegionInContentRect(visible_content_rect()); 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::ResetUpdateState() { 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skips_draw_ = false; 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) failed_update_ = false; 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LayerTilingData::TileMap::const_iterator end = tiler_->tiles().end(); 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin(); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != end; 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second); 677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(enne): This should not ever be null. 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->ResetUpdateState(); 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect ExpandRectByDelta(gfx::Rect rect, gfx::Vector2d delta) { 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width = rect.width() + std::abs(delta.x()); 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int height = rect.height() + std::abs(delta.y()); 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x = rect.x() + ((delta.x() < 0) ? delta.x() : 0); 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int y = rect.y() + ((delta.y() < 0) ? delta.y() : 0); 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Rect(x, y, width, height); 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TiledLayer::UpdateScrollPrediction() { 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This scroll prediction is very primitive and should be replaced by a 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a recursive calculation on all layers which uses actual scroll/animation 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // velocities. To insure this doesn't miss-predict, we only use it to predict 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the visible_rect if: 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - content_bounds() hasn't changed. 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - visible_rect.size() hasn't changed. 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These two conditions prevent rotations, scales, pinch-zooms etc. where 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the prediction would be incorrect. 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d delta = visible_content_rect().CenterPoint() - 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_visible_rect_.CenterPoint(); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) predicted_scroll_ = -delta; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) predicted_visible_rect_ = visible_content_rect(); 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (previous_content_bounds_ == content_bounds() && 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_visible_rect_.size() == visible_content_rect().size()) { 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only expand the visible rect in the major scroll direction, to prevent 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // massive paints due to diagonal scrolls. 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d major_scroll_delta = 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (std::abs(delta.x()) > std::abs(delta.y())) ? 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d(delta.x(), 0) : 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d(0, delta.y()); 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) predicted_visible_rect_ = 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExpandRectByDelta(visible_content_rect(), major_scroll_delta); 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Bound the prediction to prevent unbounded paints, and clamp to content 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // bounds. 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bound = visible_content_rect(); 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound.Inset(-tiler_->tile_size().width() * kMaxPredictiveTilesCount, 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -tiler_->tile_size().height() * kMaxPredictiveTilesCount); 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound.Intersect(gfx::Rect(content_bounds())); 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) predicted_visible_rect_.Intersect(bound); 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_content_bounds_ = content_bounds(); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_visible_rect_ = visible_content_rect(); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool TiledLayer::Update(ResourceUpdateQueue* queue, 731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const OcclusionTracker* occlusion) { 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!skips_draw_ && !failed_update_); // Did ResetUpdateState get skipped? 733a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 734a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool updated = false; 735a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true); 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 740a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) updated |= ContentsScalingLayer::Update(queue, occlusion); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBounds(); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tiler_->has_empty_bounds() || !DrawsContent()) 7457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Animation pre-paint. If the layer is small, try to paint it all 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // immediately whether or not it is occluded, to avoid paint/upload 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // hiccups while it is animating. 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsSmallAnimatedLayer()) { 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int left, top, right, bottom; 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->ContentRectToTileIndices(gfx::Rect(content_bounds()), 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &left, 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &top, 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &right, 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &bottom); 757a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateTiles(left, top, right, bottom, queue, NULL, &updated); 758a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (updated) 759a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This was an attempt to paint the entire layer so if we fail it's okay, 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // just fallback on painting visible etc. below. 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) failed_update_ = false; 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (predicted_visible_rect_.IsEmpty()) 766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Visible painting. First occlude visible tiles and paint the non-occluded 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // tiles. 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int left, top, right, bottom; 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->ContentRectToTileIndices( 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) predicted_visible_rect_, &left, &top, &right, &bottom); 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MarkOcclusionsAndRequestTextures(left, top, right, bottom, occlusion); 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) skips_draw_ = !UpdateTiles( 775a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) left, top, right, bottom, queue, occlusion, &updated); 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (skips_draw_) 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->reset(); 778a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (skips_draw_ || updated) 7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we have already painting everything visible. Do some pre-painting while 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // idle. 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect idle_paint_content_rect = IdlePaintRect(); 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (idle_paint_content_rect.IsEmpty()) 785a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Prepaint anything that was occluded but inside the layer's visible region. 788a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!UpdateTiles(left, top, right, bottom, queue, NULL, &updated) || 789a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) updated) 790a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int prepaint_left, prepaint_top, prepaint_right, prepaint_bottom; 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->ContentRectToTileIndices(idle_paint_content_rect, 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &prepaint_left, 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &prepaint_top, 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &prepaint_right, 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &prepaint_bottom); 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then expand outwards one row/column at a time until we find a dirty 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // row/column to update. Increment along the major and minor scroll directions 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // first. 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d delta = -predicted_scroll_; 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delta = gfx::Vector2d(delta.x() == 0 ? 1 : delta.x(), 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delta.y() == 0 ? 1 : delta.y()); 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d major_delta = 806558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch (std::abs(delta.x()) > std::abs(delta.y())) ? gfx::Vector2d(delta.x(), 0) 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : gfx::Vector2d(0, delta.y()); 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d minor_delta = 809558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch (std::abs(delta.x()) <= std::abs(delta.y())) ? gfx::Vector2d(delta.x(), 0) 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : gfx::Vector2d(0, delta.y()); 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Vector2d deltas[4] = { major_delta, minor_delta, -major_delta, 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -minor_delta }; 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < 4; i++) { 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (deltas[i].y() > 0) { 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (bottom < prepaint_bottom) { 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++bottom; 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!UpdateTiles( 818a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) left, bottom, right, bottom, queue, NULL, &updated) || 819a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) updated) 820a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (deltas[i].y() < 0) { 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (top > prepaint_top) { 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --top; 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!UpdateTiles( 827a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) left, top, right, top, queue, NULL, &updated) || 828a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) updated) 829a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (deltas[i].x() < 0) { 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (left > prepaint_left) { 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --left; 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!UpdateTiles( 836a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) left, top, left, bottom, queue, NULL, &updated) || 837a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) updated) 838a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (deltas[i].x() > 0) { 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (right < prepaint_right) { 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++right; 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!UpdateTiles( 845a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) right, top, right, bottom, queue, NULL, &updated) || 846a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) updated) 847a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 851a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return updated; 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TiledLayer::NeedsIdlePaint() { 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't trigger more paints if we failed (as we'll just fail again). 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (failed_update_ || visible_content_rect().IsEmpty() || 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->has_empty_bounds() || !DrawsContent()) 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect idle_paint_content_rect = IdlePaintRect(); 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (idle_paint_content_rect.IsEmpty()) 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int left, top, right, bottom; 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tiler_->ContentRectToTileIndices( 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) idle_paint_content_rect, &left, &top, &right, &bottom); 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int j = top; j <= bottom; ++j) { 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = left; i <= right; ++i) { 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatableTile* tile = TileAt(i, j); 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tile); // Did SetTexturePriorities get skipped? 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tile) 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool updated = !tile->update_rect.IsEmpty(); 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool can_acquire = 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->managed_resource()->can_acquire_backing_texture(); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool dirty = 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tile->is_dirty() || !tile->managed_resource()->have_backing_texture(); 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!updated && can_acquire && dirty) 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect TiledLayer::IdlePaintRect() { 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't inflate an empty rect. 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (visible_content_rect().IsEmpty()) 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Rect(); 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect prepaint_rect = visible_content_rect(); 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepaint_rect.Inset(-tiler_->tile_size().width() * kPrepaintColumns, 8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -tiler_->tile_size().height() * kPrepaintRows); 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect content_rect(content_bounds()); 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prepaint_rect.Intersect(content_rect); 8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return prepaint_rect; 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 902