diff options
-rw-r--r-- | cc/base/invalidation_region.h | 1 | ||||
-rw-r--r-- | cc/debug/debug_rect_history.cc | 4 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 2 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 2 | ||||
-rw-r--r-- | cc/layers/picture_layer.cc | 26 | ||||
-rw-r--r-- | cc/layers/picture_layer.h | 6 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 2 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.h | 2 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl_unittest.cc | 6 | ||||
-rw-r--r-- | cc/layers/picture_layer_unittest.cc | 86 | ||||
-rw-r--r-- | cc/playback/display_list_recording_source.cc | 14 | ||||
-rw-r--r-- | cc/playback/display_list_recording_source.h | 5 | ||||
-rw-r--r-- | cc/test/fake_display_list_recording_source.h | 3 |
13 files changed, 128 insertions, 31 deletions
diff --git a/cc/base/invalidation_region.h b/cc/base/invalidation_region.h index 3cf69f2..7aa4a8b 100644 --- a/cc/base/invalidation_region.h +++ b/cc/base/invalidation_region.h @@ -23,7 +23,6 @@ class CC_EXPORT InvalidationRegion { void Clear(); void Union(const gfx::Rect& rect); bool IsEmpty() const { return region_.IsEmpty(); } - Region* region() { return ®ion_; } private: void SimplifyIfNeeded(); diff --git a/cc/debug/debug_rect_history.cc b/cc/debug/debug_rect_history.cc index 5ac2b5d..bbeb1b9 100644 --- a/cc/debug/debug_rect_history.cc +++ b/cc/debug/debug_rect_history.cc @@ -67,8 +67,8 @@ void DebugRectHistory::SaveDebugRectsForCurrentFrame( void DebugRectHistory::SavePaintRects(LayerImpl* layer) { // We would like to visualize where any layer's paint rect (update rect) has // changed, regardless of whether this layer is skipped for actual drawing or - // not. Therefore we traverse recursively over all layers, not just the render - // surface list. + // not. Therefore we traverse over all layers, not just the render surface + // list. Region invalidation_region = layer->GetInvalidationRegion(); if (!invalidation_region.IsEmpty() && layer->DrawsContent()) { diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index b845968..40bc9d5 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -1879,7 +1879,7 @@ void LayerImpl::SetForceRenderSurface(bool force_render_surface) { NoteLayerPropertyChanged(); } -Region LayerImpl::GetInvalidationRegion() { +Region LayerImpl::GetInvalidationRegionForDebugging() { return Region(update_rect_); } diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 4dca350..face8a6 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -651,7 +651,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, // Get the correct invalidation region instead of conservative Rect // for layers that provide it. - virtual Region GetInvalidationRegion(); + virtual Region GetInvalidationRegionForDebugging(); virtual gfx::Rect GetEnclosingRectInTargetSpace() const; diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index f9df22cd..fb89080 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc @@ -65,9 +65,9 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) { recording_source_->CreateRasterSource(can_use_lcd_text); layer_impl->set_gpu_raster_max_texture_size( layer_tree_host()->device_viewport_size()); - layer_impl->UpdateRasterSource(raster_source, invalidation_.region(), + layer_impl->UpdateRasterSource(raster_source, &last_updated_invalidation_, nullptr); - DCHECK(invalidation_.IsEmpty()); + DCHECK(last_updated_invalidation_.IsEmpty()); } void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) { @@ -88,10 +88,8 @@ void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) { void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) { DCHECK(!layer_tree_host() || !layer_tree_host()->in_paint_layer_contents()); - if (!layer_rect.IsEmpty()) { - // Clamp invalidation to the layer bounds. - invalidation_.Union(gfx::IntersectRects(layer_rect, gfx::Rect(bounds()))); - } + if (recording_source_) + recording_source_->SetNeedsDisplayRect(layer_rect); Layer::SetNeedsDisplayRect(layer_rect); } @@ -102,12 +100,6 @@ bool PictureLayer::Update() { gfx::Rect update_rect = visible_layer_rect(); gfx::Size layer_size = paint_properties().bounds; - if (last_updated_visible_layer_rect_ == update_rect && - recording_source_->GetSize() == layer_size && invalidation_.IsEmpty()) { - // Only early out if the visible content rect of this layer hasn't changed. - return updated; - } - recording_source_->SetBackgroundColor(SafeOpaqueBackgroundColor()); recording_source_->SetRequiresClear(!contents_opaque() && !client_->FillsBoundsCompletely()); @@ -124,7 +116,7 @@ bool PictureLayer::Update() { // for them. DCHECK(client_); updated |= recording_source_->UpdateAndExpandInvalidation( - client_, invalidation_.region(), layer_size, update_rect, + client_, &last_updated_invalidation_, layer_size, update_rect, update_source_frame_number_, DisplayListRecordingSource::RECORD_NORMALLY); last_updated_visible_layer_rect_ = visible_layer_rect(); @@ -133,7 +125,7 @@ bool PictureLayer::Update() { } else { // If this invalidation did not affect the recording source, then it can be // cleared as an optimization. - invalidation_.Clear(); + last_updated_invalidation_.Clear(); } return updated; @@ -196,7 +188,7 @@ void PictureLayer::LayerSpecificPropertiesToProto( proto::PictureLayerProperties* picture = proto->mutable_picture(); recording_source_->ToProtobuf(picture->mutable_recording_source()); - RegionToProto(*invalidation_.region(), picture->mutable_invalidation()); + RegionToProto(last_updated_invalidation_, picture->mutable_invalidation()); RectToProto(last_updated_visible_layer_rect_, picture->mutable_last_updated_visible_layer_rect()); picture->set_is_mask(is_mask_); @@ -204,7 +196,7 @@ void PictureLayer::LayerSpecificPropertiesToProto( picture->set_update_source_frame_number(update_source_frame_number_); - invalidation_.Clear(); + last_updated_invalidation_.Clear(); } void PictureLayer::FromLayerSpecificPropertiesProto( @@ -214,7 +206,7 @@ void PictureLayer::FromLayerSpecificPropertiesProto( recording_source_->FromProtobuf(picture.recording_source()); Region new_invalidation = RegionFromProto(picture.invalidation()); - invalidation_.Swap(&new_invalidation); + last_updated_invalidation_.Swap(&new_invalidation); last_updated_visible_layer_rect_ = ProtoToRect(picture.last_updated_visible_layer_rect()); is_mask_ = picture.is_mask(); diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h index b7e7152..6f71735 100644 --- a/cc/layers/picture_layer.h +++ b/cc/layers/picture_layer.h @@ -70,10 +70,10 @@ class CC_EXPORT PictureLayer : public Layer { devtools_instrumentation:: ScopedLayerObjectTracker instrumentation_object_tracker_; - // Invalidation to use the next time update is called. - InvalidationRegion invalidation_; - + // These store the last visible layer and invalidation computed via a call + // to Update(). gfx::Rect last_updated_visible_layer_rect_; + Region last_updated_invalidation_; int update_source_frame_number_; bool is_mask_; diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 0ec6ed7..124e5e7 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -648,7 +648,7 @@ skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() { return raster_source_->GetFlattenedPicture(); } -Region PictureLayerImpl::GetInvalidationRegion() { +Region PictureLayerImpl::GetInvalidationRegionForDebugging() { // |invalidation_| gives the invalidation contained in the source frame, but // is not cleared after drawing from the layer. However, update_rect() is // cleared once the invalidation is drawn, which is useful for debugging diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index 03316dcd..4cd9a98 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h @@ -53,7 +53,7 @@ class CC_EXPORT PictureLayerImpl void ReleaseResources() override; void RecreateResources() override; skia::RefPtr<SkPicture> GetPicture() override; - Region GetInvalidationRegion() override; + Region GetInvalidationRegionForDebugging() override; // PictureLayerTilingClient overrides. ScopedTilePtr CreateTile(const Tile::CreateInfo& info) override; diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 9d1bbc9..5622cc3 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -4530,7 +4530,8 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { client.set_fill_with_nonsolid_color(true); - Region invalidation1(layer_rect); + recording_source->SetNeedsDisplayRect(layer_rect); + Region invalidation1; recording_source->UpdateAndExpandInvalidation( &client, &invalidation1, layer_bounds, layer_rect, frame_number++, DisplayListRecordingSource::RECORD_NORMALLY); @@ -4549,7 +4550,8 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { client.set_fill_with_nonsolid_color(false); - Region invalidation2(layer_rect); + recording_source->SetNeedsDisplayRect(layer_rect); + Region invalidation2; recording_source->UpdateAndExpandInvalidation( &client, &invalidation2, layer_bounds, layer_rect, frame_number++, DisplayListRecordingSource::RECORD_NORMALLY); diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index 1ce7567..2cdd8a4 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc @@ -46,7 +46,7 @@ class TestSerializationPictureLayer : public PictureLayer { } void set_invalidation(const Region& invalidation) { - *invalidation_.region() = invalidation; + last_updated_invalidation_ = invalidation; } void set_last_updated_visible_layer_rect(const gfx::Rect& rect) { @@ -203,6 +203,90 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) { EXPECT_FALSE(layer_impl->raster_source()->HasRecordings()); } +TEST(PictureLayerTest, InvalidateRasterAfterUpdate) { + gfx::Size layer_size(50, 50); + FakeContentLayerClient client; + client.set_bounds(layer_size); + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); + layer->SetBounds(gfx::Size(50, 50)); + + FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); + TestTaskGraphRunner task_graph_runner; + scoped_ptr<FakeLayerTreeHost> host = + FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + host->SetRootLayer(layer); + layer->SetIsDrawable(true); + layer->SavePaintProperties(); + + gfx::Rect invalidation_bounds(layer_size); + + // The important two lines are the following: + layer->SetNeedsDisplayRect(invalidation_bounds); + layer->Update(); + + host->CommitComplete(); + FakeImplTaskRunnerProvider impl_task_runner_provider; + TestSharedBitmapManager shared_bitmap_manager; + scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + LayerTreeSettings layer_tree_settings = LayerTreeSettings(); + layer_tree_settings.image_decode_tasks_enabled = true; + FakeLayerTreeHostImpl host_impl(layer_tree_settings, + &impl_task_runner_provider, + &shared_bitmap_manager, &task_graph_runner); + host_impl.SetVisible(true); + host_impl.InitializeRenderer(output_surface.get()); + host_impl.CreatePendingTree(); + host_impl.pending_tree()->SetRootLayer( + FakePictureLayerImpl::Create(host_impl.pending_tree(), 1)); + FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>( + host_impl.pending_tree()->root_layer()); + layer->PushPropertiesTo(layer_impl); + + EXPECT_EQ(invalidation_bounds, + layer_impl->GetPendingInvalidation()->bounds()); +} + +TEST(PictureLayerTest, InvalidateRasterWithoutUpdate) { + gfx::Size layer_size(50, 50); + FakeContentLayerClient client; + client.set_bounds(layer_size); + scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); + layer->SetBounds(gfx::Size(50, 50)); + + FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D); + TestTaskGraphRunner task_graph_runner; + scoped_ptr<FakeLayerTreeHost> host = + FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + host->SetRootLayer(layer); + layer->SetIsDrawable(true); + layer->SavePaintProperties(); + + gfx::Rect invalidation_bounds(layer_size); + + // The important line is the following (note that we do not call Update): + layer->SetNeedsDisplayRect(invalidation_bounds); + + host->CommitComplete(); + FakeImplTaskRunnerProvider impl_task_runner_provider; + TestSharedBitmapManager shared_bitmap_manager; + scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d()); + LayerTreeSettings layer_tree_settings = LayerTreeSettings(); + layer_tree_settings.image_decode_tasks_enabled = true; + FakeLayerTreeHostImpl host_impl(layer_tree_settings, + &impl_task_runner_provider, + &shared_bitmap_manager, &task_graph_runner); + host_impl.SetVisible(true); + host_impl.InitializeRenderer(output_surface.get()); + host_impl.CreatePendingTree(); + host_impl.pending_tree()->SetRootLayer( + FakePictureLayerImpl::Create(host_impl.pending_tree(), 1)); + FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>( + host_impl.pending_tree()->root_layer()); + layer->PushPropertiesTo(layer_impl); + + EXPECT_EQ(gfx::Rect(), layer_impl->GetPendingInvalidation()->bounds()); +} + TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { gfx::Size layer_size(50, 50); FakeContentLayerClient client; diff --git a/cc/playback/display_list_recording_source.cc b/cc/playback/display_list_recording_source.cc index d4e6a3e..bfd8fdd 100644 --- a/cc/playback/display_list_recording_source.cc +++ b/cc/playback/display_list_recording_source.cc @@ -111,6 +111,14 @@ void DisplayListRecordingSource::FinishDisplayItemListUpdate() { display_list_->GenerateDiscardableImagesMetadata(); } +void DisplayListRecordingSource::SetNeedsDisplayRect( + const gfx::Rect& layer_rect) { + if (!layer_rect.IsEmpty()) { + // Clamp invalidation to the layer bounds. + invalidation_.Union(gfx::IntersectRects(layer_rect, gfx::Rect(size_))); + } +} + bool DisplayListRecordingSource::UpdateAndExpandInvalidation( ContentLayerClient* painter, Region* invalidation, @@ -127,6 +135,9 @@ bool DisplayListRecordingSource::UpdateAndExpandInvalidation( updated = true; } + invalidation_.Swap(invalidation); + invalidation_.Clear(); + gfx::Rect new_recorded_viewport = painter->PaintableRegion(); if (new_recorded_viewport != recorded_viewport_) { UpdateInvalidationForNewViewport(recorded_viewport_, new_recorded_viewport, @@ -144,6 +155,9 @@ bool DisplayListRecordingSource::UpdateAndExpandInvalidation( if (!updated && !invalidation->Intersects(recorded_viewport_)) return false; + if (invalidation->IsEmpty()) + return false; + ContentLayerClient::PaintingControlSetting painting_control = ContentLayerClient::PAINTING_BEHAVIOR_NORMAL; diff --git a/cc/playback/display_list_recording_source.h b/cc/playback/display_list_recording_source.h index 4fb2164..543a040 100644 --- a/cc/playback/display_list_recording_source.h +++ b/cc/playback/display_list_recording_source.h @@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" +#include "cc/base/invalidation_region.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -59,6 +60,8 @@ class CC_EXPORT DisplayListRecordingSource { void SetBackgroundColor(SkColor background_color); void SetRequiresClear(bool requires_clear); + void SetNeedsDisplayRect(const gfx::Rect& layer_rect); + // These functions are virtual for testing. virtual scoped_refptr<DisplayListRasterSource> CreateRasterSource( bool can_use_lcd_text) const; @@ -92,6 +95,8 @@ class CC_EXPORT DisplayListRecordingSource { void DetermineIfSolidColor(); + InvalidationRegion invalidation_; + DISALLOW_COPY_AND_ASSIGN(DisplayListRecordingSource); }; diff --git a/cc/test/fake_display_list_recording_source.h b/cc/test/fake_display_list_recording_source.h index 158c053..28ea1ab 100644 --- a/cc/test/fake_display_list_recording_source.h +++ b/cc/test/fake_display_list_recording_source.h @@ -68,7 +68,8 @@ class FakeDisplayListRecordingSource : public DisplayListRecordingSource { } void Rerecord() { - Region invalidation = recorded_viewport_; + SetNeedsDisplayRect(recorded_viewport_); + Region invalidation; UpdateAndExpandInvalidation(&client_, &invalidation, size_, recorded_viewport_, 0, RECORD_NORMALLY); } |