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