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

Side by Side Diff: cc/resources/picture_pile_base.cc

Issue 723343002: Update from https://crrev.com/304121 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « cc/resources/picture_pile_base.h ('k') | cc/resources/picture_pile_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/resources/picture_pile_base.h"
6
7 #include <algorithm>
8 #include <set>
9 #include <vector>
10
11 #include "base/debug/trace_event_argument.h"
12 #include "base/logging.h"
13 #include "base/values.h"
14 #include "cc/debug/traced_value.h"
15 #include "third_party/skia/include/core/SkColor.h"
16 #include "ui/gfx/geometry/rect_conversions.h"
17
18 namespace {
19 // Dimensions of the tiles in this picture pile as well as the dimensions of
20 // the base picture in each tile.
21 const int kBasePictureSize = 512;
22 const int kTileGridBorderPixels = 1;
23 #ifdef NDEBUG
24 const bool kDefaultClearCanvasSetting = false;
25 #else
26 const bool kDefaultClearCanvasSetting = true;
27 #endif
28
29 // Invalidation frequency settings. kInvalidationFrequencyThreshold is a value
30 // between 0 and 1 meaning invalidation frequency between 0% and 100% that
31 // indicates when to stop invalidating offscreen regions.
32 // kFrequentInvalidationDistanceThreshold defines what it means to be
33 // "offscreen" in terms of distance to visible in css pixels.
34 const float kInvalidationFrequencyThreshold = 0.75f;
35 const int kFrequentInvalidationDistanceThreshold = 512;
36
37 } // namespace
38
39 namespace cc {
40
41 PicturePileBase::PicturePileBase()
42 : min_contents_scale_(0),
43 background_color_(SkColorSetARGBInline(0, 0, 0, 0)),
44 slow_down_raster_scale_factor_for_debug_(0),
45 contents_opaque_(false),
46 contents_fill_bounds_completely_(false),
47 show_debug_picture_borders_(false),
48 clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
49 has_any_recordings_(false),
50 is_mask_(false),
51 is_solid_color_(false),
52 solid_color_(SK_ColorTRANSPARENT) {
53 tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize));
54 tile_grid_info_.fTileInterval.setEmpty();
55 tile_grid_info_.fMargin.setEmpty();
56 tile_grid_info_.fOffset.setZero();
57 }
58
59 PicturePileBase::PicturePileBase(const PicturePileBase* other)
60 : picture_map_(other->picture_map_),
61 tiling_(other->tiling_),
62 recorded_viewport_(other->recorded_viewport_),
63 min_contents_scale_(other->min_contents_scale_),
64 tile_grid_info_(other->tile_grid_info_),
65 background_color_(other->background_color_),
66 slow_down_raster_scale_factor_for_debug_(
67 other->slow_down_raster_scale_factor_for_debug_),
68 contents_opaque_(other->contents_opaque_),
69 contents_fill_bounds_completely_(other->contents_fill_bounds_completely_),
70 show_debug_picture_borders_(other->show_debug_picture_borders_),
71 clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
72 has_any_recordings_(other->has_any_recordings_),
73 is_mask_(other->is_mask_),
74 is_solid_color_(other->is_solid_color_),
75 solid_color_(other->solid_color_) {
76 }
77
78 PicturePileBase::~PicturePileBase() {
79 }
80
81 void PicturePileBase::SetMinContentsScale(float min_contents_scale) {
82 DCHECK(min_contents_scale);
83 if (min_contents_scale_ == min_contents_scale)
84 return;
85
86 // Picture contents are played back scaled. When the final contents scale is
87 // less than 1 (i.e. low res), then multiple recorded pixels will be used
88 // to raster one final pixel. To avoid splitting a final pixel across
89 // pictures (which would result in incorrect rasterization due to blending), a
90 // buffer margin is added so that any picture can be snapped to integral
91 // final pixels.
92 //
93 // For example, if a 1/4 contents scale is used, then that would be 3 buffer
94 // pixels, since that's the minimum number of pixels to add so that resulting
95 // content can be snapped to a four pixel aligned grid.
96 int buffer_pixels = static_cast<int>(ceil(1 / min_contents_scale) - 1);
97 buffer_pixels = std::max(0, buffer_pixels);
98 SetBufferPixels(buffer_pixels);
99 min_contents_scale_ = min_contents_scale;
100 }
101
102 // static
103 void PicturePileBase::ComputeTileGridInfo(
104 const gfx::Size& tile_grid_size,
105 SkTileGridFactory::TileGridInfo* info) {
106 DCHECK(info);
107 info->fTileInterval.set(tile_grid_size.width() - 2 * kTileGridBorderPixels,
108 tile_grid_size.height() - 2 * kTileGridBorderPixels);
109 DCHECK_GT(info->fTileInterval.width(), 0);
110 DCHECK_GT(info->fTileInterval.height(), 0);
111 info->fMargin.set(kTileGridBorderPixels, kTileGridBorderPixels);
112 // Offset the tile grid coordinate space to take into account the fact
113 // that the top-most and left-most tiles do not have top and left borders
114 // respectively.
115 info->fOffset.set(-kTileGridBorderPixels, -kTileGridBorderPixels);
116 }
117
118 void PicturePileBase::SetTileGridSize(const gfx::Size& tile_grid_size) {
119 ComputeTileGridInfo(tile_grid_size, &tile_grid_info_);
120 }
121
122 void PicturePileBase::SetBufferPixels(int new_buffer_pixels) {
123 if (new_buffer_pixels == buffer_pixels())
124 return;
125
126 Clear();
127 tiling_.SetBorderTexels(new_buffer_pixels);
128 }
129
130 void PicturePileBase::Clear() {
131 picture_map_.clear();
132 recorded_viewport_ = gfx::Rect();
133 has_any_recordings_ = false;
134 is_solid_color_ = false;
135 }
136
137 bool PicturePileBase::HasRecordingAt(int x, int y) {
138 PictureMap::const_iterator found = picture_map_.find(PictureMapKey(x, y));
139 if (found == picture_map_.end())
140 return false;
141 return !!found->second.GetPicture();
142 }
143
144 bool PicturePileBase::CanRaster(float contents_scale,
145 const gfx::Rect& content_rect) const {
146 if (tiling_.tiling_size().IsEmpty())
147 return false;
148 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect(
149 content_rect, 1.f / contents_scale);
150 layer_rect.Intersect(gfx::Rect(tiling_.tiling_size()));
151
152 // Common case inside of viewport to avoid the slower map lookups.
153 if (recorded_viewport_.Contains(layer_rect)) {
154 // Sanity check that there are no false positives in recorded_viewport_.
155 DCHECK(CanRasterSlowTileCheck(layer_rect));
156 return true;
157 }
158
159 return CanRasterSlowTileCheck(layer_rect);
160 }
161
162 bool PicturePileBase::CanRasterSlowTileCheck(
163 const gfx::Rect& layer_rect) const {
164 bool include_borders = false;
165 for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders);
166 tile_iter;
167 ++tile_iter) {
168 PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index());
169 if (map_iter == picture_map_.end())
170 return false;
171 if (!map_iter->second.GetPicture())
172 return false;
173 }
174 return true;
175 }
176
177 gfx::Rect PicturePileBase::PaddedRect(const PictureMapKey& key) const {
178 gfx::Rect tile = tiling_.TileBounds(key.first, key.second);
179 return PadRect(tile);
180 }
181
182 gfx::Rect PicturePileBase::PadRect(const gfx::Rect& rect) const {
183 gfx::Rect padded_rect = rect;
184 padded_rect.Inset(
185 -buffer_pixels(), -buffer_pixels(), -buffer_pixels(), -buffer_pixels());
186 return padded_rect;
187 }
188
189 void PicturePileBase::AsValueInto(base::debug::TracedValue* pictures) const {
190 gfx::Rect tiling_rect(tiling_.tiling_size());
191 std::set<const void*> appended_pictures;
192 bool include_borders = true;
193 for (TilingData::Iterator tile_iter(&tiling_, tiling_rect, include_borders);
194 tile_iter;
195 ++tile_iter) {
196 PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index());
197 if (map_iter == picture_map_.end())
198 continue;
199
200 const Picture* picture = map_iter->second.GetPicture();
201 if (picture && (appended_pictures.count(picture) == 0)) {
202 appended_pictures.insert(picture);
203 TracedValue::AppendIDRef(picture, pictures);
204 }
205 }
206 }
207
208 PicturePileBase::PictureInfo::PictureInfo() : last_frame_number_(0) {}
209
210 PicturePileBase::PictureInfo::~PictureInfo() {}
211
212 void PicturePileBase::PictureInfo::AdvanceInvalidationHistory(
213 int frame_number) {
214 DCHECK_GE(frame_number, last_frame_number_);
215 if (frame_number == last_frame_number_)
216 return;
217
218 invalidation_history_ <<= (frame_number - last_frame_number_);
219 last_frame_number_ = frame_number;
220 }
221
222 bool PicturePileBase::PictureInfo::Invalidate(int frame_number) {
223 AdvanceInvalidationHistory(frame_number);
224 invalidation_history_.set(0);
225
226 bool did_invalidate = !!picture_.get();
227 picture_ = NULL;
228 return did_invalidate;
229 }
230
231 bool PicturePileBase::PictureInfo::NeedsRecording(int frame_number,
232 int distance_to_visible) {
233 AdvanceInvalidationHistory(frame_number);
234
235 // We only need recording if we don't have a picture. Furthermore, we only
236 // need a recording if we're within frequent invalidation distance threshold
237 // or the invalidation is not frequent enough (below invalidation frequency
238 // threshold).
239 return !picture_.get() &&
240 ((distance_to_visible <= kFrequentInvalidationDistanceThreshold) ||
241 (GetInvalidationFrequency() < kInvalidationFrequencyThreshold));
242 }
243
244 void PicturePileBase::PictureInfo::SetPicture(scoped_refptr<Picture> picture) {
245 picture_ = picture;
246 }
247
248 const Picture* PicturePileBase::PictureInfo::GetPicture() const {
249 return picture_.get();
250 }
251
252 float PicturePileBase::PictureInfo::GetInvalidationFrequency() const {
253 return invalidation_history_.count() /
254 static_cast<float>(INVALIDATION_FRAMES_TRACKED);
255 }
256
257 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_pile_base.h ('k') | cc/resources/picture_pile_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698