| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/playback/display_item_list.h" | 5 #include "cc/playback/display_item_list.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/numerics/safe_conversions.h" | 11 #include "base/numerics/safe_conversions.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
| 14 #include "base/trace_event/trace_event_argument.h" | 14 #include "base/trace_event/trace_event_argument.h" |
| 15 #include "cc/base/math_util.h" | 15 #include "cc/base/math_util.h" |
| 16 #include "cc/debug/picture_debug_util.h" | 16 #include "cc/debug/picture_debug_util.h" |
| 17 #include "cc/debug/traced_display_item_list.h" | |
| 18 #include "cc/debug/traced_value.h" | |
| 19 #include "cc/playback/clip_display_item.h" | 17 #include "cc/playback/clip_display_item.h" |
| 20 #include "cc/playback/clip_path_display_item.h" | 18 #include "cc/playback/clip_path_display_item.h" |
| 21 #include "cc/playback/compositing_display_item.h" | 19 #include "cc/playback/compositing_display_item.h" |
| 22 #include "cc/playback/drawing_display_item.h" | 20 #include "cc/playback/drawing_display_item.h" |
| 23 #include "cc/playback/filter_display_item.h" | 21 #include "cc/playback/filter_display_item.h" |
| 24 #include "cc/playback/float_clip_display_item.h" | 22 #include "cc/playback/float_clip_display_item.h" |
| 25 #include "cc/playback/largest_display_item.h" | 23 #include "cc/playback/largest_display_item.h" |
| 26 #include "cc/playback/transform_display_item.h" | 24 #include "cc/playback/transform_display_item.h" |
| 27 #include "third_party/skia/include/core/SkCanvas.h" | 25 #include "third_party/skia/include/core/SkCanvas.h" |
| 28 #include "third_party/skia/include/core/SkPictureRecorder.h" | 26 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 29 #include "ui/gfx/geometry/rect.h" | 27 #include "ui/gfx/geometry/rect.h" |
| 30 #include "ui/gfx/geometry/rect_conversions.h" | 28 #include "ui/gfx/geometry/rect_conversions.h" |
| 31 #include "ui/gfx/skia_util.h" | 29 #include "ui/gfx/skia_util.h" |
| 32 | 30 |
| 33 namespace cc { | 31 namespace cc { |
| 34 | 32 |
| 35 namespace { | 33 namespace { |
| 36 | 34 |
| 37 // We don't perform per-layer solid color analysis when there are too many skia | 35 // We don't perform per-layer solid color analysis when there are too many skia |
| 38 // operations. | 36 // operations. |
| 39 const int kOpCountThatIsOkToAnalyze = 10; | 37 const int kOpCountThatIsOkToAnalyze = 10; |
| 40 | 38 |
| 41 bool DisplayItemsTracingEnabled() { | |
| 42 bool tracing_enabled; | |
| 43 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | |
| 44 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &tracing_enabled); | |
| 45 return tracing_enabled; | |
| 46 } | |
| 47 | |
| 48 bool GetCanvasClipBounds(SkCanvas* canvas, gfx::Rect* clip_bounds) { | 39 bool GetCanvasClipBounds(SkCanvas* canvas, gfx::Rect* clip_bounds) { |
| 49 SkRect canvas_clip_bounds; | 40 SkRect canvas_clip_bounds; |
| 50 if (!canvas->getLocalClipBounds(&canvas_clip_bounds)) | 41 if (!canvas->getLocalClipBounds(&canvas_clip_bounds)) |
| 51 return false; | 42 return false; |
| 52 *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds)); | 43 *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds)); |
| 53 return true; | 44 return true; |
| 54 } | 45 } |
| 55 | 46 |
| 56 const int kDefaultNumDisplayItemsToReserve = 100; | 47 const int kDefaultNumDisplayItemsToReserve = 100; |
| 57 | 48 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 // contribute to memory usage? | 178 // contribute to memory usage? |
| 188 // TODO(vmpstr): Probably DiscardableImageMap is worth counting here. | 179 // TODO(vmpstr): Probably DiscardableImageMap is worth counting here. |
| 189 | 180 |
| 190 return memory_usage; | 181 return memory_usage; |
| 191 } | 182 } |
| 192 | 183 |
| 193 bool DisplayItemList::ShouldBeAnalyzedForSolidColor() const { | 184 bool DisplayItemList::ShouldBeAnalyzedForSolidColor() const { |
| 194 return ApproximateOpCount() <= kOpCountThatIsOkToAnalyze; | 185 return ApproximateOpCount() <= kOpCountThatIsOkToAnalyze; |
| 195 } | 186 } |
| 196 | 187 |
| 197 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> | |
| 198 DisplayItemList::AsValue(bool include_items) const { | |
| 199 std::unique_ptr<base::trace_event::TracedValue> state( | |
| 200 new base::trace_event::TracedValue()); | |
| 201 | |
| 202 state->BeginDictionary("params"); | |
| 203 if (include_items) { | |
| 204 state->BeginArray("items"); | |
| 205 size_t item_index = 0; | |
| 206 for (const DisplayItem& item : inputs_.items) { | |
| 207 item.AsValueInto(item_index < inputs_.visual_rects.size() | |
| 208 ? inputs_.visual_rects[item_index] | |
| 209 : gfx::Rect(), | |
| 210 state.get()); | |
| 211 item_index++; | |
| 212 } | |
| 213 state->EndArray(); // "items". | |
| 214 } | |
| 215 MathUtil::AddToTracedValue("layer_rect", rtree_.GetBounds(), state.get()); | |
| 216 state->EndDictionary(); // "params". | |
| 217 | |
| 218 SkPictureRecorder recorder; | |
| 219 gfx::Rect bounds = rtree_.GetBounds(); | |
| 220 SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height()); | |
| 221 canvas->translate(-bounds.x(), -bounds.y()); | |
| 222 canvas->clipRect(gfx::RectToSkRect(bounds)); | |
| 223 Raster(canvas, nullptr, gfx::Rect(), 1.f); | |
| 224 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); | |
| 225 | |
| 226 std::string b64_picture; | |
| 227 PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); | |
| 228 state->SetString("skp64", b64_picture); | |
| 229 | |
| 230 return std::move(state); | |
| 231 } | |
| 232 | |
| 233 void DisplayItemList::EmitTraceSnapshot() const { | 188 void DisplayItemList::EmitTraceSnapshot() const { |
| 189 bool include_items; |
| 190 TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
| 191 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &include_items); |
| 234 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 192 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
| 235 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") "," | 193 TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") "," |
| 236 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," | 194 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," |
| 237 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), | 195 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), |
| 238 "cc::DisplayItemList", this, | 196 "cc::DisplayItemList", this, CreateTracedValue(include_items)); |
| 239 TracedDisplayItemList::AsTraceableDisplayItemList(this, | 197 } |
| 240 DisplayItemsTracingEnabled())); | 198 |
| 199 std::unique_ptr<base::trace_event::TracedValue> |
| 200 DisplayItemList::CreateTracedValue(bool include_items) const { |
| 201 auto state = base::MakeUnique<base::trace_event::TracedValue>(); |
| 202 state->BeginDictionary("params"); |
| 203 |
| 204 if (include_items) { |
| 205 state->BeginArray("items"); |
| 206 |
| 207 auto visual_rects_it = inputs_.visual_rects.begin(); |
| 208 for (const DisplayItem& base_item : inputs_.items) { |
| 209 gfx::Rect visual_rect; |
| 210 if (visual_rects_it != inputs_.visual_rects.end()) { |
| 211 visual_rect = *visual_rects_it; |
| 212 ++visual_rects_it; |
| 213 } |
| 214 |
| 215 switch (base_item.type()) { |
| 216 case DisplayItem::CLIP: { |
| 217 const auto& item = static_cast<const ClipDisplayItem&>(base_item); |
| 218 std::string output = |
| 219 base::StringPrintf("ClipDisplayItem rect: [%s] visualRect: [%s]", |
| 220 item.clip_rect().ToString().c_str(), |
| 221 visual_rect.ToString().c_str()); |
| 222 for (const SkRRect& rounded_rect : item.rounded_clip_rects()) { |
| 223 base::StringAppendF( |
| 224 &output, " rounded_rect: [rect: [%s]", |
| 225 gfx::SkRectToRectF(rounded_rect.rect()).ToString().c_str()); |
| 226 base::StringAppendF(&output, " radii: ["); |
| 227 SkVector upper_left_radius = |
| 228 rounded_rect.radii(SkRRect::kUpperLeft_Corner); |
| 229 base::StringAppendF(&output, "[%f,%f],", upper_left_radius.x(), |
| 230 upper_left_radius.y()); |
| 231 SkVector upper_right_radius = |
| 232 rounded_rect.radii(SkRRect::kUpperRight_Corner); |
| 233 base::StringAppendF(&output, " [%f,%f],", upper_right_radius.x(), |
| 234 upper_right_radius.y()); |
| 235 SkVector lower_right_radius = |
| 236 rounded_rect.radii(SkRRect::kLowerRight_Corner); |
| 237 base::StringAppendF(&output, " [%f,%f],", lower_right_radius.x(), |
| 238 lower_right_radius.y()); |
| 239 SkVector lower_left_radius = |
| 240 rounded_rect.radii(SkRRect::kLowerLeft_Corner); |
| 241 base::StringAppendF(&output, " [%f,%f]]", lower_left_radius.x(), |
| 242 lower_left_radius.y()); |
| 243 } |
| 244 state->AppendString(output); |
| 245 break; |
| 246 } |
| 247 case DisplayItem::END_CLIP: |
| 248 state->AppendString( |
| 249 base::StringPrintf("EndClipDisplayItem visualRect: [%s]", |
| 250 visual_rect.ToString().c_str())); |
| 251 break; |
| 252 case DisplayItem::CLIP_PATH: { |
| 253 const auto& item = static_cast<const ClipPathDisplayItem&>(base_item); |
| 254 state->AppendString(base::StringPrintf( |
| 255 "ClipPathDisplayItem length: %d visualRect: [%s]", |
| 256 item.clip_path().countPoints(), visual_rect.ToString().c_str())); |
| 257 break; |
| 258 } |
| 259 case DisplayItem::END_CLIP_PATH: |
| 260 state->AppendString( |
| 261 base::StringPrintf("EndClipPathDisplayItem visualRect: [%s]", |
| 262 visual_rect.ToString().c_str())); |
| 263 break; |
| 264 case DisplayItem::COMPOSITING: { |
| 265 const auto& item = |
| 266 static_cast<const CompositingDisplayItem&>(base_item); |
| 267 std::string output = base::StringPrintf( |
| 268 "CompositingDisplayItem alpha: %d, xfermode: %d, visualRect: " |
| 269 "[%s]", |
| 270 item.alpha(), static_cast<int>(item.xfermode()), |
| 271 visual_rect.ToString().c_str()); |
| 272 if (item.has_bounds()) { |
| 273 base::StringAppendF( |
| 274 &output, ", bounds: [%s]", |
| 275 gfx::SkRectToRectF(item.bounds()).ToString().c_str()); |
| 276 } |
| 277 state->AppendString(output); |
| 278 break; |
| 279 } |
| 280 case DisplayItem::END_COMPOSITING: |
| 281 state->AppendString( |
| 282 base::StringPrintf("EndCompositingDisplayItem visualRect: [%s]", |
| 283 visual_rect.ToString().c_str())); |
| 284 break; |
| 285 case DisplayItem::DRAWING: { |
| 286 const auto& item = static_cast<const DrawingDisplayItem&>(base_item); |
| 287 state->BeginDictionary(); |
| 288 state->SetString("name", "DrawingDisplayItem"); |
| 289 |
| 290 state->BeginArray("visualRect"); |
| 291 state->AppendInteger(visual_rect.x()); |
| 292 state->AppendInteger(visual_rect.y()); |
| 293 state->AppendInteger(visual_rect.width()); |
| 294 state->AppendInteger(visual_rect.height()); |
| 295 state->EndArray(); |
| 296 |
| 297 state->BeginArray("cullRect"); |
| 298 state->AppendInteger(item.picture().cullRect().x()); |
| 299 state->AppendInteger(item.picture().cullRect().y()); |
| 300 state->AppendInteger(item.picture().cullRect().width()); |
| 301 state->AppendInteger(item.picture().cullRect().height()); |
| 302 state->EndArray(); |
| 303 |
| 304 std::string b64_picture; |
| 305 PictureDebugUtil::SerializeAsBase64(ToSkPicture(&item.picture()), |
| 306 &b64_picture); |
| 307 state->SetString("skp64", b64_picture); |
| 308 state->EndDictionary(); |
| 309 break; |
| 310 } |
| 311 case DisplayItem::FILTER: { |
| 312 const auto& item = static_cast<const FilterDisplayItem&>(base_item); |
| 313 state->AppendString(base::StringPrintf( |
| 314 "FilterDisplayItem bounds: [%s] visualRect: [%s]", |
| 315 item.bounds().ToString().c_str(), |
| 316 visual_rect.ToString().c_str())); |
| 317 break; |
| 318 } |
| 319 case DisplayItem::END_FILTER: |
| 320 state->AppendString( |
| 321 base::StringPrintf("EndFilterDisplayItem visualRect: [%s]", |
| 322 visual_rect.ToString().c_str())); |
| 323 break; |
| 324 case DisplayItem::FLOAT_CLIP: { |
| 325 const auto& item = |
| 326 static_cast<const FloatClipDisplayItem&>(base_item); |
| 327 state->AppendString(base::StringPrintf( |
| 328 "FloatClipDisplayItem rect: [%s] visualRect: [%s]", |
| 329 item.clip_rect().ToString().c_str(), |
| 330 visual_rect.ToString().c_str())); |
| 331 break; |
| 332 } |
| 333 case DisplayItem::END_FLOAT_CLIP: |
| 334 state->AppendString( |
| 335 base::StringPrintf("EndFloatClipDisplayItem visualRect: [%s]", |
| 336 visual_rect.ToString().c_str())); |
| 337 break; |
| 338 case DisplayItem::TRANSFORM: { |
| 339 const auto& item = |
| 340 static_cast<const TransformDisplayItem&>(base_item); |
| 341 state->AppendString(base::StringPrintf( |
| 342 "TransformDisplayItem transform: [%s] visualRect: [%s]", |
| 343 item.transform().ToString().c_str(), |
| 344 visual_rect.ToString().c_str())); |
| 345 break; |
| 346 } |
| 347 case DisplayItem::END_TRANSFORM: |
| 348 state->AppendString( |
| 349 base::StringPrintf("EndTransformDisplayItem visualRect: [%s]", |
| 350 visual_rect.ToString().c_str())); |
| 351 break; |
| 352 } |
| 353 } |
| 354 state->EndArray(); // "items". |
| 355 } |
| 356 |
| 357 MathUtil::AddToTracedValue("layer_rect", rtree_.GetBounds(), state.get()); |
| 358 state->EndDictionary(); // "params". |
| 359 |
| 360 { |
| 361 SkPictureRecorder recorder; |
| 362 gfx::Rect bounds = rtree_.GetBounds(); |
| 363 SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height()); |
| 364 canvas->translate(-bounds.x(), -bounds.y()); |
| 365 canvas->clipRect(gfx::RectToSkRect(bounds)); |
| 366 Raster(canvas, nullptr, gfx::Rect(), 1.f); |
| 367 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); |
| 368 |
| 369 std::string b64_picture; |
| 370 PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); |
| 371 state->SetString("skp64", b64_picture); |
| 372 } |
| 373 |
| 374 return state; |
| 241 } | 375 } |
| 242 | 376 |
| 243 void DisplayItemList::GenerateDiscardableImagesMetadata() { | 377 void DisplayItemList::GenerateDiscardableImagesMetadata() { |
| 244 // This should be only called once. | 378 // This should be only called once. |
| 245 DCHECK(image_map_.empty()); | 379 DCHECK(image_map_.empty()); |
| 246 | 380 |
| 247 gfx::Rect bounds = rtree_.GetBounds(); | 381 gfx::Rect bounds = rtree_.GetBounds(); |
| 248 DiscardableImageMap::ScopedMetadataGenerator generator( | 382 DiscardableImageMap::ScopedMetadataGenerator generator( |
| 249 &image_map_, gfx::Size(bounds.right(), bounds.bottom())); | 383 &image_map_, gfx::Size(bounds.right(), bounds.bottom())); |
| 250 auto* canvas = generator.canvas(); | 384 auto* canvas = generator.canvas(); |
| 251 for (const auto& item : inputs_.items) | 385 for (const auto& item : inputs_.items) |
| 252 item.Raster(canvas, nullptr); | 386 item.Raster(canvas, nullptr); |
| 253 } | 387 } |
| 254 | 388 |
| 255 void DisplayItemList::GetDiscardableImagesInRect( | 389 void DisplayItemList::GetDiscardableImagesInRect( |
| 256 const gfx::Rect& rect, | 390 const gfx::Rect& rect, |
| 257 float contents_scale, | 391 float contents_scale, |
| 258 std::vector<DrawImage>* images) { | 392 std::vector<DrawImage>* images) { |
| 259 image_map_.GetDiscardableImagesInRect(rect, contents_scale, images); | 393 image_map_.GetDiscardableImagesInRect(rect, contents_scale, images); |
| 260 } | 394 } |
| 261 | 395 |
| 262 gfx::Rect DisplayItemList::GetRectForImage(ImageId image_id) const { | 396 gfx::Rect DisplayItemList::GetRectForImage(ImageId image_id) const { |
| 263 return image_map_.GetRectForImage(image_id); | 397 return image_map_.GetRectForImage(image_id); |
| 264 } | 398 } |
| 265 | 399 |
| 266 } // namespace cc | 400 } // namespace cc |
| OLD | NEW |