Chromium Code Reviews| Index: cc/picture_pile.cc |
| diff --git a/cc/picture_pile.cc b/cc/picture_pile.cc |
| index eab92c66e39ab46a072adca036e55fcfc5a9f8fe..54c191b116c8316eb2c37bb06ca1015fbeaa3d0a 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()) |
| @@ -78,7 +113,7 @@ void PicturePile::InvalidateRect(gfx::Rect invalidation) { |
| } |
| if (picture_rect.size().GetArea() / static_cast<float>(size_.GetArea()) > |
| kResetThreshold) |
| - picture_rect = gfx::Rect(size_); |
| + picture_rect = gfx::Rect(gfx::Rect(size_)); |
|
danakj
2013/01/05 00:04:58
Yo dawg, I heard you like Rects.
enne (OOO)
2013/01/06 03:57:18
Oops.
|
| FullyContainedPredicate pred(picture_rect); |
| pile_.erase(std::remove_if(pile_.begin(), pile_.end(), pred), pile_.end()); |
| @@ -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(); |
| } |