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 { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 37 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { | 41 scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) { |
| 38 return make_scoped_refptr(new Picture(layer_rect)); | 42 return make_scoped_refptr(new Picture(layer_rect)); |
| 39 } | 43 } |
| 40 | 44 |
| 41 Picture::Picture(gfx::Rect layer_rect) | 45 Picture::Picture(gfx::Rect layer_rect) |
| 42 : layer_rect_(layer_rect) { | 46 : layer_rect_(layer_rect) { |
| 43 } | 47 } |
| 44 | 48 |
| 45 Picture::Picture(const skia::RefPtr<SkPicture>& picture, | 49 Picture::Picture(const skia::RefPtr<SkPicture>& picture, |
| 46 gfx::Rect layer_rect, | 50 gfx::Rect layer_rect, |
| 47 gfx::Rect opaque_rect) : | 51 gfx::Rect opaque_rect, |
| 52 const PositionPixelRefsVector& lazy_pixel_refs) : | |
| 48 layer_rect_(layer_rect), | 53 layer_rect_(layer_rect), |
| 49 opaque_rect_(opaque_rect), | 54 opaque_rect_(opaque_rect), |
| 50 picture_(picture) { | 55 picture_(picture), |
| 56 lazy_pixel_refs_(lazy_pixel_refs) { | |
| 51 } | 57 } |
| 52 | 58 |
| 53 Picture::~Picture() { | 59 Picture::~Picture() { |
| 54 } | 60 } |
| 55 | 61 |
| 56 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( | 62 scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread( |
| 57 unsigned thread_index) const { | 63 unsigned thread_index) const { |
| 58 // SkPicture is not thread-safe to rasterize with, this returns a clone | 64 // SkPicture is not thread-safe to rasterize with, this returns a clone |
| 59 // to rasterize with on a specific thread. | 65 // to rasterize with on a specific thread. |
| 60 CHECK_GT(clones_.size(), thread_index); | 66 CHECK_GT(clones_.size(), thread_index); |
| 61 return clones_[thread_index]; | 67 return clones_[thread_index]; |
| 62 } | 68 } |
| 63 | 69 |
| 64 void Picture::CloneForDrawing(int num_threads) { | 70 void Picture::CloneForDrawing(int num_threads) { |
| 65 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); | 71 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); |
| 66 | 72 |
| 67 DCHECK(picture_); | 73 DCHECK(picture_); |
| 68 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads]); | 74 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads]); |
| 69 picture_->clone(&clones[0], num_threads); | 75 picture_->clone(&clones[0], num_threads); |
| 70 | 76 |
| 71 clones_.clear(); | 77 clones_.clear(); |
| 72 for (int i = 0; i < num_threads; i++) { | 78 for (int i = 0; i < num_threads; i++) { |
| 73 scoped_refptr<Picture> clone = make_scoped_refptr( | 79 scoped_refptr<Picture> clone = make_scoped_refptr( |
| 74 new Picture(skia::AdoptRef(new SkPicture(clones[i])), | 80 new Picture(skia::AdoptRef(new SkPicture(clones[i])), |
| 75 layer_rect_, | 81 layer_rect_, |
| 76 opaque_rect_)); | 82 opaque_rect_, |
| 83 lazy_pixel_refs_)); | |
| 77 clones_.push_back(clone); | 84 clones_.push_back(clone); |
| 78 } | 85 } |
| 79 } | 86 } |
| 80 | 87 |
| 81 void Picture::Record(ContentLayerClient* painter, | 88 void Picture::Record(ContentLayerClient* painter, |
| 82 RenderingStats* stats, | 89 RenderingStats* stats, |
| 83 const SkTileGridPicture::TileGridInfo& tile_grid_info) { | 90 const SkTileGridPicture::TileGridInfo& tile_grid_info) { |
| 84 TRACE_EVENT2("cc", "Picture::Record", | 91 TRACE_EVENT2("cc", "Picture::Record", |
| 85 "width", layer_rect_.width(), "height", layer_rect_.height()); | 92 "width", layer_rect_.width(), "height", layer_rect_.height()); |
| 86 | 93 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 if (stats) { | 125 if (stats) { |
| 119 stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time; | 126 stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time; |
| 120 stats->total_pixels_painted += | 127 stats->total_pixels_painted += |
| 121 layer_rect_.width() * layer_rect_.height(); | 128 layer_rect_.width() * layer_rect_.height(); |
| 122 } | 129 } |
| 123 | 130 |
| 124 canvas->restore(); | 131 canvas->restore(); |
| 125 picture_->endRecording(); | 132 picture_->endRecording(); |
| 126 | 133 |
| 127 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); | 134 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); |
| 135 | |
| 136 GatherAllPixelRefs(); | |
| 128 } | 137 } |
| 129 | 138 |
| 130 void Picture::Raster( | 139 void Picture::Raster( |
| 131 SkCanvas* canvas, | 140 SkCanvas* canvas, |
| 132 gfx::Rect content_rect, | 141 gfx::Rect content_rect, |
| 133 float contents_scale, | 142 float contents_scale, |
| 134 bool enable_lcd_text) { | 143 bool enable_lcd_text) { |
| 135 TRACE_EVENT2("cc", "Picture::Raster", | 144 TRACE_EVENT2("cc", "Picture::Raster", |
| 136 "layer width", layer_rect_.width(), | 145 "layer width", layer_rect_.width(), |
| 137 "layer height", layer_rect_.height()); | 146 "layer height", layer_rect_.height()); |
| 138 DCHECK(picture_); | 147 DCHECK(picture_); |
| 139 | 148 |
| 140 DisableLCDTextFilter disable_lcd_text_filter; | 149 DisableLCDTextFilter disable_lcd_text_filter; |
| 141 | 150 |
| 142 canvas->save(); | 151 canvas->save(); |
| 143 canvas->clipRect(gfx::RectToSkRect(content_rect)); | 152 canvas->clipRect(gfx::RectToSkRect(content_rect)); |
| 144 canvas->scale(contents_scale, contents_scale); | 153 canvas->scale(contents_scale, contents_scale); |
| 145 canvas->translate(layer_rect_.x(), layer_rect_.y()); | 154 canvas->translate(layer_rect_.x(), layer_rect_.y()); |
| 146 // Pictures by default have LCD text enabled. | 155 // Pictures by default have LCD text enabled. |
| 147 if (!enable_lcd_text) | 156 if (!enable_lcd_text) |
| 148 canvas->setDrawFilter(&disable_lcd_text_filter); | 157 canvas->setDrawFilter(&disable_lcd_text_filter); |
| 149 canvas->drawPicture(*picture_); | 158 canvas->drawPicture(*picture_); |
| 150 canvas->restore(); | 159 canvas->restore(); |
| 151 } | 160 } |
| 152 | 161 |
| 153 void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, | 162 void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, |
| 154 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | 163 std::list<skia::LazyPixelRef*>& pixel_ref_list) { |
| 164 std::list<skia::LazyPixelRef*> pixel_refs; | |
| 165 for (PositionPixelRefsVector::iterator iter = lazy_pixel_refs_.begin(); | |
| 166 iter != lazy_pixel_refs_.end(); | |
| 167 ++iter) { | |
| 168 if (iter->rect.Intersects(layer_rect)) { | |
| 169 pixel_refs.insert(pixel_refs.end(), | |
| 170 iter->pixel_refs.begin(), | |
| 171 iter->pixel_refs.end()); | |
| 172 } | |
| 173 } | |
| 174 std::set<skia::LazyPixelRef*> unique_pixel_refs(pixel_refs.begin(), | |
| 175 pixel_refs.end()); | |
| 176 pixel_ref_list.insert(pixel_ref_list.end(), | |
| 177 unique_pixel_refs.begin(), | |
| 178 unique_pixel_refs.end()); | |
| 179 } | |
| 180 | |
| 181 void Picture::GatherPixelRefsFromSkia( | |
| 182 const gfx::Rect& layer_rect, | |
| 183 std::list<skia::LazyPixelRef*>& pixel_ref_list) { | |
| 155 DCHECK(picture_); | 184 DCHECK(picture_); |
| 156 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( | 185 SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( |
| 157 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), | 186 picture_.get(), SkRect::MakeXYWH(layer_rect.x(), |
| 158 layer_rect.y(), | 187 layer_rect.y(), |
| 159 layer_rect.width(), | 188 layer_rect.width(), |
| 160 layer_rect.height())); | 189 layer_rect.height())); |
| 161 if (!pixel_refs) | 190 if (!pixel_refs) |
| 162 return; | 191 return; |
| 163 | 192 |
| 164 void* data = const_cast<void*>(pixel_refs->data()); | 193 void* data = const_cast<void*>(pixel_refs->data()); |
| 165 if (!data) { | 194 if (!data) { |
| 166 pixel_refs->unref(); | 195 pixel_refs->unref(); |
| 167 return; | 196 return; |
| 168 } | 197 } |
| 169 | 198 |
| 170 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); | 199 SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data); |
| 171 for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) { | 200 for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) { |
| 172 if (*refs && (*refs)->getURI() && !strncmp( | 201 if (*refs && (*refs)->getURI() && !strncmp( |
| 173 (*refs)->getURI(), kLabelLazyDecoded, 4)) { | 202 (*refs)->getURI(), kLabelLazyDecoded, 4)) { |
| 174 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); | 203 pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs)); |
| 175 } | 204 } |
| 176 refs++; | 205 refs++; |
| 177 } | 206 } |
| 178 pixel_refs->unref(); | 207 pixel_refs->unref(); |
| 179 } | 208 } |
| 180 | 209 |
| 210 void Picture::GatherAllPixelRefs() { | |
| 211 const gfx::Size kRegionSize(512, 512); | |
| 212 // Capture pixel refs for this picture in a grid | |
| 213 // with kRegionSize sized cells. | |
| 214 for (int y = layer_rect_.y(); | |
| 215 y < layer_rect_.bottom(); | |
| 216 y += kRegionSize.height()) { | |
| 217 for (int x = layer_rect_.x(); | |
| 218 x < layer_rect_.right(); | |
| 219 x += kRegionSize.width()) { | |
| 220 gfx::Size extent( | |
| 221 std::min(kRegionSize.width(), layer_rect_.right() - x), | |
| 222 std::min(kRegionSize.height(), layer_rect_.bottom() - y)); | |
| 223 gfx::Rect rect(x, y, extent.width(), extent.height()); | |
|
enne (OOO)
2013/04/16 22:03:36
Can we get this information from Skia, rather than
reveman
2013/04/17 00:25:28
this is not related to the image size. it's the gr
| |
| 224 | |
| 225 std::list<skia::LazyPixelRef*> lazy_pixel_refs; | |
| 226 GatherPixelRefsFromSkia(rect, lazy_pixel_refs); | |
| 227 | |
| 228 // Only capture non-empty cells. | |
| 229 if (!lazy_pixel_refs.empty()) { | |
| 230 PositionPixelRefs position_pixel_refs; | |
| 231 position_pixel_refs.rect = rect; | |
| 232 position_pixel_refs.pixel_refs.swap(lazy_pixel_refs); | |
| 233 lazy_pixel_refs_.push_back(position_pixel_refs); | |
| 234 } | |
| 235 } | |
| 236 } | |
| 237 } | |
| 238 | |
| 181 } // namespace cc | 239 } // namespace cc |
| OLD | NEW |