OLD | NEW |
| (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/picture_pile_base.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "third_party/skia/include/core/SkColor.h" | |
9 #include "ui/gfx/rect_conversions.h" | |
10 | |
11 namespace { | |
12 // Dimensions of the tiles in this picture pile as well as the dimensions of | |
13 // the base picture in each tile. | |
14 const int kBasePictureSize = 3000; | |
15 const int kTileGridBorderPixels = 1; | |
16 } | |
17 | |
18 namespace cc { | |
19 | |
20 PicturePileBase::PicturePileBase() | |
21 : min_contents_scale_(0), | |
22 background_color_(SkColorSetARGBInline(0, 0, 0, 0)), | |
23 slow_down_raster_scale_factor_for_debug_(0), | |
24 num_raster_threads_(0) { | |
25 tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize)); | |
26 tile_grid_info_.fTileInterval.setEmpty(); | |
27 tile_grid_info_.fMargin.setEmpty(); | |
28 tile_grid_info_.fOffset.setZero(); | |
29 } | |
30 | |
31 PicturePileBase::PicturePileBase(const PicturePileBase* other) | |
32 : picture_list_map_(other->picture_list_map_), | |
33 tiling_(other->tiling_), | |
34 recorded_region_(other->recorded_region_), | |
35 min_contents_scale_(other->min_contents_scale_), | |
36 tile_grid_info_(other->tile_grid_info_), | |
37 background_color_(other->background_color_), | |
38 slow_down_raster_scale_factor_for_debug_( | |
39 other->slow_down_raster_scale_factor_for_debug_), | |
40 num_raster_threads_(other->num_raster_threads_) { | |
41 } | |
42 | |
43 PicturePileBase::PicturePileBase( | |
44 const PicturePileBase* other, unsigned thread_index) | |
45 : tiling_(other->tiling_), | |
46 recorded_region_(other->recorded_region_), | |
47 min_contents_scale_(other->min_contents_scale_), | |
48 tile_grid_info_(other->tile_grid_info_), | |
49 background_color_(other->background_color_), | |
50 slow_down_raster_scale_factor_for_debug_( | |
51 other->slow_down_raster_scale_factor_for_debug_), | |
52 num_raster_threads_(other->num_raster_threads_) { | |
53 const PictureListMap& other_pic_list_map = other->picture_list_map_; | |
54 for (PictureListMap::const_iterator map_iter = other_pic_list_map.begin(); | |
55 map_iter != other_pic_list_map.end(); ++map_iter) { | |
56 PictureList& pic_list = picture_list_map_[map_iter->first]; | |
57 const PictureList& other_pic_list = map_iter->second; | |
58 for (PictureList::const_iterator pic_iter = other_pic_list.begin(); | |
59 pic_iter != other_pic_list.end(); ++pic_iter) { | |
60 pic_list.push_back( | |
61 (*pic_iter)->GetCloneForDrawingOnThread(thread_index)); | |
62 } | |
63 } | |
64 } | |
65 | |
66 PicturePileBase::~PicturePileBase() { | |
67 } | |
68 | |
69 void PicturePileBase::Resize(gfx::Size new_size) { | |
70 if (size() == new_size) | |
71 return; | |
72 | |
73 gfx::Size old_size = size(); | |
74 tiling_.SetTotalSize(new_size); | |
75 | |
76 // Find all tiles that contain any pixels outside the new size. | |
77 std::vector<PictureListMapKey> to_erase; | |
78 int min_toss_x = tiling_.FirstBorderTileXIndexFromSrcCoord( | |
79 std::min(old_size.width(), new_size.width())); | |
80 int min_toss_y = tiling_.FirstBorderTileYIndexFromSrcCoord( | |
81 std::min(old_size.height(), new_size.height())); | |
82 for (PictureListMap::iterator iter = picture_list_map_.begin(); | |
83 iter != picture_list_map_.end(); ++iter) { | |
84 if (iter->first.first < min_toss_x && iter->first.second < min_toss_y) | |
85 continue; | |
86 to_erase.push_back(iter->first); | |
87 } | |
88 | |
89 for (size_t i = 0; i < to_erase.size(); ++i) | |
90 picture_list_map_.erase(to_erase[i]); | |
91 } | |
92 | |
93 void PicturePileBase::SetMinContentsScale(float min_contents_scale) { | |
94 DCHECK(min_contents_scale); | |
95 if (min_contents_scale_ == min_contents_scale) | |
96 return; | |
97 | |
98 // Picture contents are played back scaled. When the final contents scale is | |
99 // less than 1 (i.e. low res), then multiple recorded pixels will be used | |
100 // to raster one final pixel. To avoid splitting a final pixel across | |
101 // pictures (which would result in incorrect rasterization due to blending), a | |
102 // buffer margin is added so that any picture can be snapped to integral | |
103 // final pixels. | |
104 // | |
105 // For example, if a 1/4 contents scale is used, then that would be 3 buffer | |
106 // pixels, since that's the minimum number of pixels to add so that resulting | |
107 // content can be snapped to a four pixel aligned grid. | |
108 int buffer_pixels = static_cast<int>(ceil(1 / min_contents_scale) - 1); | |
109 buffer_pixels = std::max(0, buffer_pixels); | |
110 SetBufferPixels(buffer_pixels); | |
111 min_contents_scale_ = min_contents_scale; | |
112 } | |
113 | |
114 void PicturePileBase::SetTileGridSize(const gfx::Size& tile_grid_size) { | |
115 tile_grid_info_.fTileInterval.set( | |
116 tile_grid_size.width() - 2 * kTileGridBorderPixels, | |
117 tile_grid_size.height() - 2 * kTileGridBorderPixels); | |
118 DCHECK_GT(tile_grid_info_.fTileInterval.width(), 0); | |
119 DCHECK_GT(tile_grid_info_.fTileInterval.height(), 0); | |
120 tile_grid_info_.fMargin.set(kTileGridBorderPixels, | |
121 kTileGridBorderPixels); | |
122 // Offset the tile grid coordinate space to take into account the fact | |
123 // that the top-most and left-most tiles do not have top and left borders | |
124 // respectively. | |
125 tile_grid_info_.fOffset.set(-kTileGridBorderPixels, | |
126 -kTileGridBorderPixels); | |
127 } | |
128 | |
129 void PicturePileBase::SetBufferPixels(int new_buffer_pixels) { | |
130 if (new_buffer_pixels == buffer_pixels()) | |
131 return; | |
132 | |
133 Clear(); | |
134 tiling_.SetBorderTexels(new_buffer_pixels); | |
135 } | |
136 | |
137 void PicturePileBase::Clear() { | |
138 picture_list_map_.clear(); | |
139 } | |
140 | |
141 void PicturePileBase::UpdateRecordedRegion() { | |
142 recorded_region_.Clear(); | |
143 for (int x = 0; x < num_tiles_x(); ++x) { | |
144 for (int y = 0; y < num_tiles_y(); ++y) { | |
145 if (!HasRecordingAt(x, y)) | |
146 continue; | |
147 recorded_region_.Union(tile_bounds(x, y)); | |
148 } | |
149 } | |
150 } | |
151 | |
152 bool PicturePileBase::HasRecordingAt(int x, int y) { | |
153 PictureListMap::iterator found = | |
154 picture_list_map_.find(PictureListMapKey(x, y)); | |
155 if (found == picture_list_map_.end()) | |
156 return false; | |
157 DCHECK(!found->second.empty()); | |
158 return true; | |
159 } | |
160 | |
161 bool PicturePileBase::CanRaster(float contents_scale, gfx::Rect content_rect) { | |
162 if (tiling_.total_size().IsEmpty()) | |
163 return false; | |
164 gfx::Rect layer_rect = gfx::ToEnclosingRect( | |
165 gfx::ScaleRect(content_rect, 1.f / contents_scale)); | |
166 layer_rect.Intersect(gfx::Rect(tiling_.total_size())); | |
167 return recorded_region_.Contains(layer_rect); | |
168 } | |
169 | |
170 } // namespace cc | |
OLD | NEW |