Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2521)

Unified Diff: cc/picture_pile.cc

Issue 11678003: cc: Fix low-res impl-side painting artifacts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More RectToSkRect, 1/16 default min Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
}

Powered by Google App Engine
This is Rietveld 408576698