Index: cc/picture_pile.cc |
diff --git a/cc/picture_pile.cc b/cc/picture_pile.cc |
index eab92c66e39ab46a072adca036e55fcfc5a9f8fe..565c6c2d8eb14a9b09b64dfb82208b3ed6c4b986 100644 |
--- a/cc/picture_pile.cc |
+++ b/cc/picture_pile.cc |
@@ -18,7 +18,10 @@ const float kResetThreshold = 0.7f; |
namespace cc { |
-PicturePile::PicturePile() { |
+PicturePile::PicturePile() |
+ : min_contents_scale_(0), |
+ buffer_pixels_(0) { |
+ SetMinContentsScale(1); |
} |
PicturePile::~PicturePile() { |
@@ -32,6 +35,28 @@ void PicturePile::Resize(gfx::Size size) { |
size_ = size; |
} |
+void PicturePile::SetMinContentsScale(float min_contents_scale) { |
+ DCHECK(min_contents_scale); |
+ if (min_contents_scale_ == min_contents_scale) |
+ return; |
+ |
+ pile_.clear(); |
+ min_contents_scale_ = min_contents_scale; |
+ |
+ // Picture contents are played back scaled. When the final contents scale is |
+ // less than 1 (i.e. low res), then multiple recorded pixels will be used |
+ // to raster one final pixel. To avoid splitting a final pixel across |
+ // pictures (which would result in incorrect rasterization due to blending), a |
+ // buffer margin is added so that any picture can be snapped to integral |
+ // final pixels. |
+ // |
+ // For example, if a 1/4 contents scale is used, then that would be 3 buffer |
+ // pixels, since that's the minimum number of pixels to add so that resulting |
+ // content can be snapped to a four pixel aligned grid. |
+ buffer_pixels_ = static_cast<int>(ceil(1 / min_contents_scale_) - 1); |
+ buffer_pixels_ = std::max(0, buffer_pixels_); |
+} |
+ |
void PicturePile::Update( |
ContentLayerClient* painter, |
const Region& invalidation, |
@@ -63,6 +88,16 @@ void PicturePile::InvalidateRect(gfx::Rect invalidation) { |
if (invalidation.IsEmpty()) |
return; |
+ // Inflate all recordings from invalidations with a margin so that when |
+ // scaled down to at least min_contents_scale, any final pixel touched by an |
+ // invalidation can be fully rasterized by this picture. |
+ invalidation.Inset( |
+ -buffer_pixels_, |
+ -buffer_pixels_, |
+ -buffer_pixels_, |
+ -buffer_pixels_); |
+ invalidation.Intersect(gfx::Rect(size_)); |
+ |
std::vector<Pile::iterator> overlaps; |
for (Pile::iterator i = pile_.begin(); i != pile_.end(); ++i) { |
if ((*i)->LayerRect().Contains(invalidation) && !(*i)->HasRecording()) |
@@ -98,6 +133,7 @@ void PicturePile::ResetPile(ContentLayerClient* painter, |
void PicturePile::PushPropertiesTo(PicturePileImpl* other) { |
other->pile_ = pile_; |
+ other->min_contents_scale_ = min_contents_scale_; |
// Remove all old clones. |
other->clones_.clear(); |
} |