| Index: cc/resources/display_list_recording_source.cc
|
| diff --git a/cc/resources/display_list_recording_source.cc b/cc/resources/display_list_recording_source.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3c0e0e4c74272e0a5b7037931079dc6c65028cd3
|
| --- /dev/null
|
| +++ b/cc/resources/display_list_recording_source.cc
|
| @@ -0,0 +1,158 @@
|
| +// Copyright 2014 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/resources/display_list_recording_source.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "cc/base/region.h"
|
| +#include "cc/layers/content_layer_client.h"
|
| +#include "cc/resources/display_item_list.h"
|
| +#include "cc/resources/display_list_raster_source.h"
|
| +#include "skia/ext/analysis_canvas.h"
|
| +
|
| +namespace {
|
| +
|
| +// Layout pixel buffer around the visible layer rect to record. Any base
|
| +// picture that intersects the visible layer rect expanded by this distance
|
| +// will be recorded.
|
| +const int kPixelDistanceToRecord = 8000;
|
| +// We don't perform solid color analysis on images that have more than 10 skia
|
| +// operations.
|
| +const int kOpCountThatIsOkToAnalyze = 10;
|
| +
|
| +} // namespace
|
| +
|
| +namespace cc {
|
| +
|
| +DisplayListRecordingSource::DisplayListRecordingSource()
|
| + : slow_down_raster_scale_factor_for_debug_(0),
|
| + can_use_lcd_text_(true),
|
| + is_solid_color_(false),
|
| + solid_color_(SK_ColorTRANSPARENT),
|
| + pixel_record_distance_(kPixelDistanceToRecord),
|
| + is_suitable_for_gpu_rasterization_(true) {
|
| +}
|
| +
|
| +DisplayListRecordingSource::~DisplayListRecordingSource() {
|
| +}
|
| +
|
| +bool DisplayListRecordingSource::UpdateAndExpandInvalidation(
|
| + ContentLayerClient* painter,
|
| + Region* invalidation,
|
| + bool can_use_lcd_text,
|
| + const gfx::Size& layer_size,
|
| + const gfx::Rect& visible_layer_rect,
|
| + int frame_number,
|
| + Picture::RecordingMode recording_mode) {
|
| + bool updated = false;
|
| +
|
| + if (size_ != layer_size) {
|
| + size_ = layer_size;
|
| + updated = true;
|
| + }
|
| +
|
| + if (can_use_lcd_text_ != can_use_lcd_text) {
|
| + can_use_lcd_text_ = can_use_lcd_text;
|
| + invalidation->Union(gfx::Rect(GetSize()));
|
| + updated = true;
|
| + }
|
| +
|
| + gfx::Rect old_recorded_viewport = recorded_viewport_;
|
| + recorded_viewport_ = visible_layer_rect;
|
| + recorded_viewport_.Inset(-pixel_record_distance_, -pixel_record_distance_);
|
| + recorded_viewport_.Intersect(gfx::Rect(GetSize()));
|
| +
|
| + if (recorded_viewport_ != old_recorded_viewport) {
|
| + // Invalidate newly-exposed and no-longer-exposed areas.
|
| + Region newly_exposed_region(recorded_viewport_);
|
| + newly_exposed_region.Subtract(old_recorded_viewport);
|
| + invalidation->Union(newly_exposed_region);
|
| +
|
| + Region no_longer_exposed_region(old_recorded_viewport);
|
| + no_longer_exposed_region.Subtract(recorded_viewport_);
|
| + invalidation->Union(no_longer_exposed_region);
|
| +
|
| + updated = true;
|
| + }
|
| +
|
| + if (!updated && !invalidation->Intersects(recorded_viewport_))
|
| + return false;
|
| +
|
| + // TODO(ajuma): Does repeating this way really makes sense with display lists?
|
| + // With Blink caching recordings, repeated calls will not cause re-recording.
|
| + int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
|
| + for (int i = 0; i < repeat_count; ++i) {
|
| + display_list_ = painter->PaintContentsToDisplayList(
|
| + recorded_viewport_, ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
|
| + }
|
| + is_suitable_for_gpu_rasterization_ =
|
| + display_list_->IsSuitableForGpuRasterization();
|
| +
|
| + DetermineIfSolidColor();
|
| + display_list_->EmitTraceSnapshot();
|
| + return true;
|
| +}
|
| +
|
| +gfx::Size DisplayListRecordingSource::GetSize() const {
|
| + return size_;
|
| +}
|
| +
|
| +void DisplayListRecordingSource::SetEmptyBounds() {
|
| + size_ = gfx::Size();
|
| + Clear();
|
| +}
|
| +
|
| +void DisplayListRecordingSource::SetMinContentsScale(float min_contents_scale) {
|
| +}
|
| +
|
| +void DisplayListRecordingSource::SetTileGridSize(
|
| + const gfx::Size& tile_grid_size) {
|
| +}
|
| +
|
| +void DisplayListRecordingSource::SetSlowdownRasterScaleFactor(int factor) {
|
| + slow_down_raster_scale_factor_for_debug_ = factor;
|
| +}
|
| +
|
| +void DisplayListRecordingSource::SetUnsuitableForGpuRasterizationForTesting() {
|
| + is_suitable_for_gpu_rasterization_ = false;
|
| +}
|
| +
|
| +bool DisplayListRecordingSource::IsSuitableForGpuRasterization() const {
|
| + return is_suitable_for_gpu_rasterization_;
|
| +}
|
| +
|
| +scoped_refptr<RasterSource> DisplayListRecordingSource::CreateRasterSource()
|
| + const {
|
| + return scoped_refptr<RasterSource>(
|
| + DisplayListRasterSource::CreateFromDisplayListRecordingSource(this));
|
| +}
|
| +
|
| +SkTileGridFactory::TileGridInfo
|
| +DisplayListRecordingSource::GetTileGridInfoForTesting() const {
|
| + return SkTileGridFactory::TileGridInfo();
|
| +}
|
| +
|
| +void DisplayListRecordingSource::DetermineIfSolidColor() {
|
| + DCHECK(display_list_.get());
|
| + is_solid_color_ = false;
|
| + solid_color_ = SK_ColorTRANSPARENT;
|
| +
|
| + if (display_list_->ApproximateOpCount() > kOpCountThatIsOkToAnalyze)
|
| + return;
|
| +
|
| + skia::AnalysisCanvas canvas(recorded_viewport_.width(),
|
| + recorded_viewport_.height());
|
| + canvas.translate(-recorded_viewport_.x(), -recorded_viewport_.y());
|
| + display_list_->Raster(&canvas, nullptr, 1.f);
|
| + is_solid_color_ = canvas.GetColorIfSolid(&solid_color_);
|
| +}
|
| +
|
| +void DisplayListRecordingSource::Clear() {
|
| + recorded_viewport_ = gfx::Rect();
|
| + display_list_ = NULL;
|
| + is_solid_color_ = false;
|
| +}
|
| +
|
| +} // namespace cc
|
|
|