Index: cc/resources/picture.cc |
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc |
index 2b6eca8777fbc0c3d7d280170d3f7008ce85d990..24cbb244a2493a6f7231b0d4f696bf59ea0213e4 100644 |
--- a/cc/resources/picture.cc |
+++ b/cc/resources/picture.cc |
@@ -2,10 +2,14 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "cc/resources/picture.h" |
+ |
+#include <algorithm> |
+#include <set> |
+ |
#include "base/debug/trace_event.h" |
#include "cc/debug/rendering_stats.h" |
#include "cc/layers/content_layer_client.h" |
-#include "cc/resources/picture.h" |
#include "skia/ext/analysis_canvas.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
#include "third_party/skia/include/core/SkData.h" |
@@ -18,6 +22,9 @@ |
namespace { |
// URI label for a lazily decoded SkPixelRef. |
const char kLabelLazyDecoded[] = "lazy"; |
+// Size of each of the grid cells for storing lazy pixel refs. |
+const int kRegionWidth = 512; |
+const int kRegionHeight = 512; |
class DisableLCDTextFilter : public SkDrawFilter { |
public: |
@@ -44,10 +51,12 @@ Picture::Picture(gfx::Rect layer_rect) |
Picture::Picture(const skia::RefPtr<SkPicture>& picture, |
gfx::Rect layer_rect, |
- gfx::Rect opaque_rect) : |
+ gfx::Rect opaque_rect, |
+ const PixelRefsMap& lazy_pixel_refs) : |
layer_rect_(layer_rect), |
opaque_rect_(opaque_rect), |
- picture_(picture) { |
+ picture_(picture), |
+ lazy_pixel_refs_(lazy_pixel_refs) { |
} |
Picture::~Picture() { |
@@ -73,7 +82,8 @@ void Picture::CloneForDrawing(int num_threads) { |
scoped_refptr<Picture> clone = make_scoped_refptr( |
new Picture(skia::AdoptRef(new SkPicture(clones[i])), |
layer_rect_, |
- opaque_rect_)); |
+ opaque_rect_, |
+ lazy_pixel_refs_)); |
clones_.push_back(clone); |
} |
} |
@@ -125,6 +135,8 @@ void Picture::Record(ContentLayerClient* painter, |
picture_->endRecording(); |
opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); |
+ |
+ GatherAllPixelRefs(); |
} |
void Picture::Raster( |
@@ -150,8 +162,9 @@ void Picture::Raster( |
canvas->restore(); |
} |
-void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, |
- std::list<skia::LazyPixelRef*>& pixel_ref_list) { |
+void Picture::GatherPixelRefsFromSkia( |
+ const gfx::Rect& layer_rect, |
+ std::list<skia::LazyPixelRef*>& pixel_ref_list) { |
DCHECK(picture_); |
SkData* pixel_refs = SkPictureUtils::GatherPixelRefs( |
picture_.get(), SkRect::MakeXYWH(layer_rect.x(), |
@@ -178,4 +191,96 @@ void Picture::GatherPixelRefs(const gfx::Rect& layer_rect, |
pixel_refs->unref(); |
} |
+void Picture::GatherAllPixelRefs() { |
+ // Capture pixel refs for this picture in a grid |
+ // with kRegionWidth by kRegionHeight cells. |
+ for (int y = layer_rect_.y(); y < layer_rect_.bottom(); y += kRegionHeight) { |
+ for (int x = layer_rect_.x(); x < layer_rect_.right(); x += kRegionWidth) { |
+ gfx::Size extent(std::min(kRegionWidth, layer_rect_.right() - x), |
+ std::min(kRegionHeight, layer_rect_.bottom() - y)); |
+ gfx::Rect rect(x, y, extent.width(), extent.height()); |
+ |
+ std::list<skia::LazyPixelRef*> lazy_pixel_refs; |
+ GatherPixelRefsFromSkia(rect, lazy_pixel_refs); |
+ |
+ // Only capture non-empty cells. |
+ if (!lazy_pixel_refs.empty()) |
+ lazy_pixel_refs_[std::make_pair(x, y)].swap(lazy_pixel_refs); |
+ } |
+ } |
+} |
+ |
+Picture::LazyPixelRefsIterator::LazyPixelRefsIterator() |
enne (OOO)
2013/04/22 16:47:26
What's the default ctor for?
|
+ : picture_(0), |
+ current_pixel_ref_(0), |
+ min_point_(-1, -1), |
+ max_point_(-1, -1), |
+ current_x_(0), |
+ current_y_(0) { |
+} |
+ |
+Picture::LazyPixelRefsIterator::LazyPixelRefsIterator( |
enne (OOO)
2013/04/22 16:47:26
To be consistent with other code, could you call t
|
+ gfx::Rect layer_rect, |
+ const Picture* picture) |
+ : picture_(picture), |
+ current_pixel_ref_(NULL) { |
+ // The min/max point calculation assumes that layer_rect |
+ // origin's coordinates are non-negative. |
+ DCHECK(layer_rect.x() >= 0 && layer_rect.y() >= 0); |
+ min_point_ = gfx::Point( |
+ (layer_rect.x() / kRegionWidth) * kRegionWidth, |
+ (layer_rect.y() / kRegionHeight) * kRegionHeight); |
+ max_point_ = gfx::Point( |
+ (layer_rect.right() / kRegionWidth) * kRegionWidth, |
+ (layer_rect.bottom() / kRegionHeight) * kRegionHeight); |
+ |
+ // Make the current x be kRegionWidth less than min point, so that |
+ // the first increment will point at min_point_. |
+ current_x_ = min_point_.x() - kRegionWidth; |
+ current_y_ = min_point_.y(); |
+ ++(*this); |
+} |
+ |
+Picture::LazyPixelRefsIterator::~LazyPixelRefsIterator() { |
+} |
+ |
+Picture::LazyPixelRefsIterator& Picture::LazyPixelRefsIterator::operator++() { |
+ // If we're not at the end of the list, then just get the next item. |
+ if (!current_list_.empty()) { |
+ current_pixel_ref_ = current_list_.front(); |
+ current_list_.pop_front(); |
+ return *this; |
+ } |
+ |
+ // If we already passed the max y, do nothing. |
+ if (current_y_ > max_point_.y()) |
+ return *this; |
+ |
+ while (true) { |
+ // Advance the current grid cell. |
+ current_x_ += kRegionWidth; |
+ if (current_x_ > max_point_.x()) { |
+ current_y_ += kRegionHeight; |
+ current_x_ = min_point_.x(); |
+ if (current_y_ > max_point_.y()) { |
+ current_pixel_ref_ = NULL; |
+ break; |
+ } |
+ } |
+ |
+ // If there are no pixel refs at this grid cell, keep incrementing. |
+ PixelRefsMap::const_iterator iter = |
+ picture_->lazy_pixel_refs_.find(std::make_pair(current_x_, current_y_)); |
+ if (iter == picture_->lazy_pixel_refs_.end() || iter->second.empty()) |
+ continue; |
+ |
+ // We found a non-empty list: store it and get the first pixel ref. |
+ current_list_ = iter->second; |
+ current_pixel_ref_ = current_list_.front(); |
+ current_list_.pop_front(); |
+ break; |
+ } |
+ return *this; |
+} |
+ |
} // namespace cc |