| 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <limits> | 6 #include <limits> |
| 7 #include <set> |
| 7 | 8 |
| 8 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 9 #include "cc/base/region.h" | 10 #include "cc/base/region.h" |
| 10 #include "cc/debug/debug_colors.h" | 11 #include "cc/debug/debug_colors.h" |
| 11 #include "cc/resources/picture_pile_impl.h" | 12 #include "cc/resources/picture_pile_impl.h" |
| 13 #include "cc/resources/raster_source_helper.h" |
| 12 #include "skia/ext/analysis_canvas.h" | 14 #include "skia/ext/analysis_canvas.h" |
| 13 #include "third_party/skia/include/core/SkCanvas.h" | 15 #include "third_party/skia/include/core/SkCanvas.h" |
| 14 #include "third_party/skia/include/core/SkPictureRecorder.h" | 16 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 15 #include "ui/gfx/geometry/rect_conversions.h" | 17 #include "ui/gfx/geometry/rect_conversions.h" |
| 16 | 18 |
| 17 namespace { | 19 namespace { |
| 18 | 20 |
| 19 #ifdef NDEBUG | 21 #ifdef NDEBUG |
| 20 const bool kDefaultClearCanvasSetting = false; | 22 const bool kDefaultClearCanvasSetting = false; |
| 21 #else | 23 #else |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 | 82 |
| 81 void PicturePileImpl::RasterForAnalysis(skia::AnalysisCanvas* canvas, | 83 void PicturePileImpl::RasterForAnalysis(skia::AnalysisCanvas* canvas, |
| 82 const gfx::Rect& canvas_rect, | 84 const gfx::Rect& canvas_rect, |
| 83 float contents_scale) const { | 85 float contents_scale) const { |
| 84 RasterCommon(canvas, canvas, canvas_rect, contents_scale, true); | 86 RasterCommon(canvas, canvas, canvas_rect, contents_scale, true); |
| 85 } | 87 } |
| 86 | 88 |
| 87 void PicturePileImpl::PlaybackToCanvas(SkCanvas* canvas, | 89 void PicturePileImpl::PlaybackToCanvas(SkCanvas* canvas, |
| 88 const gfx::Rect& canvas_rect, | 90 const gfx::Rect& canvas_rect, |
| 89 float contents_scale) const { | 91 float contents_scale) const { |
| 90 canvas->discard(); | 92 RasterSourceHelper::PrepareForPlaybackToCanvas( |
| 91 if (clear_canvas_with_debug_color_) { | 93 canvas, canvas_rect, gfx::Rect(tiling_.tiling_size()), contents_scale, |
| 92 // Any non-painted areas in the content bounds will be left in this color. | 94 background_color_, clear_canvas_with_debug_color_, requires_clear_); |
| 93 canvas->clear(DebugColors::NonPaintedFillColor()); | |
| 94 } | |
| 95 | |
| 96 // If this picture has opaque contents, it is guaranteeing that it will | |
| 97 // draw an opaque rect the size of the layer. If it is not, then we must | |
| 98 // clear this canvas ourselves. | |
| 99 if (requires_clear_) { | |
| 100 TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD); | |
| 101 // Clearing is about ~4x faster than drawing a rect even if the content | |
| 102 // isn't covering a majority of the canvas. | |
| 103 canvas->clear(SK_ColorTRANSPARENT); | |
| 104 } else { | |
| 105 // Even if completely covered, for rasterizations that touch the edge of the | |
| 106 // layer, we also need to raster the background color underneath the last | |
| 107 // texel (since the recording won't cover it) and outside the last texel | |
| 108 // (due to linear filtering when using this texture). | |
| 109 gfx::Rect content_tiling_rect = gfx::ToEnclosingRect( | |
| 110 gfx::ScaleRect(gfx::Rect(tiling_.tiling_size()), contents_scale)); | |
| 111 | |
| 112 // The final texel of content may only be partially covered by a | |
| 113 // rasterization; this rect represents the content rect that is fully | |
| 114 // covered by content. | |
| 115 gfx::Rect deflated_content_tiling_rect = content_tiling_rect; | |
| 116 deflated_content_tiling_rect.Inset(0, 0, 1, 1); | |
| 117 if (!deflated_content_tiling_rect.Contains(canvas_rect)) { | |
| 118 if (clear_canvas_with_debug_color_) { | |
| 119 // Any non-painted areas outside of the content bounds are left in | |
| 120 // this color. If this is seen then it means that cc neglected to | |
| 121 // rerasterize a tile that used to intersect with the content rect | |
| 122 // after the content bounds grew. | |
| 123 canvas->save(); | |
| 124 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); | |
| 125 canvas->clipRect(gfx::RectToSkRect(content_tiling_rect), | |
| 126 SkRegion::kDifference_Op); | |
| 127 canvas->drawColor(DebugColors::MissingResizeInvalidations(), | |
| 128 SkXfermode::kSrc_Mode); | |
| 129 canvas->restore(); | |
| 130 } | |
| 131 | |
| 132 // Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X | |
| 133 // faster than clearing, so special case this. | |
| 134 canvas->save(); | |
| 135 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); | |
| 136 gfx::Rect inflated_content_tiling_rect = content_tiling_rect; | |
| 137 inflated_content_tiling_rect.Inset(0, 0, -1, -1); | |
| 138 canvas->clipRect(gfx::RectToSkRect(inflated_content_tiling_rect), | |
| 139 SkRegion::kReplace_Op); | |
| 140 canvas->clipRect(gfx::RectToSkRect(deflated_content_tiling_rect), | |
| 141 SkRegion::kDifference_Op); | |
| 142 canvas->drawColor(background_color_, SkXfermode::kSrc_Mode); | |
| 143 canvas->restore(); | |
| 144 } | |
| 145 } | |
| 146 | 95 |
| 147 RasterCommon(canvas, | 96 RasterCommon(canvas, |
| 148 NULL, | 97 NULL, |
| 149 canvas_rect, | 98 canvas_rect, |
| 150 contents_scale, | 99 contents_scale, |
| 151 false); | 100 false); |
| 152 } | 101 } |
| 153 | 102 |
| 154 void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect, | 103 void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect, |
| 155 const gfx::Rect& content_rect, | 104 const gfx::Rect& content_rect, |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 SkPictureRecorder recorder; | 261 SkPictureRecorder recorder; |
| 313 SkCanvas* canvas = | 262 SkCanvas* canvas = |
| 314 recorder.beginRecording(tiling_rect.width(), tiling_rect.height()); | 263 recorder.beginRecording(tiling_rect.width(), tiling_rect.height()); |
| 315 if (!tiling_rect.IsEmpty()) | 264 if (!tiling_rect.IsEmpty()) |
| 316 PlaybackToCanvas(canvas, tiling_rect, 1.0); | 265 PlaybackToCanvas(canvas, tiling_rect, 1.0); |
| 317 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); | 266 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); |
| 318 | 267 |
| 319 return picture; | 268 return picture; |
| 320 } | 269 } |
| 321 | 270 |
| 271 size_t PicturePileImpl::GetPictureMemoryUsage() const { |
| 272 // Place all pictures in a set to de-dupe. |
| 273 size_t total_size = 0; |
| 274 std::set<const Picture*> pictures_seen; |
| 275 for (const auto& map_value : picture_map_) { |
| 276 const Picture* picture = map_value.second.GetPicture(); |
| 277 if (picture && pictures_seen.insert(picture).second) |
| 278 total_size += picture->ApproximateMemoryUsage(); |
| 279 } |
| 280 |
| 281 return total_size; |
| 282 } |
| 283 |
| 322 void PicturePileImpl::PerformSolidColorAnalysis( | 284 void PicturePileImpl::PerformSolidColorAnalysis( |
| 323 const gfx::Rect& content_rect, | 285 const gfx::Rect& content_rect, |
| 324 float contents_scale, | 286 float contents_scale, |
| 325 RasterSource::SolidColorAnalysis* analysis) const { | 287 RasterSource::SolidColorAnalysis* analysis) const { |
| 326 DCHECK(analysis); | 288 DCHECK(analysis); |
| 327 TRACE_EVENT0("cc", "PicturePileImpl::PerformSolidColorAnalysis"); | 289 TRACE_EVENT0("cc", "PicturePileImpl::PerformSolidColorAnalysis"); |
| 328 | 290 |
| 329 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( | 291 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( |
| 330 content_rect, 1.0f / contents_scale); | 292 content_rect, 1.0f / contents_scale); |
| 331 | 293 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 ++it) { | 462 ++it) { |
| 501 const Picture* picture = it->second.GetPicture(); | 463 const Picture* picture = it->second.GetPicture(); |
| 502 if (picture && (processed_pictures.count(picture) == 0)) { | 464 if (picture && (processed_pictures.count(picture) == 0)) { |
| 503 picture->EmitTraceSnapshot(); | 465 picture->EmitTraceSnapshot(); |
| 504 processed_pictures.insert(picture); | 466 processed_pictures.insert(picture); |
| 505 } | 467 } |
| 506 } | 468 } |
| 507 } | 469 } |
| 508 | 470 |
| 509 } // namespace cc | 471 } // namespace cc |
| OLD | NEW |