summaryrefslogtreecommitdiffstats
path: root/chromium/cc/resources/picture_pile.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/resources/picture_pile.cc')
-rw-r--r--chromium/cc/resources/picture_pile.cc110
1 files changed, 84 insertions, 26 deletions
diff --git a/chromium/cc/resources/picture_pile.cc b/chromium/cc/resources/picture_pile.cc
index 68d75d7aea1..6341e88b368 100644
--- a/chromium/cc/resources/picture_pile.cc
+++ b/chromium/cc/resources/picture_pile.cc
@@ -11,6 +11,7 @@
#include "cc/base/region.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/resources/picture_pile_impl.h"
+#include "cc/resources/raster_worker_pool.h"
#include "cc/resources/tile_priority.h"
namespace {
@@ -140,22 +141,24 @@ float ClusterTiles(const std::vector<gfx::Rect>& invalid_tiles,
namespace cc {
-PicturePile::PicturePile() {
-}
+PicturePile::PicturePile() : is_suitable_for_gpu_rasterization_(true) {}
PicturePile::~PicturePile() {
}
-bool PicturePile::Update(
+bool PicturePile::UpdateAndExpandInvalidation(
ContentLayerClient* painter,
+ Region* invalidation,
SkColor background_color,
bool contents_opaque,
- const Region& invalidation,
- gfx::Rect visible_layer_rect,
+ bool contents_fill_bounds_completely,
+ const gfx::Rect& visible_layer_rect,
int frame_number,
+ Picture::RecordingMode recording_mode,
RenderingStatsInstrumentation* stats_instrumentation) {
background_color_ = background_color;
contents_opaque_ = contents_opaque;
+ contents_fill_bounds_completely_ = contents_fill_bounds_completely;
gfx::Rect interest_rect = visible_layer_rect;
interest_rect.Inset(
@@ -163,14 +166,23 @@ bool PicturePile::Update(
-kPixelDistanceToRecord,
-kPixelDistanceToRecord,
-kPixelDistanceToRecord);
+ recorded_viewport_ = interest_rect;
+ recorded_viewport_.Intersect(tiling_rect());
+
+ gfx::Rect interest_rect_over_tiles =
+ tiling_.ExpandRectToTileBounds(interest_rect);
+
+ Region invalidation_expanded_to_full_tiles;
bool invalidated = false;
- for (Region::Iterator i(invalidation); i.has_rect(); i.next()) {
- gfx::Rect invalidation = i.rect();
+ for (Region::Iterator i(*invalidation); i.has_rect(); i.next()) {
+ gfx::Rect invalid_rect = i.rect();
// Split this inflated invalidation across tile boundaries and apply it
// to all tiles that it touches.
- for (TilingData::Iterator iter(&tiling_, invalidation);
- iter; ++iter) {
+ bool include_borders = true;
+ for (TilingData::Iterator iter(&tiling_, invalid_rect, include_borders);
+ iter;
+ ++iter) {
const PictureMapKey& key = iter.index();
PictureMap::iterator picture_it = picture_map_.find(key);
@@ -180,14 +192,28 @@ bool PicturePile::Update(
// Inform the grid cell that it has been invalidated in this frame.
invalidated = picture_it->second.Invalidate(frame_number) || invalidated;
}
+
+ // Expand invalidation that is outside tiles that intersect the interest
+ // rect. These tiles are no longer valid and should be considerered fully
+ // invalid, so we can know to not keep around raster tiles that intersect
+ // with these recording tiles.
+ gfx::Rect invalid_rect_outside_interest_rect_tiles = invalid_rect;
+ // TODO(danakj): We should have a Rect-subtract-Rect-to-2-rects operator
+ // instead of using Rect::Subtract which gives you the bounding box of the
+ // subtraction.
+ invalid_rect_outside_interest_rect_tiles.Subtract(interest_rect_over_tiles);
+ invalidation_expanded_to_full_tiles.Union(tiling_.ExpandRectToTileBounds(
+ invalid_rect_outside_interest_rect_tiles));
}
+ invalidation->Union(invalidation_expanded_to_full_tiles);
+
// Make a list of all invalid tiles; we will attempt to
// cluster these into multiple invalidation regions.
std::vector<gfx::Rect> invalid_tiles;
-
- for (TilingData::Iterator it(&tiling_, interest_rect);
- it; ++it) {
+ bool include_borders = true;
+ for (TilingData::Iterator it(&tiling_, interest_rect, include_borders); it;
+ ++it) {
const PictureMapKey& key = it.index();
PictureInfo& info = picture_map_[key];
@@ -198,17 +224,27 @@ bool PicturePile::Update(
if (info.NeedsRecording(frame_number, distance_to_visible)) {
gfx::Rect tile = tiling_.TileBounds(key.first, key.second);
invalid_tiles.push_back(tile);
+ } else if (!info.GetPicture()) {
+ if (recorded_viewport_.Intersects(rect)) {
+ // Recorded viewport is just an optimization for a fully recorded
+ // interest rect. In this case, a tile in that rect has declined
+ // to be recorded (probably due to frequent invalidations).
+ // TODO(enne): Shrink the recorded_viewport_ rather than clearing.
+ recorded_viewport_ = gfx::Rect();
+ }
+
+ // If a tile in the interest rect is not recorded, the entire tile needs
+ // to be considered invalid, so that we know not to keep around raster
+ // tiles that intersect this recording tile.
+ invalidation->Union(tiling_.TileBounds(it.index_x(), it.index_y()));
}
}
std::vector<gfx::Rect> record_rects;
ClusterTiles(invalid_tiles, &record_rects);
- if (record_rects.empty()) {
- if (invalidated)
- UpdateRecordedRegion();
+ if (record_rects.empty())
return invalidated;
- }
for (std::vector<gfx::Rect>::iterator it = record_rects.begin();
it != record_rects.end();
@@ -217,14 +253,33 @@ bool PicturePile::Update(
record_rect = PadRect(record_rect);
int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
- scoped_refptr<Picture> picture = Picture::Create(record_rect);
+ scoped_refptr<Picture> picture;
+ int num_raster_threads = RasterWorkerPool::GetNumRasterThreads();
+
+ // Note: Currently, gathering of pixel refs when using a single
+ // raster thread doesn't provide any benefit. This might change
+ // in the future but we avoid it for now to reduce the cost of
+ // Picture::Create.
+ bool gather_pixel_refs = num_raster_threads > 1;
{
- base::TimeDelta best_duration = base::TimeDelta::FromInternalValue(
- std::numeric_limits<int64>::max());
+ base::TimeDelta best_duration = base::TimeDelta::Max();
for (int i = 0; i < repeat_count; i++) {
base::TimeTicks start_time = stats_instrumentation->StartRecording();
- picture->Record(painter, tile_grid_info_);
+ picture = Picture::Create(record_rect,
+ painter,
+ tile_grid_info_,
+ gather_pixel_refs,
+ num_raster_threads,
+ recording_mode);
+ // Note the '&&' with previous is-suitable state.
+ // This means that once a picture-pile becomes unsuitable for gpu
+ // rasterization due to some content, it will continue to be unsuitable
+ // even if that content is replaced by gpu-friendly content.
+ // This is an optimization to avoid iterating though all pictures in
+ // the pile after each invalidation.
+ is_suitable_for_gpu_rasterization_ &=
+ picture->IsSuitableForGpuRasterization();
base::TimeDelta duration =
stats_instrumentation->EndRecording(start_time);
best_duration = std::min(duration, best_duration);
@@ -232,23 +287,26 @@ bool PicturePile::Update(
int recorded_pixel_count =
picture->LayerRect().width() * picture->LayerRect().height();
stats_instrumentation->AddRecord(best_duration, recorded_pixel_count);
- if (num_raster_threads_ > 1)
- picture->GatherPixelRefs(tile_grid_info_);
- picture->CloneForDrawing(num_raster_threads_);
}
- for (TilingData::Iterator it(&tiling_, record_rect);
- it; ++it) {
+ bool found_tile_for_recorded_picture = false;
+
+ bool include_borders = true;
+ for (TilingData::Iterator it(&tiling_, record_rect, include_borders); it;
+ ++it) {
const PictureMapKey& key = it.index();
gfx::Rect tile = PaddedRect(key);
if (record_rect.Contains(tile)) {
PictureInfo& info = picture_map_[key];
info.SetPicture(picture);
+ found_tile_for_recorded_picture = true;
}
}
+ DCHECK(found_tile_for_recorded_picture);
}
- UpdateRecordedRegion();
+ has_any_recordings_ = true;
+ DCHECK(CanRasterSlowTileCheck(recorded_viewport_));
return true;
}