| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/layers/picture_layer.h" | 5 #include "cc/layers/picture_layer.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.h" |
| 9 #include "cc/layers/content_layer_client.h" | 9 #include "cc/layers/content_layer_client.h" |
| 10 #include "cc/layers/picture_layer_impl.h" | 10 #include "cc/layers/picture_layer_impl.h" |
| 11 #include "cc/playback/recording_source.h" | 11 #include "cc/playback/recording_source.h" |
| 12 #include "cc/proto/cc_conversions.h" | 12 #include "cc/proto/cc_conversions.h" |
| 13 #include "cc/proto/gfx_conversions.h" | 13 #include "cc/proto/gfx_conversions.h" |
| 14 #include "cc/proto/layer.pb.h" | 14 #include "cc/proto/layer.pb.h" |
| 15 #include "cc/trees/layer_tree_host.h" | 15 #include "cc/trees/layer_tree_host.h" |
| 16 #include "cc/trees/layer_tree_impl.h" | 16 #include "cc/trees/layer_tree_impl.h" |
| 17 #include "third_party/skia/include/core/SkPictureRecorder.h" | 17 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 18 #include "ui/gfx/geometry/rect_conversions.h" | 18 #include "ui/gfx/geometry/rect_conversions.h" |
| 19 | 19 |
| 20 namespace cc { | 20 namespace cc { |
| 21 | 21 |
| 22 PictureLayer::PictureLayerInputs::PictureLayerInputs() = default; |
| 23 |
| 24 PictureLayer::PictureLayerInputs::~PictureLayerInputs() = default; |
| 25 |
| 22 scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) { | 26 scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) { |
| 23 return make_scoped_refptr(new PictureLayer(client)); | 27 return make_scoped_refptr(new PictureLayer(client)); |
| 24 } | 28 } |
| 25 | 29 |
| 26 PictureLayer::PictureLayer(ContentLayerClient* client) | 30 PictureLayer::PictureLayer(ContentLayerClient* client) |
| 27 : instrumentation_object_tracker_(id()), | 31 : instrumentation_object_tracker_(id()), |
| 28 update_source_frame_number_(-1), | 32 update_source_frame_number_(-1), |
| 29 is_mask_(false) { | 33 is_mask_(false) { |
| 30 picture_layer_inputs_.client = client; | 34 picture_layer_inputs_.client = client; |
| 31 } | 35 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 "source_frame_number", | 107 "source_frame_number", |
| 104 layer_tree_host()->source_frame_number()); | 108 layer_tree_host()->source_frame_number()); |
| 105 devtools_instrumentation::ScopedLayerTreeTask update_layer( | 109 devtools_instrumentation::ScopedLayerTreeTask update_layer( |
| 106 devtools_instrumentation::kUpdateLayer, id(), layer_tree_host()->id()); | 110 devtools_instrumentation::kUpdateLayer, id(), layer_tree_host()->id()); |
| 107 | 111 |
| 108 // UpdateAndExpandInvalidation will give us an invalidation that covers | 112 // UpdateAndExpandInvalidation will give us an invalidation that covers |
| 109 // anything not explicitly recorded in this frame. We give this region | 113 // anything not explicitly recorded in this frame. We give this region |
| 110 // to the impl side so that it drops tiles that may not have a recording | 114 // to the impl side so that it drops tiles that may not have a recording |
| 111 // for them. | 115 // for them. |
| 112 DCHECK(picture_layer_inputs_.client); | 116 DCHECK(picture_layer_inputs_.client); |
| 117 |
| 118 picture_layer_inputs_.recorded_viewport = |
| 119 picture_layer_inputs_.client->PaintableRegion(); |
| 120 |
| 113 updated |= recording_source_->UpdateAndExpandInvalidation( | 121 updated |= recording_source_->UpdateAndExpandInvalidation( |
| 114 picture_layer_inputs_.client, &last_updated_invalidation_, layer_size, | 122 &last_updated_invalidation_, layer_size, |
| 115 update_source_frame_number_, RecordingSource::RECORD_NORMALLY); | 123 picture_layer_inputs_.recorded_viewport); |
| 116 | 124 |
| 117 if (updated) { | 125 if (updated) { |
| 126 picture_layer_inputs_.display_list = |
| 127 picture_layer_inputs_.client->PaintContentsToDisplayList( |
| 128 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); |
| 129 picture_layer_inputs_.painter_reported_memory_usage = |
| 130 picture_layer_inputs_.client->GetApproximateUnsharedMemoryUsage(); |
| 131 recording_source_->UpdateDisplayItemList( |
| 132 picture_layer_inputs_.display_list, |
| 133 picture_layer_inputs_.painter_reported_memory_usage); |
| 118 SetNeedsPushProperties(); | 134 SetNeedsPushProperties(); |
| 119 } else { | 135 } else { |
| 120 // If this invalidation did not affect the recording source, then it can be | 136 // If this invalidation did not affect the recording source, then it can be |
| 121 // cleared as an optimization. | 137 // cleared as an optimization. |
| 122 last_updated_invalidation_.Clear(); | 138 last_updated_invalidation_.Clear(); |
| 123 } | 139 } |
| 124 | 140 |
| 125 return updated; | 141 return updated; |
| 126 } | 142 } |
| 127 | 143 |
| 128 void PictureLayer::SetIsMask(bool is_mask) { | 144 void PictureLayer::SetIsMask(bool is_mask) { |
| 129 is_mask_ = is_mask; | 145 is_mask_ = is_mask; |
| 130 } | 146 } |
| 131 | 147 |
| 132 sk_sp<SkPicture> PictureLayer::GetPicture() const { | 148 sk_sp<SkPicture> PictureLayer::GetPicture() const { |
| 133 // We could either flatten the RecordingSource into a single | 149 // We could either flatten the RecordingSource into a single |
| 134 // SkPicture, or paint a fresh one depending on what we intend to do with the | 150 // SkPicture, or paint a fresh one depending on what we intend to do with the |
| 135 // picture. For now we just paint a fresh one to get consistent results. | 151 // picture. For now we just paint a fresh one to get consistent results. |
| 136 if (!DrawsContent()) | 152 if (!DrawsContent()) |
| 137 return nullptr; | 153 return nullptr; |
| 138 | 154 |
| 139 gfx::Size layer_size = bounds(); | 155 gfx::Size layer_size = bounds(); |
| 140 std::unique_ptr<RecordingSource> recording_source(new RecordingSource); | 156 RecordingSource recording_source; |
| 141 Region recording_invalidation; | 157 Region recording_invalidation; |
| 142 recording_source->UpdateAndExpandInvalidation( | 158 |
| 143 picture_layer_inputs_.client, &recording_invalidation, layer_size, | 159 gfx::Rect new_recorded_viewport = |
| 144 update_source_frame_number_, RecordingSource::RECORD_NORMALLY); | 160 picture_layer_inputs_.client->PaintableRegion(); |
| 161 scoped_refptr<DisplayItemList> display_list = |
| 162 picture_layer_inputs_.client->PaintContentsToDisplayList( |
| 163 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL); |
| 164 size_t painter_reported_memory_usage = |
| 165 picture_layer_inputs_.client->GetApproximateUnsharedMemoryUsage(); |
| 166 |
| 167 recording_source.UpdateAndExpandInvalidation( |
| 168 &recording_invalidation, layer_size, new_recorded_viewport); |
| 169 recording_source.UpdateDisplayItemList(display_list, |
| 170 painter_reported_memory_usage); |
| 145 | 171 |
| 146 scoped_refptr<RasterSource> raster_source = | 172 scoped_refptr<RasterSource> raster_source = |
| 147 recording_source->CreateRasterSource(false); | 173 recording_source.CreateRasterSource(false); |
| 148 | 174 |
| 149 return raster_source->GetFlattenedPicture(); | 175 return raster_source->GetFlattenedPicture(); |
| 150 } | 176 } |
| 151 | 177 |
| 152 bool PictureLayer::IsSuitableForGpuRasterization() const { | 178 bool PictureLayer::IsSuitableForGpuRasterization() const { |
| 153 return recording_source_->IsSuitableForGpuRasterization(); | 179 // The display list needs to be created (see: UpdateAndExpandInvalidation) |
| 180 // before checking for suitability. There are cases where an update will not |
| 181 // create a display list (e.g., if the size is empty). We return true in these |
| 182 // cases because the gpu suitability bit sticks false. |
| 183 return !picture_layer_inputs_.display_list || |
| 184 picture_layer_inputs_.display_list->IsSuitableForGpuRasterization(); |
| 154 } | 185 } |
| 155 | 186 |
| 156 void PictureLayer::ClearClient() { | 187 void PictureLayer::ClearClient() { |
| 157 picture_layer_inputs_.client = nullptr; | 188 picture_layer_inputs_.client = nullptr; |
| 158 UpdateDrawsContent(HasDrawableContent()); | 189 UpdateDrawsContent(HasDrawableContent()); |
| 159 } | 190 } |
| 160 | 191 |
| 161 void PictureLayer::SetNearestNeighbor(bool nearest_neighbor) { | 192 void PictureLayer::SetNearestNeighbor(bool nearest_neighbor) { |
| 162 if (picture_layer_inputs_.nearest_neighbor == nearest_neighbor) | 193 if (picture_layer_inputs_.nearest_neighbor == nearest_neighbor) |
| 163 return; | 194 return; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 175 } | 206 } |
| 176 | 207 |
| 177 void PictureLayer::LayerSpecificPropertiesToProto( | 208 void PictureLayer::LayerSpecificPropertiesToProto( |
| 178 proto::LayerProperties* proto) { | 209 proto::LayerProperties* proto) { |
| 179 Layer::LayerSpecificPropertiesToProto(proto); | 210 Layer::LayerSpecificPropertiesToProto(proto); |
| 180 DropRecordingSourceContentIfInvalid(); | 211 DropRecordingSourceContentIfInvalid(); |
| 181 | 212 |
| 182 proto::PictureLayerProperties* picture = proto->mutable_picture(); | 213 proto::PictureLayerProperties* picture = proto->mutable_picture(); |
| 183 recording_source_->ToProtobuf(picture->mutable_recording_source()); | 214 recording_source_->ToProtobuf(picture->mutable_recording_source()); |
| 184 | 215 |
| 185 // Add all SkPicture items to the picture cache. | 216 RectToProto(picture_layer_inputs_.recorded_viewport, |
| 186 const DisplayItemList* display_list = recording_source_->GetDisplayItemList(); | 217 picture->mutable_recorded_viewport()); |
| 187 if (display_list) { | 218 if (picture_layer_inputs_.display_list) { |
| 188 for (auto it = display_list->begin(); it != display_list->end(); ++it) { | 219 picture_layer_inputs_.display_list->ToProtobuf( |
| 189 sk_sp<const SkPicture> picture = it->GetPicture(); | 220 picture->mutable_display_list()); |
| 221 for (const auto& item : *picture_layer_inputs_.display_list) { |
| 222 sk_sp<const SkPicture> picture = item.GetPicture(); |
| 190 // Only DrawingDisplayItems have SkPictures. | 223 // Only DrawingDisplayItems have SkPictures. |
| 191 if (!picture) | 224 if (!picture) |
| 192 continue; | 225 continue; |
| 193 | 226 |
| 194 layer_tree_host()->engine_picture_cache()->MarkUsed(picture.get()); | 227 layer_tree_host()->engine_picture_cache()->MarkUsed(picture.get()); |
| 195 } | 228 } |
| 196 } | 229 } |
| 197 | 230 |
| 198 RegionToProto(last_updated_invalidation_, picture->mutable_invalidation()); | 231 RegionToProto(last_updated_invalidation_, picture->mutable_invalidation()); |
| 199 picture->set_is_mask(is_mask_); | 232 picture->set_is_mask(is_mask_); |
| 200 picture->set_nearest_neighbor(picture_layer_inputs_.nearest_neighbor); | 233 picture->set_nearest_neighbor(picture_layer_inputs_.nearest_neighbor); |
| 201 | 234 |
| 202 picture->set_update_source_frame_number(update_source_frame_number_); | 235 picture->set_update_source_frame_number(update_source_frame_number_); |
| 203 | 236 |
| 204 last_updated_invalidation_.Clear(); | 237 last_updated_invalidation_.Clear(); |
| 205 } | 238 } |
| 206 | 239 |
| 207 void PictureLayer::FromLayerSpecificPropertiesProto( | 240 void PictureLayer::FromLayerSpecificPropertiesProto( |
| 208 const proto::LayerProperties& proto) { | 241 const proto::LayerProperties& proto) { |
| 209 Layer::FromLayerSpecificPropertiesProto(proto); | 242 Layer::FromLayerSpecificPropertiesProto(proto); |
| 210 const proto::PictureLayerProperties& picture = proto.picture(); | 243 const proto::PictureLayerProperties& picture = proto.picture(); |
| 211 // If this is a new layer, ensure it has a recording source. During layer | 244 // If this is a new layer, ensure it has a recording source. During layer |
| 212 // hierarchy deserialization, ::SetLayerTreeHost(...) is not called, but | 245 // hierarchy deserialization, ::SetLayerTreeHost(...) is not called, but |
| 213 // instead the member is set directly, so it needs to be set here explicitly. | 246 // instead the member is set directly, so it needs to be set here explicitly. |
| 214 if (!recording_source_) | 247 if (!recording_source_) |
| 215 recording_source_.reset(new RecordingSource); | 248 recording_source_.reset(new RecordingSource); |
| 216 | 249 |
| 217 std::vector<uint32_t> used_engine_picture_ids; | 250 std::vector<uint32_t> used_engine_picture_ids; |
| 251 |
| 252 picture_layer_inputs_.recorded_viewport = |
| 253 ProtoToRect(picture.recorded_viewport()); |
| 254 |
| 255 ClientPictureCache* client_picture_cache = |
| 256 layer_tree_host()->client_picture_cache(); |
| 257 DCHECK(client_picture_cache); |
| 258 // This might not exist if the |input_.display_list| of the serialized |
| 259 // RecordingSource was null, which can happen if |Clear()| is |
| 260 // called. |
| 261 if (picture.has_display_list()) { |
| 262 picture_layer_inputs_.display_list = DisplayItemList::CreateFromProto( |
| 263 picture.display_list(), client_picture_cache, &used_engine_picture_ids); |
| 264 } else { |
| 265 picture_layer_inputs_.display_list = nullptr; |
| 266 } |
| 267 |
| 218 recording_source_->FromProtobuf(picture.recording_source(), | 268 recording_source_->FromProtobuf(picture.recording_source(), |
| 219 layer_tree_host()->client_picture_cache(), | 269 picture_layer_inputs_.display_list); |
| 220 &used_engine_picture_ids); | |
| 221 | 270 |
| 222 // Inform picture cache about which SkPictures are now in use. | 271 // Inform picture cache about which SkPictures are now in use. |
| 223 for (uint32_t engine_picture_id : used_engine_picture_ids) | 272 for (uint32_t engine_picture_id : used_engine_picture_ids) |
| 224 layer_tree_host()->client_picture_cache()->MarkUsed(engine_picture_id); | 273 layer_tree_host()->client_picture_cache()->MarkUsed(engine_picture_id); |
| 225 | 274 |
| 226 Region new_invalidation = RegionFromProto(picture.invalidation()); | 275 Region new_invalidation = RegionFromProto(picture.invalidation()); |
| 227 last_updated_invalidation_.Swap(&new_invalidation); | 276 last_updated_invalidation_.Swap(&new_invalidation); |
| 228 is_mask_ = picture.is_mask(); | 277 is_mask_ = picture.is_mask(); |
| 229 picture_layer_inputs_.nearest_neighbor = picture.nearest_neighbor(); | 278 picture_layer_inputs_.nearest_neighbor = picture.nearest_neighbor(); |
| 230 | 279 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 249 layer_bounds == recording_source_bounds) | 298 layer_bounds == recording_source_bounds) |
| 250 << " bounds " << layer_bounds.ToString() << " recording source " | 299 << " bounds " << layer_bounds.ToString() << " recording source " |
| 251 << recording_source_bounds.ToString(); | 300 << recording_source_bounds.ToString(); |
| 252 | 301 |
| 253 if (update_source_frame_number_ != source_frame_number && | 302 if (update_source_frame_number_ != source_frame_number && |
| 254 recording_source_bounds != layer_bounds) { | 303 recording_source_bounds != layer_bounds) { |
| 255 // Update may not get called for the layer (if it's not in the viewport | 304 // Update may not get called for the layer (if it's not in the viewport |
| 256 // for example), even though it has resized making the recording source no | 305 // for example), even though it has resized making the recording source no |
| 257 // longer valid. In this case just destroy the recording source. | 306 // longer valid. In this case just destroy the recording source. |
| 258 recording_source_->SetEmptyBounds(); | 307 recording_source_->SetEmptyBounds(); |
| 308 picture_layer_inputs_.recorded_viewport = gfx::Rect(); |
| 309 picture_layer_inputs_.display_list = nullptr; |
| 310 picture_layer_inputs_.painter_reported_memory_usage = 0; |
| 259 } | 311 } |
| 260 } | 312 } |
| 261 | 313 |
| 314 const DisplayItemList* PictureLayer::GetDisplayItemList() { |
| 315 return picture_layer_inputs_.display_list.get(); |
| 316 } |
| 317 |
| 262 } // namespace cc | 318 } // namespace cc |
| OLD | NEW |