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_list_raster_source.h" | 5 #include "cc/playback/display_list_raster_source.h" |
6 | 6 |
7 #include "base/trace_event/trace_event.h" | 7 #include "base/trace_event/trace_event.h" |
8 #include "cc/base/region.h" | 8 #include "cc/base/region.h" |
9 #include "cc/debug/debug_colors.h" | 9 #include "cc/debug/debug_colors.h" |
10 #include "cc/playback/display_item_list.h" | 10 #include "cc/playback/display_item_list.h" |
11 #include "cc/playback/raster_source_helper.h" | |
12 #include "skia/ext/analysis_canvas.h" | 11 #include "skia/ext/analysis_canvas.h" |
13 #include "third_party/skia/include/core/SkCanvas.h" | 12 #include "third_party/skia/include/core/SkCanvas.h" |
14 #include "third_party/skia/include/core/SkPictureRecorder.h" | 13 #include "third_party/skia/include/core/SkPictureRecorder.h" |
15 #include "ui/gfx/geometry/rect_conversions.h" | 14 #include "ui/gfx/geometry/rect_conversions.h" |
16 | 15 |
17 namespace cc { | 16 namespace cc { |
18 | 17 |
19 scoped_refptr<DisplayListRasterSource> | 18 scoped_refptr<DisplayListRasterSource> |
20 DisplayListRasterSource::CreateFromDisplayListRecordingSource( | 19 DisplayListRasterSource::CreateFromDisplayListRecordingSource( |
21 const DisplayListRecordingSource* other, | 20 const DisplayListRecordingSource* other, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 const gfx::Rect& canvas_rect, | 72 const gfx::Rect& canvas_rect, |
74 float contents_scale) const { | 73 float contents_scale) const { |
75 RasterCommon(canvas, canvas, canvas_rect, canvas_rect, contents_scale); | 74 RasterCommon(canvas, canvas, canvas_rect, canvas_rect, contents_scale); |
76 } | 75 } |
77 | 76 |
78 void DisplayListRasterSource::PlaybackToCanvas( | 77 void DisplayListRasterSource::PlaybackToCanvas( |
79 SkCanvas* canvas, | 78 SkCanvas* canvas, |
80 const gfx::Rect& canvas_bitmap_rect, | 79 const gfx::Rect& canvas_bitmap_rect, |
81 const gfx::Rect& canvas_playback_rect, | 80 const gfx::Rect& canvas_playback_rect, |
82 float contents_scale) const { | 81 float contents_scale) const { |
83 RasterSourceHelper::PrepareForPlaybackToCanvas( | 82 PrepareForPlaybackToCanvas(canvas, canvas_bitmap_rect, canvas_playback_rect, |
84 canvas, canvas_bitmap_rect, canvas_playback_rect, gfx::Rect(size_), | 83 contents_scale); |
85 contents_scale, background_color_, clear_canvas_with_debug_color_, | |
86 requires_clear_); | |
87 | |
88 RasterCommon(canvas, NULL, canvas_bitmap_rect, canvas_playback_rect, | 84 RasterCommon(canvas, NULL, canvas_bitmap_rect, canvas_playback_rect, |
89 contents_scale); | 85 contents_scale); |
90 } | 86 } |
91 | 87 |
| 88 void DisplayListRasterSource::PrepareForPlaybackToCanvas( |
| 89 SkCanvas* canvas, |
| 90 const gfx::Rect& canvas_bitmap_rect, |
| 91 const gfx::Rect& canvas_playback_rect, |
| 92 float contents_scale) const { |
| 93 // TODO(hendrikw): See if we can split this up into separate functions. |
| 94 bool partial_update = canvas_bitmap_rect != canvas_playback_rect; |
| 95 |
| 96 if (!partial_update) |
| 97 canvas->discard(); |
| 98 if (clear_canvas_with_debug_color_) { |
| 99 // Any non-painted areas in the content bounds will be left in this color. |
| 100 if (!partial_update) { |
| 101 canvas->clear(DebugColors::NonPaintedFillColor()); |
| 102 } else { |
| 103 canvas->save(); |
| 104 canvas->clipRect(gfx::RectToSkRect( |
| 105 canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin())); |
| 106 canvas->drawColor(DebugColors::NonPaintedFillColor()); |
| 107 canvas->restore(); |
| 108 } |
| 109 } |
| 110 |
| 111 // If this raster source has opaque contents, it is guaranteeing that it will |
| 112 // draw an opaque rect the size of the layer. If it is not, then we must |
| 113 // clear this canvas ourselves. |
| 114 if (requires_clear_) { |
| 115 TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD); |
| 116 // Clearing is about ~4x faster than drawing a rect even if the content |
| 117 // isn't covering a majority of the canvas. |
| 118 if (!partial_update) { |
| 119 canvas->clear(SK_ColorTRANSPARENT); |
| 120 } else { |
| 121 canvas->save(); |
| 122 canvas->clipRect(gfx::RectToSkRect( |
| 123 canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin())); |
| 124 canvas->drawColor(SK_ColorTRANSPARENT, SkXfermode::kClear_Mode); |
| 125 canvas->restore(); |
| 126 } |
| 127 } else { |
| 128 // Even if completely covered, for rasterizations that touch the edge of the |
| 129 // layer, we also need to raster the background color underneath the last |
| 130 // texel (since the recording won't cover it) and outside the last texel |
| 131 // (due to linear filtering when using this texture). |
| 132 gfx::Rect content_rect = |
| 133 gfx::ScaleToEnclosingRect(gfx::Rect(size_), contents_scale); |
| 134 |
| 135 // The final texel of content may only be partially covered by a |
| 136 // rasterization; this rect represents the content rect that is fully |
| 137 // covered by content. |
| 138 gfx::Rect deflated_content_rect = content_rect; |
| 139 deflated_content_rect.Inset(0, 0, 1, 1); |
| 140 deflated_content_rect.Intersect(canvas_playback_rect); |
| 141 if (!deflated_content_rect.Contains(canvas_playback_rect)) { |
| 142 if (clear_canvas_with_debug_color_) { |
| 143 // Any non-painted areas outside of the content bounds are left in |
| 144 // this color. If this is seen then it means that cc neglected to |
| 145 // rerasterize a tile that used to intersect with the content rect |
| 146 // after the content bounds grew. |
| 147 canvas->save(); |
| 148 canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); |
| 149 canvas->clipRect(gfx::RectToSkRect(content_rect), |
| 150 SkRegion::kDifference_Op); |
| 151 canvas->drawColor(DebugColors::MissingResizeInvalidations(), |
| 152 SkXfermode::kSrc_Mode); |
| 153 canvas->restore(); |
| 154 } |
| 155 |
| 156 // Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X |
| 157 // faster than clearing, so special case this. |
| 158 canvas->save(); |
| 159 canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); |
| 160 gfx::Rect inflated_content_rect = content_rect; |
| 161 // Only clear edges that will be inside the canvas_playback_rect, else we |
| 162 // clear things that are still valid from a previous raster. |
| 163 inflated_content_rect.Inset(0, 0, -1, -1); |
| 164 inflated_content_rect.Intersect(canvas_playback_rect); |
| 165 canvas->clipRect(gfx::RectToSkRect(inflated_content_rect), |
| 166 SkRegion::kReplace_Op); |
| 167 canvas->clipRect(gfx::RectToSkRect(deflated_content_rect), |
| 168 SkRegion::kDifference_Op); |
| 169 canvas->drawColor(background_color_, SkXfermode::kSrc_Mode); |
| 170 canvas->restore(); |
| 171 } |
| 172 } |
| 173 } |
| 174 |
92 void DisplayListRasterSource::RasterCommon( | 175 void DisplayListRasterSource::RasterCommon( |
93 SkCanvas* canvas, | 176 SkCanvas* canvas, |
94 SkPicture::AbortCallback* callback, | 177 SkPicture::AbortCallback* callback, |
95 const gfx::Rect& canvas_bitmap_rect, | 178 const gfx::Rect& canvas_bitmap_rect, |
96 const gfx::Rect& canvas_playback_rect, | 179 const gfx::Rect& canvas_playback_rect, |
97 float contents_scale) const { | 180 float contents_scale) const { |
98 canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); | 181 canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); |
99 gfx::Rect content_rect = | 182 gfx::Rect content_rect = |
100 gfx::ScaleToEnclosingRect(gfx::Rect(size_), contents_scale); | 183 gfx::ScaleToEnclosingRect(gfx::Rect(size_), contents_scale); |
101 content_rect.Intersect(canvas_playback_rect); | 184 content_rect.Intersect(canvas_playback_rect); |
(...skipping 28 matching lines...) Expand all Loading... |
130 size_t DisplayListRasterSource::GetPictureMemoryUsage() const { | 213 size_t DisplayListRasterSource::GetPictureMemoryUsage() const { |
131 if (!display_list_) | 214 if (!display_list_) |
132 return 0; | 215 return 0; |
133 return display_list_->ApproximateMemoryUsage() + | 216 return display_list_->ApproximateMemoryUsage() + |
134 painter_reported_memory_usage_; | 217 painter_reported_memory_usage_; |
135 } | 218 } |
136 | 219 |
137 void DisplayListRasterSource::PerformSolidColorAnalysis( | 220 void DisplayListRasterSource::PerformSolidColorAnalysis( |
138 const gfx::Rect& content_rect, | 221 const gfx::Rect& content_rect, |
139 float contents_scale, | 222 float contents_scale, |
140 RasterSource::SolidColorAnalysis* analysis) const { | 223 DisplayListRasterSource::SolidColorAnalysis* analysis) const { |
141 DCHECK(analysis); | 224 DCHECK(analysis); |
142 TRACE_EVENT0("cc", "DisplayListRasterSource::PerformSolidColorAnalysis"); | 225 TRACE_EVENT0("cc", "DisplayListRasterSource::PerformSolidColorAnalysis"); |
143 | 226 |
144 gfx::Rect layer_rect = | 227 gfx::Rect layer_rect = |
145 gfx::ScaleToEnclosingRect(content_rect, 1.0f / contents_scale); | 228 gfx::ScaleToEnclosingRect(content_rect, 1.0f / contents_scale); |
146 | 229 |
147 layer_rect.Intersect(gfx::Rect(size_)); | 230 layer_rect.Intersect(gfx::Rect(size_)); |
148 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); | 231 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); |
149 RasterForAnalysis(&canvas, layer_rect, 1.0f); | 232 RasterForAnalysis(&canvas, layer_rect, 1.0f); |
150 analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color); | 233 analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 | 285 |
203 void DisplayListRasterSource::DidBeginTracing() { | 286 void DisplayListRasterSource::DidBeginTracing() { |
204 if (display_list_.get()) | 287 if (display_list_.get()) |
205 display_list_->EmitTraceSnapshot(); | 288 display_list_->EmitTraceSnapshot(); |
206 } | 289 } |
207 | 290 |
208 bool DisplayListRasterSource::CanUseLCDText() const { | 291 bool DisplayListRasterSource::CanUseLCDText() const { |
209 return can_use_lcd_text_; | 292 return can_use_lcd_text_; |
210 } | 293 } |
211 | 294 |
212 scoped_refptr<RasterSource> DisplayListRasterSource::CreateCloneWithoutLCDText() | 295 scoped_refptr<DisplayListRasterSource> |
213 const { | 296 DisplayListRasterSource::CreateCloneWithoutLCDText() const { |
214 bool can_use_lcd_text = false; | 297 bool can_use_lcd_text = false; |
215 return scoped_refptr<RasterSource>( | 298 return scoped_refptr<DisplayListRasterSource>( |
216 new DisplayListRasterSource(this, can_use_lcd_text)); | 299 new DisplayListRasterSource(this, can_use_lcd_text)); |
217 } | 300 } |
218 | 301 |
219 } // namespace cc | 302 } // namespace cc |
OLD | NEW |