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