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
3 // found in the LICENSE file.
5 #include "cc/playback/display_list_raster_source.h"
7 #include "base/trace_event/trace_event.h"
8 #include "cc/base/region.h"
9 #include "cc/debug/debug_colors.h"
10 #include "cc/playback/display_item_list.h"
11 #include "cc/playback/raster_source_helper.h"
12 #include "skia/ext/analysis_canvas.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/core/SkPictureRecorder.h"
15 #include "ui/gfx/geometry/rect_conversions.h"
19 scoped_refptr
<DisplayListRasterSource
>
20 DisplayListRasterSource::CreateFromDisplayListRecordingSource(
21 const DisplayListRecordingSource
* other
,
22 bool can_use_lcd_text
) {
23 return make_scoped_refptr(
24 new DisplayListRasterSource(other
, can_use_lcd_text
));
27 DisplayListRasterSource::DisplayListRasterSource()
28 : background_color_(SK_ColorTRANSPARENT
),
29 requires_clear_(true),
30 can_use_lcd_text_(true),
31 is_solid_color_(false),
32 solid_color_(SK_ColorTRANSPARENT
),
33 clear_canvas_with_debug_color_(false),
34 slow_down_raster_scale_factor_for_debug_(0),
35 should_attempt_to_use_distance_field_text_(false) {
38 DisplayListRasterSource::DisplayListRasterSource(
39 const DisplayListRecordingSource
* other
,
40 bool can_use_lcd_text
)
41 : display_list_(other
->display_list_
),
42 background_color_(other
->background_color_
),
43 requires_clear_(other
->requires_clear_
),
44 can_use_lcd_text_(can_use_lcd_text
),
45 is_solid_color_(other
->is_solid_color_
),
46 solid_color_(other
->solid_color_
),
47 recorded_viewport_(other
->recorded_viewport_
),
49 clear_canvas_with_debug_color_(other
->clear_canvas_with_debug_color_
),
50 slow_down_raster_scale_factor_for_debug_(
51 other
->slow_down_raster_scale_factor_for_debug_
),
52 should_attempt_to_use_distance_field_text_(false) {
55 DisplayListRasterSource::DisplayListRasterSource(
56 const DisplayListRasterSource
* other
,
57 bool can_use_lcd_text
)
58 : display_list_(other
->display_list_
),
59 background_color_(other
->background_color_
),
60 requires_clear_(other
->requires_clear_
),
61 can_use_lcd_text_(can_use_lcd_text
),
62 is_solid_color_(other
->is_solid_color_
),
63 solid_color_(other
->solid_color_
),
64 recorded_viewport_(other
->recorded_viewport_
),
66 clear_canvas_with_debug_color_(other
->clear_canvas_with_debug_color_
),
67 slow_down_raster_scale_factor_for_debug_(
68 other
->slow_down_raster_scale_factor_for_debug_
),
69 should_attempt_to_use_distance_field_text_(
70 other
->should_attempt_to_use_distance_field_text_
) {
73 DisplayListRasterSource::~DisplayListRasterSource() {
76 void DisplayListRasterSource::PlaybackToSharedCanvas(
78 const gfx::Rect
& canvas_rect
,
79 float contents_scale
) const {
80 RasterCommon(canvas
, NULL
, canvas_rect
, canvas_rect
, contents_scale
);
83 void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas
* canvas
,
84 const gfx::Rect
& canvas_rect
,
85 float contents_scale
) const {
86 RasterCommon(canvas
, canvas
, canvas_rect
, canvas_rect
, contents_scale
);
89 void DisplayListRasterSource::PlaybackToCanvas(
91 const gfx::Rect
& canvas_bitmap_rect
,
92 const gfx::Rect
& canvas_playback_rect
,
93 float contents_scale
) const {
94 RasterSourceHelper::PrepareForPlaybackToCanvas(
95 canvas
, canvas_bitmap_rect
, canvas_playback_rect
, gfx::Rect(size_
),
96 contents_scale
, background_color_
, clear_canvas_with_debug_color_
,
99 RasterCommon(canvas
, NULL
, canvas_bitmap_rect
, canvas_playback_rect
,
103 void DisplayListRasterSource::RasterCommon(
105 SkPicture::AbortCallback
* callback
,
106 const gfx::Rect
& canvas_bitmap_rect
,
107 const gfx::Rect
& canvas_playback_rect
,
108 float contents_scale
) const {
109 canvas
->translate(-canvas_bitmap_rect
.x(), -canvas_bitmap_rect
.y());
110 gfx::Rect content_rect
=
111 gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(size_
), contents_scale
));
112 content_rect
.Intersect(canvas_playback_rect
);
114 canvas
->clipRect(gfx::RectToSkRect(content_rect
), SkRegion::kIntersect_Op
);
116 DCHECK(display_list_
.get());
117 gfx::Rect canvas_target_playback_rect
=
118 canvas_playback_rect
- canvas_bitmap_rect
.OffsetFromOrigin();
119 display_list_
->Raster(canvas
, callback
, canvas_target_playback_rect
,
123 skia::RefPtr
<SkPicture
> DisplayListRasterSource::GetFlattenedPicture() {
124 TRACE_EVENT0("cc", "DisplayListRasterSource::GetFlattenedPicture");
126 gfx::Rect
display_list_rect(size_
);
127 SkPictureRecorder recorder
;
128 SkCanvas
* canvas
= recorder
.beginRecording(display_list_rect
.width(),
129 display_list_rect
.height());
130 if (!display_list_rect
.IsEmpty())
131 PlaybackToCanvas(canvas
, display_list_rect
, display_list_rect
, 1.0);
132 skia::RefPtr
<SkPicture
> picture
=
133 skia::AdoptRef(recorder
.endRecordingAsPicture());
138 size_t DisplayListRasterSource::GetPictureMemoryUsage() const {
141 return display_list_
->PictureMemoryUsage();
144 void DisplayListRasterSource::PerformSolidColorAnalysis(
145 const gfx::Rect
& content_rect
,
146 float contents_scale
,
147 RasterSource::SolidColorAnalysis
* analysis
) const {
149 TRACE_EVENT0("cc", "DisplayListRasterSource::PerformSolidColorAnalysis");
151 gfx::Rect layer_rect
=
152 gfx::ScaleToEnclosingRect(content_rect
, 1.0f
/ contents_scale
);
154 layer_rect
.Intersect(gfx::Rect(size_
));
155 skia::AnalysisCanvas
canvas(layer_rect
.width(), layer_rect
.height());
156 RasterForAnalysis(&canvas
, layer_rect
, 1.0f
);
157 analysis
->is_solid_color
= canvas
.GetColorIfSolid(&analysis
->solid_color
);
160 void DisplayListRasterSource::GatherPixelRefs(
161 const gfx::Rect
& content_rect
,
162 float contents_scale
,
163 std::vector
<SkPixelRef
*>* pixel_refs
) const {
164 DCHECK_EQ(0u, pixel_refs
->size());
166 gfx::Rect layer_rect
=
167 gfx::ScaleToEnclosingRect(content_rect
, 1.0f
/ contents_scale
);
169 PixelRefMap::Iterator
iterator(layer_rect
, display_list_
.get());
171 pixel_refs
->push_back(*iterator
);
176 bool DisplayListRasterSource::CoversRect(const gfx::Rect
& content_rect
,
177 float contents_scale
) const {
180 gfx::Rect layer_rect
=
181 gfx::ScaleToEnclosingRect(content_rect
, 1.f
/ contents_scale
);
182 layer_rect
.Intersect(gfx::Rect(size_
));
184 return recorded_viewport_
.Contains(layer_rect
);
187 gfx::Size
DisplayListRasterSource::GetSize() const {
191 bool DisplayListRasterSource::IsSolidColor() const {
192 return is_solid_color_
;
195 SkColor
DisplayListRasterSource::GetSolidColor() const {
196 DCHECK(IsSolidColor());
200 bool DisplayListRasterSource::HasRecordings() const {
201 return !!display_list_
.get();
204 void DisplayListRasterSource::SetShouldAttemptToUseDistanceFieldText() {
205 should_attempt_to_use_distance_field_text_
= true;
208 bool DisplayListRasterSource::ShouldAttemptToUseDistanceFieldText() const {
209 return should_attempt_to_use_distance_field_text_
;
212 void DisplayListRasterSource::AsValueInto(
213 base::trace_event::TracedValue
* array
) const {
214 if (display_list_
.get())
215 TracedValue::AppendIDRef(display_list_
.get(), array
);
218 void DisplayListRasterSource::DidBeginTracing() {
219 if (display_list_
.get())
220 display_list_
->EmitTraceSnapshot();
223 bool DisplayListRasterSource::CanUseLCDText() const {
224 return can_use_lcd_text_
;
227 scoped_refptr
<RasterSource
> DisplayListRasterSource::CreateCloneWithoutLCDText()
229 bool can_use_lcd_text
= false;
230 return scoped_refptr
<RasterSource
>(
231 new DisplayListRasterSource(this, can_use_lcd_text
));