Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1396)

Unified Diff: cc/layers/tiled_layer.cc

Issue 1057283003: Remove parts of //cc we aren't using (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/layers/tiled_layer.h ('k') | cc/layers/tiled_layer_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/layers/tiled_layer.cc
diff --git a/cc/layers/tiled_layer.cc b/cc/layers/tiled_layer.cc
deleted file mode 100644
index 55143befe9305b55ef351dd7f7ae7d2ce77ce233..0000000000000000000000000000000000000000
--- a/cc/layers/tiled_layer.cc
+++ /dev/null
@@ -1,869 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/tiled_layer.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "base/auto_reset.h"
-#include "base/basictypes.h"
-#include "build/build_config.h"
-#include "cc/base/simple_enclosed_region.h"
-#include "cc/layers/layer_impl.h"
-#include "cc/layers/tiled_layer_impl.h"
-#include "cc/resources/layer_updater.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/priority_calculator.h"
-#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/occlusion_tracker.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-namespace cc {
-
-// Maximum predictive expansion of the visible area.
-static const int kMaxPredictiveTilesCount = 2;
-
-// Number of rows/columns of tiles to pre-paint.
-// We should increase these further as all textures are
-// prioritized and we insure performance doesn't suffer.
-static const int kPrepaintRows = 4;
-static const int kPrepaintColumns = 2;
-
-class UpdatableTile : public LayerTilingData::Tile {
- public:
- static scoped_ptr<UpdatableTile> Create(
- scoped_ptr<LayerUpdater::Resource> updater_resource) {
- return make_scoped_ptr(new UpdatableTile(updater_resource.Pass()));
- }
-
- LayerUpdater::Resource* updater_resource() { return updater_resource_.get(); }
- PrioritizedResource* managed_resource() {
- return updater_resource_->texture();
- }
-
- bool is_dirty() const { return !dirty_rect.IsEmpty(); }
-
- // Reset update state for the current frame. This should occur before painting
- // for all layers. Since painting one layer can invalidate another layer after
- // it has already painted, mark all non-dirty tiles as valid before painting
- // such that invalidations during painting won't prevent them from being
- // pushed.
- void ResetUpdateState() {
- update_rect = gfx::Rect();
- occluded = false;
- partial_update = false;
- valid_for_frame = !is_dirty();
- }
-
- // This promises to update the tile and therefore also guarantees the tile
- // will be valid for this frame. dirty_rect is copied into update_rect so we
- // can continue to track re-entrant invalidations that occur during painting.
- void MarkForUpdate() {
- valid_for_frame = true;
- update_rect = dirty_rect;
- dirty_rect = gfx::Rect();
- }
-
- gfx::Rect dirty_rect;
- gfx::Rect update_rect;
- bool partial_update;
- bool valid_for_frame;
- bool occluded;
-
- private:
- explicit UpdatableTile(scoped_ptr<LayerUpdater::Resource> updater_resource)
- : partial_update(false),
- valid_for_frame(false),
- occluded(false),
- updater_resource_(updater_resource.Pass()) {}
-
- scoped_ptr<LayerUpdater::Resource> updater_resource_;
-
- DISALLOW_COPY_AND_ASSIGN(UpdatableTile);
-};
-
-TiledLayer::TiledLayer()
- : ContentsScalingLayer(),
- texture_format_(RGBA_8888),
- skips_draw_(false),
- failed_update_(false),
- tiling_option_(AUTO_TILE) {
- tiler_ =
- LayerTilingData::Create(gfx::Size(), LayerTilingData::HAS_BORDER_TEXELS);
-}
-
-TiledLayer::~TiledLayer() {}
-
-scoped_ptr<LayerImpl> TiledLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
- return TiledLayerImpl::Create(tree_impl, id());
-}
-
-void TiledLayer::UpdateTileSizeAndTilingOption() {
- DCHECK(layer_tree_host());
-
- gfx::Size default_tile_size = layer_tree_host()->settings().default_tile_size;
- gfx::Size max_untiled_layer_size =
- layer_tree_host()->settings().max_untiled_layer_size;
- int layer_width = content_bounds().width();
- int layer_height = content_bounds().height();
-
- gfx::Size tile_size(std::min(default_tile_size.width(), layer_width),
- std::min(default_tile_size.height(), layer_height));
-
- // Tile if both dimensions large, or any one dimension large and the other
- // extends into a second tile but the total layer area isn't larger than that
- // of the largest possible untiled layer. This heuristic allows for long
- // skinny layers (e.g. scrollbars) that are Nx1 tiles to minimize wasted
- // texture space but still avoids creating very large tiles.
- bool any_dimension_large = layer_width > max_untiled_layer_size.width() ||
- layer_height > max_untiled_layer_size.height();
- bool any_dimension_one_tile =
- (layer_width <= default_tile_size.width() ||
- layer_height <= default_tile_size.height()) &&
- (layer_width * layer_height) <= (max_untiled_layer_size.width() *
- max_untiled_layer_size.height());
- bool auto_tiled = any_dimension_large && !any_dimension_one_tile;
-
- bool is_tiled;
- if (tiling_option_ == ALWAYS_TILE)
- is_tiled = true;
- else if (tiling_option_ == NEVER_TILE)
- is_tiled = false;
- else
- is_tiled = auto_tiled;
-
- gfx::Size requested_size = is_tiled ? tile_size : content_bounds();
- const int max_size =
- layer_tree_host()->GetRendererCapabilities().max_texture_size;
- requested_size.SetToMin(gfx::Size(max_size, max_size));
- SetTileSize(requested_size);
-}
-
-void TiledLayer::UpdateBounds() {
- gfx::Size old_tiling_size = tiler_->tiling_size();
- gfx::Size new_tiling_size = content_bounds();
- if (old_tiling_size == new_tiling_size)
- return;
- tiler_->SetTilingSize(new_tiling_size);
-
- // Invalidate any areas that the new bounds exposes.
- Region new_region =
- SubtractRegions(gfx::Rect(new_tiling_size), gfx::Rect(old_tiling_size));
- for (Region::Iterator new_rects(new_region); new_rects.has_rect();
- new_rects.next())
- InvalidateContentRect(new_rects.rect());
- UpdateDrawsContent(HasDrawableContent());
-}
-
-void TiledLayer::SetTileSize(const gfx::Size& size) {
- tiler_->SetTileSize(size);
- UpdateDrawsContent(HasDrawableContent());
-}
-
-void TiledLayer::SetBorderTexelOption(
- LayerTilingData::BorderTexelOption border_texel_option) {
- tiler_->SetBorderTexelOption(border_texel_option);
- UpdateDrawsContent(HasDrawableContent());
-}
-
-bool TiledLayer::HasDrawableContent() const {
- bool has_more_than_one_tile =
- (tiler_->num_tiles_x() > 1) || (tiler_->num_tiles_y() > 1);
-
- return !(tiling_option_ == NEVER_TILE && has_more_than_one_tile) &&
- ContentsScalingLayer::HasDrawableContent();
-}
-
-void TiledLayer::ReduceMemoryUsage() {
- if (Updater())
- Updater()->ReduceMemoryUsage();
-}
-
-void TiledLayer::SetIsMask(bool is_mask) {
- set_tiling_option(is_mask ? NEVER_TILE : AUTO_TILE);
-}
-
-void TiledLayer::PushPropertiesTo(LayerImpl* layer) {
- ContentsScalingLayer::PushPropertiesTo(layer);
-
- TiledLayerImpl* tiled_layer = static_cast<TiledLayerImpl*>(layer);
-
- tiled_layer->set_skips_draw(skips_draw_);
- tiled_layer->SetTilingData(*tiler_);
- std::vector<UpdatableTile*> invalid_tiles;
-
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- int i = iter->first.first;
- int j = iter->first.second;
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
-
- if (!tile->managed_resource()->have_backing_texture()) {
- // Evicted tiles get deleted from both layers
- invalid_tiles.push_back(tile);
- continue;
- }
-
- if (!tile->valid_for_frame) {
- // Invalidated tiles are set so they can get different debug colors.
- tiled_layer->PushInvalidTile(i, j);
- continue;
- }
-
- tiled_layer->PushTileProperties(
- i,
- j,
- tile->managed_resource()->resource_id(),
- tile->managed_resource()->contents_swizzled());
- }
- for (std::vector<UpdatableTile*>::const_iterator iter = invalid_tiles.begin();
- iter != invalid_tiles.end();
- ++iter)
- tiler_->TakeTile((*iter)->i(), (*iter)->j());
-
- // TiledLayer must push properties every frame, since viewport state and
- // occlusion from anywhere in the tree can change what the layer decides to
- // push to the impl tree.
- needs_push_properties_ = true;
-}
-
-PrioritizedResourceManager* TiledLayer::ResourceManager() {
- if (!layer_tree_host())
- return nullptr;
- return layer_tree_host()->contents_texture_manager();
-}
-
-const PrioritizedResource* TiledLayer::ResourceAtForTesting(int i,
- int j) const {
- UpdatableTile* tile = TileAt(i, j);
- if (!tile)
- return nullptr;
- return tile->managed_resource();
-}
-
-void TiledLayer::SetLayerTreeHost(LayerTreeHost* host) {
- if (host && host != layer_tree_host()) {
- for (LayerTilingData::TileMap::const_iterator
- iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- tile->managed_resource()->SetTextureManager(
- host->contents_texture_manager());
- }
- }
- ContentsScalingLayer::SetLayerTreeHost(host);
-}
-
-UpdatableTile* TiledLayer::TileAt(int i, int j) const {
- return static_cast<UpdatableTile*>(tiler_->TileAt(i, j));
-}
-
-UpdatableTile* TiledLayer::CreateTile(int i, int j) {
- CreateUpdaterIfNeeded();
-
- scoped_ptr<UpdatableTile> tile(
- UpdatableTile::Create(Updater()->CreateResource(ResourceManager())));
- tile->managed_resource()->SetDimensions(tiler_->tile_size(), texture_format_);
-
- UpdatableTile* added_tile = tile.get();
- tiler_->AddTile(tile.Pass(), i, j);
-
- added_tile->dirty_rect = tiler_->TileRect(added_tile);
-
- // Temporary diagnostic crash.
- CHECK(added_tile);
- CHECK(TileAt(i, j));
-
- return added_tile;
-}
-
-void TiledLayer::SetNeedsDisplayRect(const gfx::Rect& dirty_rect) {
- InvalidateContentRect(LayerRectToContentRect(dirty_rect));
- ContentsScalingLayer::SetNeedsDisplayRect(dirty_rect);
-}
-
-void TiledLayer::InvalidateContentRect(const gfx::Rect& content_rect) {
- UpdateBounds();
- if (tiler_->is_empty() || content_rect.IsEmpty() || skips_draw_)
- return;
-
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- DCHECK(tile);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- gfx::Rect bound = tiler_->TileRect(tile);
- bound.Intersect(content_rect);
- tile->dirty_rect.Union(bound);
- }
-}
-
-// Returns true if tile is dirty and only part of it needs to be updated.
-bool TiledLayer::TileOnlyNeedsPartialUpdate(UpdatableTile* tile) {
- return !tile->dirty_rect.Contains(tiler_->TileRect(tile)) &&
- tile->managed_resource()->have_backing_texture();
-}
-
-bool TiledLayer::UpdateTiles(int left,
- int top,
- int right,
- int bottom,
- ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion,
- bool* updated) {
- CreateUpdaterIfNeeded();
-
- bool ignore_occlusions = !occlusion;
- if (!HaveTexturesForTiles(left, top, right, bottom, ignore_occlusions)) {
- failed_update_ = true;
- return false;
- }
-
- gfx::Rect update_rect;
- gfx::Rect paint_rect;
- MarkTilesForUpdate(
- &update_rect, &paint_rect, left, top, right, bottom, ignore_occlusions);
-
- if (paint_rect.IsEmpty())
- return true;
-
- *updated = true;
- UpdateTileTextures(
- update_rect, paint_rect, left, top, right, bottom, queue, occlusion);
- return true;
-}
-
-void TiledLayer::MarkOcclusionsAndRequestTextures(
- int left,
- int top,
- int right,
- int bottom,
- const OcclusionTracker<Layer>* occlusion) {
- int occluded_tile_count = 0;
- bool succeeded = true;
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorities get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- // Did ResetUpdateState get skipped? Are we doing more than one occlusion
- // pass?
- DCHECK(!tile->occluded);
- gfx::Rect visible_tile_rect = gfx::IntersectRects(
- tiler_->tile_bounds(i, j), visible_content_rect());
- if (!draw_transform_is_animating() && occlusion &&
- occlusion->GetCurrentOcclusionForLayer(draw_transform())
- .IsOccluded(visible_tile_rect)) {
- tile->occluded = true;
- occluded_tile_count++;
- } else {
- succeeded &= tile->managed_resource()->RequestLate();
- }
- }
- }
-}
-
-bool TiledLayer::HaveTexturesForTiles(int left,
- int top,
- int right,
- int bottom,
- bool ignore_occlusions) {
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorites get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
-
- // Ensure the entire tile is dirty if we don't have the texture.
- if (!tile->managed_resource()->have_backing_texture())
- tile->dirty_rect = tiler_->TileRect(tile);
-
- // If using occlusion and the visible region of the tile is occluded,
- // don't reserve a texture or update the tile.
- if (tile->occluded && !ignore_occlusions)
- continue;
-
- if (!tile->managed_resource()->can_acquire_backing_texture())
- return false;
- }
- }
- return true;
-}
-
-void TiledLayer::MarkTilesForUpdate(gfx::Rect* update_rect,
- gfx::Rect* paint_rect,
- int left,
- int top,
- int right,
- int bottom,
- bool ignore_occlusions) {
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorites get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- if (tile->occluded && !ignore_occlusions)
- continue;
-
- // Prepare update rect from original dirty rects.
- update_rect->Union(tile->dirty_rect);
-
- // TODO(reveman): Decide if partial update should be allowed based on cost
- // of update. https://bugs.webkit.org/show_bug.cgi?id=77376
- if (tile->is_dirty() &&
- !layer_tree_host()->AlwaysUsePartialTextureUpdates()) {
- // If we get a partial update, we use the same texture, otherwise return
- // the current texture backing, so we don't update visible textures
- // non-atomically. If the current backing is in-use, it won't be
- // deleted until after the commit as the texture manager will not allow
- // deletion or recycling of in-use textures.
- if (TileOnlyNeedsPartialUpdate(tile) &&
- layer_tree_host()->RequestPartialTextureUpdate()) {
- tile->partial_update = true;
- } else {
- tile->dirty_rect = tiler_->TileRect(tile);
- tile->managed_resource()->ReturnBackingTexture();
- }
- }
-
- paint_rect->Union(tile->dirty_rect);
- tile->MarkForUpdate();
- }
- }
-}
-
-void TiledLayer::UpdateTileTextures(const gfx::Rect& update_rect,
- const gfx::Rect& paint_rect,
- int left,
- int top,
- int right,
- int bottom,
- ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- // The update_rect should be in layer space. So we have to convert the
- // paint_rect from content space to layer space.
- float width_scale = 1 / draw_properties().contents_scale_x;
- float height_scale = 1 / draw_properties().contents_scale_y;
- update_rect_ =
- gfx::ScaleToEnclosingRect(update_rect, width_scale, height_scale);
-
- // Calling PrepareToUpdate() calls into WebKit to paint, which may have the
- // side effect of disabling compositing, which causes our reference to the
- // texture updater to be deleted. However, we can't free the memory backing
- // the SkCanvas until the paint finishes, so we grab a local reference here to
- // hold the updater alive until the paint completes.
- scoped_refptr<LayerUpdater> protector(Updater());
- Updater()->PrepareToUpdate(content_bounds(),
- paint_rect,
- tiler_->tile_size(),
- 1.f / width_scale,
- 1.f / height_scale);
-
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorites get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
-
- gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
-
- // Use update_rect as the above loop copied the dirty rect for this frame
- // to update_rect.
- gfx::Rect dirty_rect = tile->update_rect;
- if (dirty_rect.IsEmpty())
- continue;
-
- // source_rect starts as a full-sized tile with border texels included.
- gfx::Rect source_rect = tiler_->TileRect(tile);
- source_rect.Intersect(dirty_rect);
- // Paint rect not guaranteed to line up on tile boundaries, so
- // make sure that source_rect doesn't extend outside of it.
- source_rect.Intersect(paint_rect);
-
- tile->update_rect = source_rect;
-
- if (source_rect.IsEmpty())
- continue;
-
- const gfx::Point anchor = tiler_->TileRect(tile).origin();
-
- // Calculate tile-space rectangle to upload into.
- gfx::Vector2d dest_offset = source_rect.origin() - anchor;
- CHECK_GE(dest_offset.x(), 0);
- CHECK_GE(dest_offset.y(), 0);
-
- // Offset from paint rectangle to this tile's dirty rectangle.
- gfx::Vector2d paint_offset = source_rect.origin() - paint_rect.origin();
- CHECK_GE(paint_offset.x(), 0);
- CHECK_GE(paint_offset.y(), 0);
- CHECK_LE(paint_offset.x() + source_rect.width(), paint_rect.width());
- CHECK_LE(paint_offset.y() + source_rect.height(), paint_rect.height());
-
- tile->updater_resource()->Update(
- queue, source_rect, dest_offset, tile->partial_update);
- }
- }
-}
-
-// This picks a small animated layer to be anything less than one viewport. This
-// is specifically for page transitions which are viewport-sized layers. The
-// extra tile of padding is due to these layers being slightly larger than the
-// viewport in some cases.
-bool TiledLayer::IsSmallAnimatedLayer() const {
- if (!draw_transform_is_animating() && !screen_space_transform_is_animating())
- return false;
- gfx::Size viewport_size =
- layer_tree_host() ? layer_tree_host()->device_viewport_size()
- : gfx::Size();
- gfx::Rect content_rect(content_bounds());
- return content_rect.width() <=
- viewport_size.width() + tiler_->tile_size().width() &&
- content_rect.height() <=
- viewport_size.height() + tiler_->tile_size().height();
-}
-
-namespace {
-// TODO(epenner): Remove this and make this based on distance once distance can
-// be calculated for offscreen layers. For now, prioritize all small animated
-// layers after 512 pixels of pre-painting.
-void SetPriorityForTexture(const gfx::Rect& visible_rect,
- const gfx::Rect& tile_rect,
- bool draws_to_root,
- bool is_small_animated_layer,
- PrioritizedResource* texture) {
- int priority = PriorityCalculator::LowestPriority();
- if (!visible_rect.IsEmpty()) {
- priority = PriorityCalculator::PriorityFromDistance(
- visible_rect, tile_rect, draws_to_root);
- }
-
- if (is_small_animated_layer) {
- priority = PriorityCalculator::max_priority(
- priority, PriorityCalculator::SmallAnimatedLayerMinPriority());
- }
-
- if (priority != PriorityCalculator::LowestPriority())
- texture->set_request_priority(priority);
-}
-} // namespace
-
-void TiledLayer::SetTexturePriorities(const PriorityCalculator& priority_calc) {
- UpdateBounds();
- ResetUpdateState();
- UpdateScrollPrediction();
-
- if (tiler_->has_empty_bounds())
- return;
-
- bool draws_to_root = !render_target()->parent();
- bool small_animated_layer = IsSmallAnimatedLayer();
-
- // Minimally create the tiles in the desired pre-paint rect.
- gfx::Rect create_tiles_rect = IdlePaintRect();
- if (small_animated_layer)
- create_tiles_rect = gfx::Rect(content_bounds());
- if (!create_tiles_rect.IsEmpty()) {
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(
- create_tiles_rect, &left, &top, &right, &bottom);
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- if (!TileAt(i, j))
- CreateTile(i, j);
- }
- }
- }
-
- // Now update priorities on all tiles we have in the layer, no matter where
- // they are.
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- gfx::Rect tile_rect = tiler_->TileRect(tile);
- SetPriorityForTexture(predicted_visible_rect_,
- tile_rect,
- draws_to_root,
- small_animated_layer,
- tile->managed_resource());
- }
-}
-
-SimpleEnclosedRegion TiledLayer::VisibleContentOpaqueRegion() const {
- if (skips_draw_)
- return SimpleEnclosedRegion();
- return Layer::VisibleContentOpaqueRegion();
-}
-
-void TiledLayer::ResetUpdateState() {
- skips_draw_ = false;
- failed_update_ = false;
-
- LayerTilingData::TileMap::const_iterator end = tiler_->tiles().end();
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != end;
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- tile->ResetUpdateState();
- }
-}
-
-namespace {
-gfx::Rect ExpandRectByDelta(const gfx::Rect& rect, const gfx::Vector2d& delta) {
- int width = rect.width() + std::abs(delta.x());
- int height = rect.height() + std::abs(delta.y());
- int x = rect.x() + ((delta.x() < 0) ? delta.x() : 0);
- int y = rect.y() + ((delta.y() < 0) ? delta.y() : 0);
- return gfx::Rect(x, y, width, height);
-}
-}
-
-void TiledLayer::UpdateScrollPrediction() {
- // This scroll prediction is very primitive and should be replaced by a
- // a recursive calculation on all layers which uses actual scroll/animation
- // velocities. To insure this doesn't miss-predict, we only use it to predict
- // the visible_rect if:
- // - content_bounds() hasn't changed.
- // - visible_rect.size() hasn't changed.
- // These two conditions prevent rotations, scales, pinch-zooms etc. where
- // the prediction would be incorrect.
- gfx::Vector2d delta = visible_content_rect().CenterPoint() -
- previous_visible_rect_.CenterPoint();
- predicted_scroll_ = -delta;
- predicted_visible_rect_ = visible_content_rect();
- if (previous_content_bounds_ == content_bounds() &&
- previous_visible_rect_.size() == visible_content_rect().size()) {
- // Only expand the visible rect in the major scroll direction, to prevent
- // massive paints due to diagonal scrolls.
- gfx::Vector2d major_scroll_delta =
- (std::abs(delta.x()) > std::abs(delta.y())) ?
- gfx::Vector2d(delta.x(), 0) :
- gfx::Vector2d(0, delta.y());
- predicted_visible_rect_ =
- ExpandRectByDelta(visible_content_rect(), major_scroll_delta);
-
- // Bound the prediction to prevent unbounded paints, and clamp to content
- // bounds.
- gfx::Rect bound = visible_content_rect();
- bound.Inset(-tiler_->tile_size().width() * kMaxPredictiveTilesCount,
- -tiler_->tile_size().height() * kMaxPredictiveTilesCount);
- bound.Intersect(gfx::Rect(content_bounds()));
- predicted_visible_rect_.Intersect(bound);
- }
- previous_content_bounds_ = content_bounds();
- previous_visible_rect_ = visible_content_rect();
-}
-
-bool TiledLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- DCHECK(!skips_draw_ && !failed_update_); // Did ResetUpdateState get skipped?
-
- // Tiled layer always causes commits to wait for activation, as it does
- // not support pending trees.
- SetNextCommitWaitsForActivation();
-
- bool updated = false;
-
- {
- base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
- true);
-
- updated |= ContentsScalingLayer::Update(queue, occlusion);
- UpdateBounds();
- }
-
- if (tiler_->has_empty_bounds() || !DrawsContent())
- return false;
-
- // Animation pre-paint. If the layer is small, try to paint it all
- // immediately whether or not it is occluded, to avoid paint/upload
- // hiccups while it is animating.
- if (IsSmallAnimatedLayer()) {
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(gfx::Rect(content_bounds()),
- &left,
- &top,
- &right,
- &bottom);
- UpdateTiles(left, top, right, bottom, queue, nullptr, &updated);
- if (updated)
- return updated;
- // This was an attempt to paint the entire layer so if we fail it's okay,
- // just fallback on painting visible etc. below.
- failed_update_ = false;
- }
-
- if (predicted_visible_rect_.IsEmpty())
- return updated;
-
- // Visible painting. First occlude visible tiles and paint the non-occluded
- // tiles.
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(
- predicted_visible_rect_, &left, &top, &right, &bottom);
- MarkOcclusionsAndRequestTextures(left, top, right, bottom, occlusion);
- skips_draw_ = !UpdateTiles(
- left, top, right, bottom, queue, occlusion, &updated);
- if (skips_draw_)
- tiler_->reset();
- if (skips_draw_ || updated)
- return true;
-
- // If we have already painting everything visible. Do some pre-painting while
- // idle.
- gfx::Rect idle_paint_content_rect = IdlePaintRect();
- if (idle_paint_content_rect.IsEmpty())
- return updated;
-
- // Prepaint anything that was occluded but inside the layer's visible region.
- if (!UpdateTiles(left, top, right, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
-
- int prepaint_left, prepaint_top, prepaint_right, prepaint_bottom;
- tiler_->ContentRectToTileIndices(idle_paint_content_rect,
- &prepaint_left,
- &prepaint_top,
- &prepaint_right,
- &prepaint_bottom);
-
- // Then expand outwards one row/column at a time until we find a dirty
- // row/column to update. Increment along the major and minor scroll directions
- // first.
- gfx::Vector2d delta = -predicted_scroll_;
- delta = gfx::Vector2d(delta.x() == 0 ? 1 : delta.x(),
- delta.y() == 0 ? 1 : delta.y());
- gfx::Vector2d major_delta =
- (std::abs(delta.x()) > std::abs(delta.y())) ? gfx::Vector2d(delta.x(), 0)
- : gfx::Vector2d(0, delta.y());
- gfx::Vector2d minor_delta =
- (std::abs(delta.x()) <= std::abs(delta.y())) ? gfx::Vector2d(delta.x(), 0)
- : gfx::Vector2d(0, delta.y());
- gfx::Vector2d deltas[4] = { major_delta, minor_delta, -major_delta,
- -minor_delta };
- for (int i = 0; i < 4; i++) {
- if (deltas[i].y() > 0) {
- while (bottom < prepaint_bottom) {
- ++bottom;
- if (!UpdateTiles(
- left, bottom, right, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- if (deltas[i].y() < 0) {
- while (top > prepaint_top) {
- --top;
- if (!UpdateTiles(left, top, right, top, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- if (deltas[i].x() < 0) {
- while (left > prepaint_left) {
- --left;
- if (!UpdateTiles(left, top, left, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- if (deltas[i].x() > 0) {
- while (right < prepaint_right) {
- ++right;
- if (!UpdateTiles(right, top, right, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- }
- return updated;
-}
-
-void TiledLayer::OnOutputSurfaceCreated() {
- // Ensure that all textures are of the right format.
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- if (!tile)
- continue;
- PrioritizedResource* resource = tile->managed_resource();
- resource->SetDimensions(resource->size(), texture_format_);
- }
-}
-
-bool TiledLayer::NeedsIdlePaint() {
- // Don't trigger more paints if we failed (as we'll just fail again).
- if (failed_update_ || visible_content_rect().IsEmpty() ||
- tiler_->has_empty_bounds() || !DrawsContent())
- return false;
-
- gfx::Rect idle_paint_content_rect = IdlePaintRect();
- if (idle_paint_content_rect.IsEmpty())
- return false;
-
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(
- idle_paint_content_rect, &left, &top, &right, &bottom);
-
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorities get skipped?
- if (!tile)
- continue;
-
- bool updated = !tile->update_rect.IsEmpty();
- bool can_acquire =
- tile->managed_resource()->can_acquire_backing_texture();
- bool dirty =
- tile->is_dirty() || !tile->managed_resource()->have_backing_texture();
- if (!updated && can_acquire && dirty)
- return true;
- }
- }
- return false;
-}
-
-gfx::Rect TiledLayer::IdlePaintRect() {
- // Don't inflate an empty rect.
- if (visible_content_rect().IsEmpty())
- return gfx::Rect();
-
- gfx::Rect prepaint_rect = visible_content_rect();
- prepaint_rect.Inset(-tiler_->tile_size().width() * kPrepaintColumns,
- -tiler_->tile_size().height() * kPrepaintRows);
- gfx::Rect content_rect(content_bounds());
- prepaint_rect.Intersect(content_rect);
-
- return prepaint_rect;
-}
-
-} // namespace cc
« no previous file with comments | « cc/layers/tiled_layer.h ('k') | cc/layers/tiled_layer_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698