Chromium Code Reviews| 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 int kRegionWidth = 512; | |
| 27 const int kRegionHeight = 512; | |
| 21 | 28 |
| 22 class DisableLCDTextFilter : public SkDrawFilter { | 29 class DisableLCDTextFilter : public SkDrawFilter { |
| 23 public: | 30 public: |
| 24 // SkDrawFilter interface. | 31 // SkDrawFilter interface. |
| 25 virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE { | 32 virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE { |
| 26 if (type != SkDrawFilter::kText_Type) | 33 if (type != SkDrawFilter::kText_Type) |
| 27 return true; | 34 return true; |
| 28 | 35 |
| 29 paint->setLCDRenderText(false); | 36 paint->setLCDRenderText(false); |
| 30 return true; | 37 return true; |
| 31 } | 38 } |
| 32 }; | 39 }; |
| 33 } // namespace | 40 } // namespace |
| 34 | 41 |
| 35 namespace cc { | 42 namespace cc { |
| 36 | 43 |
| 37 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { | 44 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { |
| 38 return make_scoped_refptr(new Picture(layer_rect)); | 45 return make_scoped_refptr(new Picture(layer_rect)); |
| 39 } | 46 } |
| 40 | 47 |
| 41 Picture::Picture(gfx::Rect layer_rect) | 48 Picture::Picture(gfx::Rect layer_rect) |
| 42 : layer_rect_(layer_rect) { | 49 : layer_rect_(layer_rect) { |
| 43 } | 50 } |
| 44 | 51 |
| 45 Picture::Picture(const skia::RefPtr<SkPicture>& picture, | 52 Picture::Picture(const skia::RefPtr<SkPicture>& picture, |
| 46 gfx::Rect layer_rect, | 53 gfx::Rect layer_rect, |
| 47 gfx::Rect opaque_rect) : | 54 gfx::Rect opaque_rect, |
| 55 const PixelRefsMap& lazy_pixel_refs) : | |
| 48 layer_rect_(layer_rect), | 56 layer_rect_(layer_rect), |
| 49 opaque_rect_(opaque_rect), | 57 opaque_rect_(opaque_rect), |
| 50 picture_(picture) { | 58 picture_(picture), |
| 59 lazy_pixel_refs_(lazy_pixel_refs) { | |
| 51 } | 60 } |
| 52 | 61 |
| 53 Picture::~Picture() { | 62 Picture::~Picture() { |
| 54 } | 63 } |
| 55 | 64 |
| 56 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( | 65 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( |
| 57 unsigned thread_index) const { | 66 unsigned thread_index) const { |
| 58 // SkPicture is not thread-safe to rasterize with, this returns a clone | 67 // SkPicture is not thread-safe to rasterize with, this returns a clone |
| 59 // to rasterize with on a specific thread. | 68 // to rasterize with on a specific thread. |
| 60 CHECK_GT(clones_.size(), thread_index); | 69 CHECK_GT(clones_.size(), thread_index); |
| 61 return clones_[thread_index]; | 70 return clones_[thread_index]; |
| 62 } | 71 } |
| 63 | 72 |
| 64 void Picture::CloneForDrawing(int num_threads) { | 73 void Picture::CloneForDrawing(int num_threads) { |
| 65 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); | 74 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); |
| 66 | 75 |
| 67 DCHECK(picture_); | 76 DCHECK(picture_); |
| 68 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads]); | 77 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads]); |
| 69 picture_->clone(&clones[0], num_threads); | 78 picture_->clone(&clones[0], num_threads); |
| 70 | 79 |
| 71 clones_.clear(); | 80 clones_.clear(); |
| 72 for (int i = 0; i < num_threads; i++) { | 81 for (int i = 0; i < num_threads; i++) { |
| 73 scoped_refptr<Picture> clone = make_scoped_refptr( | 82 scoped_refptr<Picture> clone = make_scoped_refptr( |
| 74 new Picture(skia::AdoptRef(new SkPicture(clones[i])), | 83 new Picture(skia::AdoptRef(new SkPicture(clones[i])), |
| 75 layer_rect_, | 84 layer_rect_, |
| 76 opaque_rect_)); | 85 opaque_rect_, |
| 86 lazy_pixel_refs_)); | |
| 77 clones_.push_back(clone); | 87 clones_.push_back(clone); |
| 78 } | 88 } |
| 79 } | 89 } |
| 80 | 90 |
| 81 void Picture::Record(ContentLayerClient* painter, | 91 void Picture::Record(ContentLayerClient* painter, |
| 82 RenderingStats* stats, | 92 RenderingStats* stats, |
| 83 const SkTileGridPicture::TileGridInfo& tile_grid_info) { | 93 const SkTileGridPicture::TileGridInfo& tile_grid_info) { |
| 84 TRACE_EVENT2("cc", "Picture::Record", | 94 TRACE_EVENT2("cc", "Picture::Record", |
| 85 "width", layer_rect_.width(), "height", layer_rect_.height()); | 95 "width", layer_rect_.width(), "height", layer_rect_.height()); |
| 86 | 96 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 if (stats) { | 128 if (stats) { |
| 119 stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time; | 129 stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time; |
| 120 stats->total_pixels_painted += | 130 stats->total_pixels_painted += |
| 121 layer_rect_.width() * layer_rect_.height(); | 131 layer_rect_.width() * layer_rect_.height(); |
| 122 } | 132 } |
| 123 | 133 |
| 124 canvas->restore(); | 134 canvas->restore(); |
| 125 picture_->endRecording(); | 135 picture_->endRecording(); |
| 126 | 136 |
| 127 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); | 137 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); |
| 138 | |
| 139 GatherAllPixelRefs(); | |
| 128 } | 140 } |
| 129 | 141 |
| 130 void Picture::Raster( | 142 void Picture::Raster( |
| 131 SkCanvas* canvas, | 143 SkCanvas* canvas, |
| 132 gfx::Rect content_rect, | 144 gfx::Rect content_rect, |
| 133 float contents_scale, | 145 float contents_scale, |
| 134 bool enable_lcd_text) { | 146 bool enable_lcd_text) { |
| 135 TRACE_EVENT2("cc", "Picture::Raster", | 147 TRACE_EVENT2("cc", "Picture::Raster", |
| 136 "layer width", layer_rect_.width(), | 148 "layer width", layer_rect_.width(), |
| 137 "layer height", layer_rect_.height()); | 149 "layer height", layer_rect_.height()); |
| 138 DCHECK(picture_); | 150 DCHECK(picture_); |
| 139 | 151 |
| 140 DisableLCDTextFilter disable_lcd_text_filter; | 152 DisableLCDTextFilter disable_lcd_text_filter; |
| 141 | 153 |
| 142 canvas->save(); | 154 canvas->save(); |
| 143 canvas->clipRect(gfx::RectToSkRect(content_rect)); | 155 canvas->clipRect(gfx::RectToSkRect(content_rect)); |
| 144 canvas->scale(contents_scale, contents_scale); | 156 canvas->scale(contents_scale, contents_scale); |
| 145 canvas->translate(layer_rect_.x(), layer_rect_.y()); | 157 canvas->translate(layer_rect_.x(), layer_rect_.y()); |
| 146 // Pictures by default have LCD text enabled. | 158 // Pictures by default have LCD text enabled. |
| 147 if (!enable_lcd_text) | 159 if (!enable_lcd_text) |
| 148 canvas->setDrawFilter(&disable_lcd_text_filter); | 160 canvas->setDrawFilter(&disable_lcd_text_filter); |
| 149 canvas->drawPicture(*picture_); | 161 canvas->drawPicture(*picture_); |
| 150 canvas->restore(); | 162 canvas->restore(); |
| 151 } | 163 } |
| 152 | 164 |
| 153 void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, | 165 void Picture::GatherPixelRefsFromSkia( |
| 154 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | 166 const gfx::Rect& layer_rect, |
| 167 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | |
| 155 DCHECK(picture_); | 168 DCHECK(picture_); |
| 156 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( | 169 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( |
| 157 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), | 170 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), |
| 158 layer_rect.y(), | 171 layer_rect.y(), |
| 159 layer_rect.width(), | 172 layer_rect.width(), |
| 160 layer_rect.height())); | 173 layer_rect.height())); |
| 161 if (!pixel_refs) | 174 if (!pixel_refs) |
| 162 return; | 175 return; |
| 163 | 176 |
| 164 void* data = const_cast<void*>(pixel_refs->data()); | 177 void* data = const_cast<void*>(pixel_refs->data()); |
| 165 if (!data) { | 178 if (!data) { |
| 166 pixel_refs->unref(); | 179 pixel_refs->unref(); |
| 167 return; | 180 return; |
| 168 } | 181 } |
| 169 | 182 |
| 170 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); | 183 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); |
| 171 for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) { | 184 for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) { |
| 172 if (*refs && (*refs)->getURI() && !strncmp( | 185 if (*refs && (*refs)->getURI() && !strncmp( |
| 173 (*refs)->getURI(), kLabelLazyDecoded, 4)) { | 186 (*refs)->getURI(), kLabelLazyDecoded, 4)) { |
| 174 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); | 187 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); |
| 175 } | 188 } |
| 176 refs++; | 189 refs++; |
| 177 } | 190 } |
| 178 pixel_refs->unref(); | 191 pixel_refs->unref(); |
| 179 } | 192 } |
| 180 | 193 |
| 194 void Picture::GatherAllPixelRefs() { | |
| 195 // Capture pixel refs for this picture in a grid | |
| 196 // with kRegionWidth by kRegionHeight cells. | |
| 197 for (int y = layer_rect_.y(); y < layer_rect_.bottom(); y += kRegionHeight) { | |
| 198 for (int x = layer_rect_.x(); x < layer_rect_.right(); x += kRegionWidth) { | |
| 199 gfx::Size extent(std::min(kRegionWidth, layer_rect_.right() - x), | |
| 200 std::min(kRegionHeight, layer_rect_.bottom() - y)); | |
| 201 gfx::Rect rect(x, y, extent.width(), extent.height()); | |
| 202 | |
| 203 std::list<skia::LazyPixelRef*> lazy_pixel_refs; | |
| 204 GatherPixelRefsFromSkia(rect, lazy_pixel_refs); | |
| 205 | |
| 206 // Only capture non-empty cells. | |
| 207 if (!lazy_pixel_refs.empty()) | |
| 208 lazy_pixel_refs_[std::make_pair(x, y)].swap(lazy_pixel_refs); | |
| 209 } | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 Picture::LazyPixelRefsIterator::LazyPixelRefsIterator() | |
|
enne (OOO)
2013/04/22 16:47:26
What's the default ctor for?
| |
| 214 : picture_(0), | |
| 215 current_pixel_ref_(0), | |
| 216 min_point_(-1, -1), | |
| 217 max_point_(-1, -1), | |
| 218 current_x_(0), | |
| 219 current_y_(0) { | |
| 220 } | |
| 221 | |
| 222 Picture::LazyPixelRefsIterator::LazyPixelRefsIterator( | |
|
enne (OOO)
2013/04/22 16:47:26
To be consistent with other code, could you call t
| |
| 223 gfx::Rect layer_rect, | |
| 224 const Picture* picture) | |
| 225 : picture_(picture), | |
| 226 current_pixel_ref_(NULL) { | |
| 227 // The min/max point calculation assumes that layer_rect | |
| 228 // origin's coordinates are non-negative. | |
| 229 DCHECK(layer_rect.x() >= 0 && layer_rect.y() >= 0); | |
| 230 min_point_ = gfx::Point( | |
| 231 (layer_rect.x() / kRegionWidth) * kRegionWidth, | |
| 232 (layer_rect.y() / kRegionHeight) * kRegionHeight); | |
| 233 max_point_ = gfx::Point( | |
| 234 (layer_rect.right() / kRegionWidth) * kRegionWidth, | |
| 235 (layer_rect.bottom() / kRegionHeight) * kRegionHeight); | |
| 236 | |
| 237 // Make the current x be kRegionWidth less than min point, so that | |
| 238 // the first increment will point at min_point_. | |
| 239 current_x_ = min_point_.x() - kRegionWidth; | |
| 240 current_y_ = min_point_.y(); | |
| 241 ++(*this); | |
| 242 } | |
| 243 | |
| 244 Picture::LazyPixelRefsIterator::~LazyPixelRefsIterator() { | |
| 245 } | |
| 246 | |
| 247 Picture::LazyPixelRefsIterator& Picture::LazyPixelRefsIterator::operator++() { | |
| 248 // If we're not at the end of the list, then just get the next item. | |
| 249 if (!current_list_.empty()) { | |
| 250 current_pixel_ref_ = current_list_.front(); | |
| 251 current_list_.pop_front(); | |
| 252 return *this; | |
| 253 } | |
| 254 | |
| 255 // If we already passed the max y, do nothing. | |
| 256 if (current_y_ > max_point_.y()) | |
| 257 return *this; | |
| 258 | |
| 259 while (true) { | |
| 260 // Advance the current grid cell. | |
| 261 current_x_ += kRegionWidth; | |
| 262 if (current_x_ > max_point_.x()) { | |
| 263 current_y_ += kRegionHeight; | |
| 264 current_x_ = min_point_.x(); | |
| 265 if (current_y_ > max_point_.y()) { | |
| 266 current_pixel_ref_ = NULL; | |
| 267 break; | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 // If there are no pixel refs at this grid cell, keep incrementing. | |
| 272 PixelRefsMap::const_iterator iter = | |
| 273 picture_->lazy_pixel_refs_.find(std::make_pair(current_x_, current_y_)); | |
| 274 if (iter == picture_->lazy_pixel_refs_.end() || iter->second.empty()) | |
| 275 continue; | |
| 276 | |
| 277 // We found a non-empty list: store it and get the first pixel ref. | |
| 278 current_list_ = iter->second; | |
| 279 current_pixel_ref_ = current_list_.front(); | |
| 280 current_list_.pop_front(); | |
| 281 break; | |
| 282 } | |
| 283 return *this; | |
| 284 } | |
| 285 | |
| 181 } // namespace cc | 286 } // namespace cc |
| OLD | NEW |