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/resources/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/resources/display_item_list.h"
11 #include "cc/resources/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"
20 const bool kDefaultClearCanvasSetting
= false;
22 const bool kDefaultClearCanvasSetting
= true;
29 scoped_refptr
<DisplayListRasterSource
>
30 DisplayListRasterSource::CreateFromDisplayListRecordingSource(
31 const DisplayListRecordingSource
* other
,
32 bool can_use_lcd_text
) {
33 return make_scoped_refptr(
34 new DisplayListRasterSource(other
, can_use_lcd_text
));
37 DisplayListRasterSource::DisplayListRasterSource()
38 : background_color_(SK_ColorTRANSPARENT
),
39 requires_clear_(true),
40 can_use_lcd_text_(true),
41 is_solid_color_(false),
42 solid_color_(SK_ColorTRANSPARENT
),
43 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting
),
44 slow_down_raster_scale_factor_for_debug_(0),
45 should_attempt_to_use_distance_field_text_(false) {
48 DisplayListRasterSource::DisplayListRasterSource(
49 const DisplayListRecordingSource
* other
,
50 bool can_use_lcd_text
)
51 : display_list_(other
->display_list_
),
52 background_color_(other
->background_color_
),
53 requires_clear_(other
->requires_clear_
),
54 can_use_lcd_text_(can_use_lcd_text
),
55 is_solid_color_(other
->is_solid_color_
),
56 solid_color_(other
->solid_color_
),
57 recorded_viewport_(other
->recorded_viewport_
),
59 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting
),
60 slow_down_raster_scale_factor_for_debug_(
61 other
->slow_down_raster_scale_factor_for_debug_
),
62 should_attempt_to_use_distance_field_text_(false) {
65 DisplayListRasterSource::DisplayListRasterSource(
66 const DisplayListRasterSource
* other
,
67 bool can_use_lcd_text
)
68 : display_list_(other
->display_list_
),
69 background_color_(other
->background_color_
),
70 requires_clear_(other
->requires_clear_
),
71 can_use_lcd_text_(can_use_lcd_text
),
72 is_solid_color_(other
->is_solid_color_
),
73 solid_color_(other
->solid_color_
),
74 recorded_viewport_(other
->recorded_viewport_
),
76 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting
),
77 slow_down_raster_scale_factor_for_debug_(
78 other
->slow_down_raster_scale_factor_for_debug_
),
79 should_attempt_to_use_distance_field_text_(
80 other
->should_attempt_to_use_distance_field_text_
) {
83 DisplayListRasterSource::~DisplayListRasterSource() {
86 void DisplayListRasterSource::PlaybackToSharedCanvas(
88 const gfx::Rect
& canvas_rect
,
89 float contents_scale
) const {
90 RasterCommon(canvas
, NULL
, canvas_rect
, contents_scale
);
93 void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas
* canvas
,
94 const gfx::Rect
& canvas_rect
,
95 float contents_scale
) const {
96 RasterCommon(canvas
, canvas
, canvas_rect
, contents_scale
);
99 void DisplayListRasterSource::PlaybackToCanvas(SkCanvas
* canvas
,
100 const gfx::Rect
& canvas_rect
,
101 float contents_scale
) const {
102 RasterSourceHelper::PrepareForPlaybackToCanvas(
103 canvas
, canvas_rect
, gfx::Rect(size_
), contents_scale
, background_color_
,
104 clear_canvas_with_debug_color_
, requires_clear_
);
106 RasterCommon(canvas
, NULL
, canvas_rect
, contents_scale
);
109 void DisplayListRasterSource::RasterCommon(SkCanvas
* canvas
,
110 SkDrawPictureCallback
* callback
,
111 const gfx::Rect
& canvas_rect
,
112 float contents_scale
) const {
113 canvas
->translate(-canvas_rect
.x(), -canvas_rect
.y());
114 gfx::Rect content_rect
=
115 gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(size_
), contents_scale
));
116 content_rect
.Intersect(canvas_rect
);
118 canvas
->clipRect(gfx::RectToSkRect(content_rect
), SkRegion::kIntersect_Op
);
120 DCHECK(display_list_
.get());
121 display_list_
->Raster(canvas
, callback
, contents_scale
);
124 skia::RefPtr
<SkPicture
> DisplayListRasterSource::GetFlattenedPicture() {
125 TRACE_EVENT0("cc", "DisplayListRasterSource::GetFlattenedPicture");
127 gfx::Rect
display_list_rect(size_
);
128 SkPictureRecorder recorder
;
129 SkCanvas
* canvas
= recorder
.beginRecording(display_list_rect
.width(),
130 display_list_rect
.height());
131 if (!display_list_rect
.IsEmpty())
132 PlaybackToCanvas(canvas
, display_list_rect
, 1.0);
133 skia::RefPtr
<SkPicture
> picture
=
134 skia::AdoptRef(recorder
.endRecordingAsPicture());
139 size_t DisplayListRasterSource::GetPictureMemoryUsage() const {
142 return display_list_
->PictureMemoryUsage();
145 void DisplayListRasterSource::PerformSolidColorAnalysis(
146 const gfx::Rect
& content_rect
,
147 float contents_scale
,
148 RasterSource::SolidColorAnalysis
* analysis
) const {
150 TRACE_EVENT0("cc", "DisplayListRasterSource::PerformSolidColorAnalysis");
152 gfx::Rect layer_rect
=
153 gfx::ScaleToEnclosingRect(content_rect
, 1.0f
/ contents_scale
);
155 layer_rect
.Intersect(gfx::Rect(size_
));
156 skia::AnalysisCanvas
canvas(layer_rect
.width(), layer_rect
.height());
157 RasterForAnalysis(&canvas
, layer_rect
, 1.0f
);
158 analysis
->is_solid_color
= canvas
.GetColorIfSolid(&analysis
->solid_color
);
161 void DisplayListRasterSource::GatherPixelRefs(
162 const gfx::Rect
& content_rect
,
163 float contents_scale
,
164 std::vector
<SkPixelRef
*>* pixel_refs
) const {
165 DCHECK_EQ(0u, pixel_refs
->size());
167 gfx::Rect layer_rect
=
168 gfx::ScaleToEnclosingRect(content_rect
, 1.0f
/ contents_scale
);
170 PixelRefMap::Iterator
iterator(layer_rect
, display_list_
.get());
172 pixel_refs
->push_back(*iterator
);
177 bool DisplayListRasterSource::CoversRect(const gfx::Rect
& content_rect
,
178 float contents_scale
) const {
181 gfx::Rect layer_rect
=
182 gfx::ScaleToEnclosingRect(content_rect
, 1.f
/ contents_scale
);
183 layer_rect
.Intersect(gfx::Rect(size_
));
185 return recorded_viewport_
.Contains(layer_rect
);
188 gfx::Size
DisplayListRasterSource::GetSize() const {
192 bool DisplayListRasterSource::IsSolidColor() const {
193 return is_solid_color_
;
196 SkColor
DisplayListRasterSource::GetSolidColor() const {
197 DCHECK(IsSolidColor());
201 bool DisplayListRasterSource::HasRecordings() const {
202 return !!display_list_
.get();
205 void DisplayListRasterSource::SetShouldAttemptToUseDistanceFieldText() {
206 should_attempt_to_use_distance_field_text_
= true;
209 bool DisplayListRasterSource::ShouldAttemptToUseDistanceFieldText() const {
210 return should_attempt_to_use_distance_field_text_
;
213 void DisplayListRasterSource::AsValueInto(
214 base::trace_event::TracedValue
* array
) const {
215 if (display_list_
.get())
216 TracedValue::AppendIDRef(display_list_
.get(), array
);
219 void DisplayListRasterSource::DidBeginTracing() {
220 if (display_list_
.get())
221 display_list_
->EmitTraceSnapshot();
224 bool DisplayListRasterSource::CanUseLCDText() const {
225 return can_use_lcd_text_
;
228 scoped_refptr
<RasterSource
> DisplayListRasterSource::CreateCloneWithoutLCDText()
230 bool can_use_lcd_text
= false;
231 return scoped_refptr
<RasterSource
>(
232 new DisplayListRasterSource(this, can_use_lcd_text
));