OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/resources/picture.h" | |
6 | |
7 #include <algorithm> | |
8 #include <set> | |
9 | |
5 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
6 #include "cc/debug/rendering_stats.h" | 11 #include "cc/debug/rendering_stats.h" |
7 #include "cc/layers/content_layer_client.h" | 12 #include "cc/layers/content_layer_client.h" |
8 #include "cc/resources/picture.h" | |
9 #include "skia/ext/analysis_canvas.h" | 13 #include "skia/ext/analysis_canvas.h" |
10 #include "third_party/skia/include/core/SkCanvas.h" | 14 #include "third_party/skia/include/core/SkCanvas.h" |
11 #include "third_party/skia/include/core/SkData.h" | 15 #include "third_party/skia/include/core/SkData.h" |
12 #include "third_party/skia/include/core/SkDrawFilter.h" | 16 #include "third_party/skia/include/core/SkDrawFilter.h" |
13 #include "third_party/skia/include/core/SkPaint.h" | 17 #include "third_party/skia/include/core/SkPaint.h" |
14 #include "third_party/skia/include/utils/SkPictureUtils.h" | 18 #include "third_party/skia/include/utils/SkPictureUtils.h" |
15 #include "ui/gfx/rect_conversions.h" | 19 #include "ui/gfx/rect_conversions.h" |
16 #include "ui/gfx/skia_util.h" | 20 #include "ui/gfx/skia_util.h" |
17 | 21 |
18 namespace { | 22 namespace { |
19 // URI label for a lazily decoded SkPixelRef. | 23 // URI label for a lazily decoded SkPixelRef. |
20 const char kLabelLazyDecoded[] = "lazy"; | 24 const char kLabelLazyDecoded[] = "lazy"; |
25 // Size of each of the grid cells for storing lazy pixel refs. | |
26 const gfx::Size kRegionSize(512, 512); | |
reveman
2013/04/17 00:42:57
only POD is allowed for objects with static storag
| |
21 | 27 |
22 class DisableLCDTextFilter : public SkDrawFilter { | 28 class DisableLCDTextFilter : public SkDrawFilter { |
23 public: | 29 public: |
24 // SkDrawFilter interface. | 30 // SkDrawFilter interface. |
25 virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE { | 31 virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE { |
26 if (type != SkDrawFilter::kText_Type) | 32 if (type != SkDrawFilter::kText_Type) |
27 return true; | 33 return true; |
28 | 34 |
29 paint->setLCDRenderText(false); | 35 paint->setLCDRenderText(false); |
30 return true; | 36 return true; |
31 } | 37 } |
32 }; | 38 }; |
33 } // namespace | 39 } // namespace |
34 | 40 |
35 namespace cc { | 41 namespace cc { |
36 | 42 |
37 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { | 43 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { |
38 return make_scoped_refptr(new Picture(layer_rect)); | 44 return make_scoped_refptr(new Picture(layer_rect)); |
39 } | 45 } |
40 | 46 |
41 Picture::Picture(gfx::Rect layer_rect) | 47 Picture::Picture(gfx::Rect layer_rect) |
42 : layer_rect_(layer_rect) { | 48 : layer_rect_(layer_rect) { |
43 } | 49 } |
44 | 50 |
45 Picture::Picture(const skia::RefPtr<SkPicture>& picture, | 51 Picture::Picture(const skia::RefPtr<SkPicture>& picture, |
46 gfx::Rect layer_rect, | 52 gfx::Rect layer_rect, |
47 gfx::Rect opaque_rect) : | 53 gfx::Rect opaque_rect, |
54 const PixelRefsMap& lazy_pixel_refs) : | |
48 layer_rect_(layer_rect), | 55 layer_rect_(layer_rect), |
49 opaque_rect_(opaque_rect), | 56 opaque_rect_(opaque_rect), |
50 picture_(picture) { | 57 picture_(picture), |
58 lazy_pixel_refs_(lazy_pixel_refs) { | |
51 } | 59 } |
52 | 60 |
53 Picture::~Picture() { | 61 Picture::~Picture() { |
54 } | 62 } |
55 | 63 |
56 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( | 64 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( |
57 unsigned thread_index) const { | 65 unsigned thread_index) const { |
58 // SkPicture is not thread-safe to rasterize with, this returns a clone | 66 // SkPicture is not thread-safe to rasterize with, this returns a clone |
59 // to rasterize with on a specific thread. | 67 // to rasterize with on a specific thread. |
60 CHECK_GT(clones_.size(), thread_index); | 68 CHECK_GT(clones_.size(), thread_index); |
61 return clones_[thread_index]; | 69 return clones_[thread_index]; |
62 } | 70 } |
63 | 71 |
64 void Picture::CloneForDrawing(int num_threads) { | 72 void Picture::CloneForDrawing(int num_threads) { |
65 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); | 73 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); |
66 | 74 |
67 DCHECK(picture_); | 75 DCHECK(picture_); |
68 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads]); | 76 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads]); |
69 picture_->clone(&clones[0], num_threads); | 77 picture_->clone(&clones[0], num_threads); |
70 | 78 |
71 clones_.clear(); | 79 clones_.clear(); |
72 for (int i = 0; i < num_threads; i++) { | 80 for (int i = 0; i < num_threads; i++) { |
73 scoped_refptr<Picture> clone = make_scoped_refptr( | 81 scoped_refptr<Picture> clone = make_scoped_refptr( |
74 new Picture(skia::AdoptRef(new SkPicture(clones[i])), | 82 new Picture(skia::AdoptRef(new SkPicture(clones[i])), |
75 layer_rect_, | 83 layer_rect_, |
76 opaque_rect_)); | 84 opaque_rect_, |
85 lazy_pixel_refs_)); | |
77 clones_.push_back(clone); | 86 clones_.push_back(clone); |
78 } | 87 } |
79 } | 88 } |
80 | 89 |
81 void Picture::Record(ContentLayerClient* painter, | 90 void Picture::Record(ContentLayerClient* painter, |
82 RenderingStats* stats, | 91 RenderingStats* stats, |
83 const SkTileGridPicture::TileGridInfo& tile_grid_info) { | 92 const SkTileGridPicture::TileGridInfo& tile_grid_info) { |
84 TRACE_EVENT2("cc", "Picture::Record", | 93 TRACE_EVENT2("cc", "Picture::Record", |
85 "width", layer_rect_.width(), "height", layer_rect_.height()); | 94 "width", layer_rect_.width(), "height", layer_rect_.height()); |
86 | 95 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 if (stats) { | 127 if (stats) { |
119 stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time; | 128 stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time; |
120 stats->total_pixels_painted += | 129 stats->total_pixels_painted += |
121 layer_rect_.width() * layer_rect_.height(); | 130 layer_rect_.width() * layer_rect_.height(); |
122 } | 131 } |
123 | 132 |
124 canvas->restore(); | 133 canvas->restore(); |
125 picture_->endRecording(); | 134 picture_->endRecording(); |
126 | 135 |
127 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); | 136 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); |
137 | |
138 GatherAllPixelRefs(); | |
128 } | 139 } |
129 | 140 |
130 void Picture::Raster( | 141 void Picture::Raster( |
131 SkCanvas* canvas, | 142 SkCanvas* canvas, |
132 gfx::Rect content_rect, | 143 gfx::Rect content_rect, |
133 float contents_scale, | 144 float contents_scale, |
134 bool enable_lcd_text) { | 145 bool enable_lcd_text) { |
135 TRACE_EVENT2("cc", "Picture::Raster", | 146 TRACE_EVENT2("cc", "Picture::Raster", |
136 "layer width", layer_rect_.width(), | 147 "layer width", layer_rect_.width(), |
137 "layer height", layer_rect_.height()); | 148 "layer height", layer_rect_.height()); |
138 DCHECK(picture_); | 149 DCHECK(picture_); |
139 | 150 |
140 DisableLCDTextFilter disable_lcd_text_filter; | 151 DisableLCDTextFilter disable_lcd_text_filter; |
141 | 152 |
142 canvas->save(); | 153 canvas->save(); |
143 canvas->clipRect(gfx::RectToSkRect(content_rect)); | 154 canvas->clipRect(gfx::RectToSkRect(content_rect)); |
144 canvas->scale(contents_scale, contents_scale); | 155 canvas->scale(contents_scale, contents_scale); |
145 canvas->translate(layer_rect_.x(), layer_rect_.y()); | 156 canvas->translate(layer_rect_.x(), layer_rect_.y()); |
146 // Pictures by default have LCD text enabled. | 157 // Pictures by default have LCD text enabled. |
147 if (!enable_lcd_text) | 158 if (!enable_lcd_text) |
148 canvas->setDrawFilter(&disable_lcd_text_filter); | 159 canvas->setDrawFilter(&disable_lcd_text_filter); |
149 canvas->drawPicture(*picture_); | 160 canvas->drawPicture(*picture_); |
150 canvas->restore(); | 161 canvas->restore(); |
151 } | 162 } |
152 | 163 |
153 void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, | 164 void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, |
154 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | 165 std::list<skia::LazyPixelRef*>& pixel_ref_list) { |
reveman
2013/04/17 00:42:57
How about adding a Picture::PixelRefIterator inste
| |
166 std::list<skia::LazyPixelRef*> pixel_refs; | |
167 // The min/max point calculation assumes that layer_rect | |
168 // origin's coordinates are non-negative. | |
169 DCHECK(layer_rect.x() >= 0 && layer_rect.y() >= 0); | |
170 gfx::Point min_point( | |
171 (layer_rect.x() / kRegionSize.width()) * kRegionSize.width(), | |
172 (layer_rect.y() / kRegionSize.height()) * kRegionSize.height()); | |
173 gfx::Point max_point( | |
174 (layer_rect.right() / kRegionSize.width()) * kRegionSize.width(), | |
175 (layer_rect.bottom() / kRegionSize.height()) * kRegionSize.height()); | |
176 | |
177 for (int y = min_point.y(); y <= max_point.y(); y += kRegionSize.height()) { | |
178 for (int x = min_point.x(); x <= max_point.x(); x += kRegionSize.width()) { | |
179 PixelRefsMap::const_iterator iter = | |
180 lazy_pixel_refs_.find(std::make_pair(x, y)); | |
181 if (iter != lazy_pixel_refs_.end()) { | |
182 pixel_refs.insert(pixel_refs.end(), | |
183 iter->second.begin(), | |
184 iter->second.end()); | |
185 } | |
186 } | |
187 } | |
188 std::set<skia::LazyPixelRef*> unique_pixel_refs(pixel_refs.begin(), | |
189 pixel_refs.end()); | |
190 pixel_ref_list.insert(pixel_ref_list.end(), | |
191 unique_pixel_refs.begin(), | |
192 unique_pixel_refs.end()); | |
193 } | |
194 | |
195 void Picture::GatherPixelRefsFromSkia( | |
196 const gfx::Rect& layer_rect, | |
197 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | |
155 DCHECK(picture_); | 198 DCHECK(picture_); |
156 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( | 199 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( |
157 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), | 200 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), |
158 layer_rect.y(), | 201 layer_rect.y(), |
159 layer_rect.width(), | 202 layer_rect.width(), |
160 layer_rect.height())); | 203 layer_rect.height())); |
161 if (!pixel_refs) | 204 if (!pixel_refs) |
162 return; | 205 return; |
163 | 206 |
164 void* data = const_cast<void*>(pixel_refs->data()); | 207 void* data = const_cast<void*>(pixel_refs->data()); |
165 if (!data) { | 208 if (!data) { |
166 pixel_refs->unref(); | 209 pixel_refs->unref(); |
167 return; | 210 return; |
168 } | 211 } |
169 | 212 |
170 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); | 213 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); |
171 for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) { | 214 for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) { |
172 if (*refs && (*refs)->getURI() && !strncmp( | 215 if (*refs && (*refs)->getURI() && !strncmp( |
173 (*refs)->getURI(), kLabelLazyDecoded, 4)) { | 216 (*refs)->getURI(), kLabelLazyDecoded, 4)) { |
174 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); | 217 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); |
175 } | 218 } |
176 refs++; | 219 refs++; |
177 } | 220 } |
178 pixel_refs->unref(); | 221 pixel_refs->unref(); |
179 } | 222 } |
180 | 223 |
224 void Picture::GatherAllPixelRefs() { | |
225 // Capture pixel refs for this picture in a grid | |
226 // with kRegionSize sized cells. | |
227 for (int y = layer_rect_.y(); | |
228 y < layer_rect_.bottom(); | |
229 y += kRegionSize.height()) { | |
230 for (int x = layer_rect_.x(); | |
231 x < layer_rect_.right(); | |
232 x += kRegionSize.width()) { | |
233 gfx::Size extent( | |
234 std::min(kRegionSize.width(), layer_rect_.right() - x), | |
235 std::min(kRegionSize.height(), layer_rect_.bottom() - y)); | |
236 gfx::Rect rect(x, y, extent.width(), extent.height()); | |
237 | |
238 std::list<skia::LazyPixelRef*> lazy_pixel_refs; | |
239 GatherPixelRefsFromSkia(rect, lazy_pixel_refs); | |
240 | |
241 // Only capture non-empty cells. | |
242 if (!lazy_pixel_refs.empty()) | |
243 lazy_pixel_refs_[std::make_pair(x, y)].swap(lazy_pixel_refs); | |
244 } | |
245 } | |
246 } | |
247 | |
181 } // namespace cc | 248 } // namespace cc |
OLD | NEW |