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
> DisplayListRasterSource::Create() {
30 return make_scoped_refptr(new DisplayListRasterSource
);
33 scoped_refptr
<DisplayListRasterSource
>
34 DisplayListRasterSource::CreateFromDisplayListRecordingSource(
35 const DisplayListRecordingSource
* other
) {
36 return make_scoped_refptr(new DisplayListRasterSource(other
));
39 DisplayListRasterSource::DisplayListRasterSource()
40 : background_color_(SK_ColorTRANSPARENT
),
41 requires_clear_(true),
42 can_use_lcd_text_(true),
43 is_solid_color_(false),
44 solid_color_(SK_ColorTRANSPARENT
),
45 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting
),
46 slow_down_raster_scale_factor_for_debug_(0),
47 should_attempt_to_use_distance_field_text_(false) {
50 DisplayListRasterSource::DisplayListRasterSource(
51 const DisplayListRecordingSource
* other
)
52 : display_list_(other
->display_list_
),
53 background_color_(SK_ColorTRANSPARENT
),
54 requires_clear_(true),
55 can_use_lcd_text_(other
->can_use_lcd_text_
),
56 is_solid_color_(other
->is_solid_color_
),
57 solid_color_(other
->solid_color_
),
58 recorded_viewport_(other
->recorded_viewport_
),
60 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting
),
61 slow_down_raster_scale_factor_for_debug_(
62 other
->slow_down_raster_scale_factor_for_debug_
),
63 should_attempt_to_use_distance_field_text_(false) {
66 DisplayListRasterSource::~DisplayListRasterSource() {
69 void DisplayListRasterSource::PlaybackToSharedCanvas(
71 const gfx::Rect
& canvas_rect
,
72 float contents_scale
) const {
73 RasterCommon(canvas
, NULL
, canvas_rect
, contents_scale
, false);
76 void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas
* canvas
,
77 const gfx::Rect
& canvas_rect
,
78 float contents_scale
) const {
79 RasterCommon(canvas
, canvas
, canvas_rect
, contents_scale
, true);
82 void DisplayListRasterSource::PlaybackToCanvas(SkCanvas
* canvas
,
83 const gfx::Rect
& canvas_rect
,
84 float contents_scale
) const {
85 RasterSourceHelper::PrepareForPlaybackToCanvas(
86 canvas
, canvas_rect
, gfx::Rect(size_
), contents_scale
, background_color_
,
87 clear_canvas_with_debug_color_
, requires_clear_
);
89 RasterCommon(canvas
, NULL
, canvas_rect
, contents_scale
, false);
92 void DisplayListRasterSource::RasterCommon(SkCanvas
* canvas
,
93 SkDrawPictureCallback
* callback
,
94 const gfx::Rect
& canvas_rect
,
96 bool is_analysis
) const {
97 canvas
->translate(-canvas_rect
.x(), -canvas_rect
.y());
98 gfx::Rect content_rect
=
99 gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(size_
), contents_scale
));
100 content_rect
.Intersect(canvas_rect
);
102 canvas
->clipRect(gfx::RectToSkRect(content_rect
), SkRegion::kIntersect_Op
);
104 DCHECK(display_list_
.get());
105 display_list_
->Raster(canvas
, callback
, contents_scale
);
108 skia::RefPtr
<SkPicture
> DisplayListRasterSource::GetFlattenedPicture() {
109 TRACE_EVENT0("cc", "DisplayListRasterSource::GetFlattenedPicture");
111 gfx::Rect
display_list_rect(size_
);
112 SkPictureRecorder recorder
;
113 SkCanvas
* canvas
= recorder
.beginRecording(display_list_rect
.width(),
114 display_list_rect
.height());
115 if (!display_list_rect
.IsEmpty())
116 PlaybackToCanvas(canvas
, display_list_rect
, 1.0);
117 skia::RefPtr
<SkPicture
> picture
= skia::AdoptRef(recorder
.endRecording());
122 size_t DisplayListRasterSource::GetPictureMemoryUsage() const {
123 return display_list_
->PictureMemoryUsage();
126 void DisplayListRasterSource::PerformSolidColorAnalysis(
127 const gfx::Rect
& content_rect
,
128 float contents_scale
,
129 RasterSource::SolidColorAnalysis
* analysis
) const {
131 TRACE_EVENT0("cc", "DisplayListRasterSource::PerformSolidColorAnalysis");
133 gfx::Rect layer_rect
=
134 gfx::ScaleToEnclosingRect(content_rect
, 1.0f
/ contents_scale
);
136 layer_rect
.Intersect(gfx::Rect(size_
));
137 skia::AnalysisCanvas
canvas(layer_rect
.width(), layer_rect
.height());
138 RasterForAnalysis(&canvas
, layer_rect
, 1.0f
);
139 analysis
->is_solid_color
= canvas
.GetColorIfSolid(&analysis
->solid_color
);
142 void DisplayListRasterSource::GatherPixelRefs(
143 const gfx::Rect
& content_rect
,
144 float contents_scale
,
145 std::vector
<SkPixelRef
*>* pixel_refs
) const {
146 // TODO(ajuma): Implement this.
149 bool DisplayListRasterSource::CoversRect(const gfx::Rect
& content_rect
,
150 float contents_scale
) const {
153 gfx::Rect layer_rect
=
154 gfx::ScaleToEnclosingRect(content_rect
, 1.f
/ contents_scale
);
155 layer_rect
.Intersect(gfx::Rect(size_
));
157 return recorded_viewport_
.Contains(layer_rect
);
160 gfx::Size
DisplayListRasterSource::GetSize() const {
164 bool DisplayListRasterSource::IsSolidColor() const {
165 return is_solid_color_
;
168 SkColor
DisplayListRasterSource::GetSolidColor() const {
169 DCHECK(IsSolidColor());
173 bool DisplayListRasterSource::HasRecordings() const {
174 return !!display_list_
.get();
177 void DisplayListRasterSource::SetShouldAttemptToUseDistanceFieldText() {
178 should_attempt_to_use_distance_field_text_
= true;
181 void DisplayListRasterSource::SetBackgoundColor(SkColor background_color
) {
182 background_color_
= background_color
;
185 void DisplayListRasterSource::SetRequiresClear(bool requires_clear
) {
186 requires_clear_
= requires_clear
;
189 bool DisplayListRasterSource::ShouldAttemptToUseDistanceFieldText() const {
190 return should_attempt_to_use_distance_field_text_
;
193 void DisplayListRasterSource::AsValueInto(
194 base::trace_event::TracedValue
* array
) const {
195 if (display_list_
.get())
196 TracedValue::AppendIDRef(display_list_
.get(), array
);
199 void DisplayListRasterSource::DidBeginTracing() {
200 if (display_list_
.get())
201 display_list_
->EmitTraceSnapshot();
204 bool DisplayListRasterSource::CanUseLCDText() const {
205 return can_use_lcd_text_
;