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

Side by Side 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 7 years, 12 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <algorithm> 5 #include <algorithm>
6 6
7 #include "cc/picture_pile.h" 7 #include "cc/picture_pile.h"
8 #include "cc/picture_pile_impl.h" 8 #include "cc/picture_pile_impl.h"
9 9
10 namespace { 10 namespace {
11 // Maximum number of pictures that can overlap before we collapse them into 11 // Maximum number of pictures that can overlap before we collapse them into
12 // a larger one. 12 // a larger one.
13 const int kMaxOverlapping = 2; 13 const int kMaxOverlapping = 2;
14 // Maximum percentage area of the base picture another picture in the pile 14 // Maximum percentage area of the base picture another picture in the pile
15 // can be. If higher, we destroy the pile and recreate from scratch. 15 // can be. If higher, we destroy the pile and recreate from scratch.
16 const float kResetThreshold = 0.7f; 16 const float kResetThreshold = 0.7f;
17 } 17 }
18 18
19 namespace cc { 19 namespace cc {
20 20
21 PicturePile::PicturePile() { 21 PicturePile::PicturePile()
22 : min_contents_scale_(0),
23 buffer_pixels_(0) {
24 SetMinContentsScale(1);
22 } 25 }
23 26
24 PicturePile::~PicturePile() { 27 PicturePile::~PicturePile() {
25 } 28 }
26 29
27 void PicturePile::Resize(gfx::Size size) { 30 void PicturePile::Resize(gfx::Size size) {
28 if (size_ == size) 31 if (size_ == size)
29 return; 32 return;
30 33
31 pile_.clear(); 34 pile_.clear();
32 size_ = size; 35 size_ = size;
33 } 36 }
34 37
38 void PicturePile::SetMinContentsScale(float min_contents_scale) {
39 DCHECK(min_contents_scale);
40 if (min_contents_scale_ == min_contents_scale)
41 return;
42
43 pile_.clear();
44 min_contents_scale_ = min_contents_scale;
45
46 // Picture contents are played back scaled. When the final contents scale is
47 // less than 1 (i.e. low res), then multiple recorded pixels will be used
48 // to raster one final pixel. To avoid splitting a final pixel across
49 // pictures (which would result in incorrect rasterization due to blending), a
50 // buffer margin is added so that any picture can be snapped to integral
51 // final pixels.
52 //
53 // For example, if a 1/4 contents scale is used, then that would be 3 buffer
54 // pixels, since that's the minimum number of pixels to add so that resulting
55 // content can be snapped to a four pixel aligned grid.
56 buffer_pixels_ = static_cast<int>(ceil(1 / min_contents_scale_) - 1);
57 buffer_pixels_ = std::max(0, buffer_pixels_);
58 }
59
35 void PicturePile::Update( 60 void PicturePile::Update(
36 ContentLayerClient* painter, 61 ContentLayerClient* painter,
37 const Region& invalidation, 62 const Region& invalidation,
38 RenderingStats& stats) { 63 RenderingStats& stats) {
39 if (pile_.empty()) { 64 if (pile_.empty()) {
40 ResetPile(painter, stats); 65 ResetPile(painter, stats);
41 return; 66 return;
42 } 67 }
43 68
44 for (Region::Iterator i(invalidation); i.has_rect(); i.next()) 69 for (Region::Iterator i(invalidation); i.has_rect(); i.next())
(...skipping 11 matching lines...) Expand all
56 bool operator()(const scoped_refptr<Picture>& picture) { 81 bool operator()(const scoped_refptr<Picture>& picture) {
57 return layer_rect_.Contains(picture->LayerRect()); 82 return layer_rect_.Contains(picture->LayerRect());
58 } 83 }
59 gfx::Rect layer_rect_; 84 gfx::Rect layer_rect_;
60 }; 85 };
61 86
62 void PicturePile::InvalidateRect(gfx::Rect invalidation) { 87 void PicturePile::InvalidateRect(gfx::Rect invalidation) {
63 if (invalidation.IsEmpty()) 88 if (invalidation.IsEmpty())
64 return; 89 return;
65 90
91 // Inflate all recordings from invalidations with a margin so that when
92 // scaled down to at least min_contents_scale, any final pixel touched by an
93 // invalidation can be fully rasterized by this picture.
94 invalidation.Inset(
95 -buffer_pixels_,
96 -buffer_pixels_,
97 -buffer_pixels_,
98 -buffer_pixels_);
99 invalidation.Intersect(gfx::Rect(size_));
100
66 std::vector<Pile::iterator> overlaps; 101 std::vector<Pile::iterator> overlaps;
67 for (Pile::iterator i = pile_.begin(); i != pile_.end(); ++i) { 102 for (Pile::iterator i = pile_.begin(); i != pile_.end(); ++i) {
68 if ((*i)->LayerRect().Contains(invalidation) && !(*i)->HasRecording()) 103 if ((*i)->LayerRect().Contains(invalidation) && !(*i)->HasRecording())
69 return; 104 return;
70 if ((*i)->LayerRect().Intersects(invalidation) && i != pile_.begin()) 105 if ((*i)->LayerRect().Intersects(invalidation) && i != pile_.begin())
71 overlaps.push_back(i); 106 overlaps.push_back(i);
72 } 107 }
73 108
74 gfx::Rect picture_rect = invalidation; 109 gfx::Rect picture_rect = invalidation;
75 if (overlaps.size() >= kMaxOverlapping) { 110 if (overlaps.size() >= kMaxOverlapping) {
76 for (size_t j = 0; j < overlaps.size(); j++) 111 for (size_t j = 0; j < overlaps.size(); j++)
77 picture_rect = gfx::UnionRects(picture_rect, (*overlaps[j])->LayerRect()); 112 picture_rect = gfx::UnionRects(picture_rect, (*overlaps[j])->LayerRect());
78 } 113 }
79 if (picture_rect.size().GetArea() / static_cast<float>(size_.GetArea()) > 114 if (picture_rect.size().GetArea() / static_cast<float>(size_.GetArea()) >
80 kResetThreshold) 115 kResetThreshold)
81 picture_rect = gfx::Rect(size_); 116 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.
82 117
83 FullyContainedPredicate pred(picture_rect); 118 FullyContainedPredicate pred(picture_rect);
84 pile_.erase(std::remove_if(pile_.begin(), pile_.end(), pred), pile_.end()); 119 pile_.erase(std::remove_if(pile_.begin(), pile_.end(), pred), pile_.end());
85 120
86 pile_.push_back(Picture::Create(picture_rect)); 121 pile_.push_back(Picture::Create(picture_rect));
87 } 122 }
88 123
89 124
90 void PicturePile::ResetPile(ContentLayerClient* painter, 125 void PicturePile::ResetPile(ContentLayerClient* painter,
91 RenderingStats& stats) { 126 RenderingStats& stats) {
92 pile_.clear(); 127 pile_.clear();
93 128
94 scoped_refptr<Picture> base_picture = Picture::Create(gfx::Rect(size_)); 129 scoped_refptr<Picture> base_picture = Picture::Create(gfx::Rect(size_));
95 base_picture->Record(painter, stats); 130 base_picture->Record(painter, stats);
96 pile_.push_back(base_picture); 131 pile_.push_back(base_picture);
97 } 132 }
98 133
99 void PicturePile::PushPropertiesTo(PicturePileImpl* other) { 134 void PicturePile::PushPropertiesTo(PicturePileImpl* other) {
100 other->pile_ = pile_; 135 other->pile_ = pile_;
136 other->min_contents_scale_ = min_contents_scale_;
101 // Remove all old clones. 137 // Remove all old clones.
102 other->clones_.clear(); 138 other->clones_.clear();
103 } 139 }
104 140
105 } // namespace cc 141 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698