OLD | NEW |
1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 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 "cc/base/tiling_data.h" | 5 #include "cc/base/tiling_data.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ui/gfx/geometry/rect.h" | 9 #include "ui/gfx/geometry/rect.h" |
10 #include "ui/gfx/geometry/vector2d.h" | 10 #include "ui/gfx/geometry/vector2d.h" |
11 | 11 |
12 namespace cc { | 12 namespace cc { |
| 13 namespace { |
13 | 14 |
14 static int ComputeNumTiles(int max_texture_size, | 15 int ComputeNumTiles(int max_texture_size, int total_size, int border_texels) { |
15 int total_size, | |
16 int border_texels) { | |
17 if (max_texture_size - 2 * border_texels <= 0) | 16 if (max_texture_size - 2 * border_texels <= 0) |
18 return total_size > 0 && max_texture_size >= total_size ? 1 : 0; | 17 return total_size > 0 && max_texture_size >= total_size ? 1 : 0; |
19 | 18 |
20 int num_tiles = std::max(1, | 19 int num_tiles = std::max(1, |
21 1 + (total_size - 1 - 2 * border_texels) / | 20 1 + (total_size - 1 - 2 * border_texels) / |
22 (max_texture_size - 2 * border_texels)); | 21 (max_texture_size - 2 * border_texels)); |
23 return total_size > 0 ? num_tiles : 0; | 22 return total_size > 0 ? num_tiles : 0; |
24 } | 23 } |
25 | 24 |
| 25 } // namespace |
| 26 |
26 TilingData::TilingData() | 27 TilingData::TilingData() |
27 : border_texels_(0) { | 28 : border_texels_(0) { |
28 RecomputeNumTiles(); | 29 RecomputeNumTiles(); |
29 } | 30 } |
30 | 31 |
31 TilingData::TilingData(const gfx::Size& max_texture_size, | 32 TilingData::TilingData(const gfx::Size& max_texture_size, |
32 const gfx::Size& tiling_size, | 33 const gfx::Size& tiling_size, |
33 bool has_border_texels) | 34 bool has_border_texels) |
34 : max_texture_size_(max_texture_size), | 35 : max_texture_size_(max_texture_size), |
35 tiling_size_(tiling_size), | 36 tiling_size_(tiling_size), |
36 border_texels_(has_border_texels ? 1 : 0) { | 37 border_texels_(has_border_texels ? 1 : 0) { |
37 RecomputeNumTiles(); | 38 RecomputeNumTiles(); |
38 } | 39 } |
39 | 40 |
40 TilingData::TilingData(const gfx::Size& max_texture_size, | 41 TilingData::TilingData(const gfx::Size& max_texture_size, |
41 const gfx::Size& tiling_size, | 42 const gfx::Size& tiling_size, |
42 int border_texels) | 43 int border_texels) |
43 : max_texture_size_(max_texture_size), | 44 : max_texture_size_(max_texture_size), |
44 tiling_size_(tiling_size), | 45 tiling_size_(tiling_size), |
45 border_texels_(border_texels) { | 46 border_texels_(border_texels) { |
46 RecomputeNumTiles(); | 47 RecomputeNumTiles(); |
47 } | 48 } |
48 | 49 |
| 50 TilingData::TilingData(const TilingData& other) = default; |
| 51 |
| 52 TilingData::~TilingData() = default; |
| 53 |
49 void TilingData::SetTilingSize(const gfx::Size& tiling_size) { | 54 void TilingData::SetTilingSize(const gfx::Size& tiling_size) { |
50 tiling_size_ = tiling_size; | 55 tiling_size_ = tiling_size; |
51 RecomputeNumTiles(); | 56 RecomputeNumTiles(); |
52 } | 57 } |
53 | 58 |
54 void TilingData::SetMaxTextureSize(const gfx::Size& max_texture_size) { | 59 void TilingData::SetMaxTextureSize(const gfx::Size& max_texture_size) { |
55 max_texture_size_ = max_texture_size; | 60 max_texture_size_ = max_texture_size; |
56 RecomputeNumTiles(); | 61 RecomputeNumTiles(); |
57 } | 62 } |
58 | 63 |
59 void TilingData::SetHasBorderTexels(bool has_border_texels) { | 64 void TilingData::SetHasBorderTexels(bool has_border_texels) { |
60 border_texels_ = has_border_texels ? 1 : 0; | 65 border_texels_ = has_border_texels ? 1 : 0; |
61 RecomputeNumTiles(); | 66 RecomputeNumTiles(); |
62 } | 67 } |
63 | 68 |
64 void TilingData::SetBorderTexels(int border_texels) { | 69 void TilingData::SetBorderTexels(int border_texels) { |
65 border_texels_ = border_texels; | 70 border_texels_ = border_texels; |
66 RecomputeNumTiles(); | 71 RecomputeNumTiles(); |
67 } | 72 } |
68 | 73 |
69 int TilingData::TileXIndexFromSrcCoord(int src_position) const { | 74 int TilingData::TileXIndexFromSrcCoord(int src_position) const { |
70 if (num_tiles_x_ <= 1) | 75 if (num_tiles_x_ <= 1) |
71 return 0; | 76 return 0; |
72 | 77 |
73 DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); | 78 int x = |
74 int x = (src_position - border_texels_) / | 79 (src_position - border_texels_) / borderless_max_texture_size_.width(); |
75 (max_texture_size_.width() - 2 * border_texels_); | |
76 return std::min(std::max(x, 0), num_tiles_x_ - 1); | 80 return std::min(std::max(x, 0), num_tiles_x_ - 1); |
77 } | 81 } |
78 | 82 |
79 int TilingData::TileYIndexFromSrcCoord(int src_position) const { | 83 int TilingData::TileYIndexFromSrcCoord(int src_position) const { |
80 if (num_tiles_y_ <= 1) | 84 if (num_tiles_y_ <= 1) |
81 return 0; | 85 return 0; |
82 | 86 |
83 DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); | 87 int y = |
84 int y = (src_position - border_texels_) / | 88 (src_position - border_texels_) / borderless_max_texture_size_.height(); |
85 (max_texture_size_.height() - 2 * border_texels_); | |
86 return std::min(std::max(y, 0), num_tiles_y_ - 1); | 89 return std::min(std::max(y, 0), num_tiles_y_ - 1); |
87 } | 90 } |
88 | 91 |
89 int TilingData::FirstBorderTileXIndexFromSrcCoord(int src_position) const { | 92 int TilingData::FirstBorderTileXIndexFromSrcCoord(int src_position) const { |
90 if (num_tiles_x_ <= 1) | 93 if (num_tiles_x_ <= 1) |
91 return 0; | 94 return 0; |
92 | 95 |
93 DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); | 96 int x = (src_position - 2 * border_texels_) / |
94 int inner_tile_size = max_texture_size_.width() - 2 * border_texels_; | 97 borderless_max_texture_size_.width(); |
95 int x = (src_position - 2 * border_texels_) / inner_tile_size; | |
96 return std::min(std::max(x, 0), num_tiles_x_ - 1); | 98 return std::min(std::max(x, 0), num_tiles_x_ - 1); |
97 } | 99 } |
98 | 100 |
99 int TilingData::FirstBorderTileYIndexFromSrcCoord(int src_position) const { | 101 int TilingData::FirstBorderTileYIndexFromSrcCoord(int src_position) const { |
100 if (num_tiles_y_ <= 1) | 102 if (num_tiles_y_ <= 1) |
101 return 0; | 103 return 0; |
102 | 104 |
103 DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); | 105 int y = (src_position - 2 * border_texels_) / |
104 int inner_tile_size = max_texture_size_.height() - 2 * border_texels_; | 106 borderless_max_texture_size_.height(); |
105 int y = (src_position - 2 * border_texels_) / inner_tile_size; | |
106 return std::min(std::max(y, 0), num_tiles_y_ - 1); | 107 return std::min(std::max(y, 0), num_tiles_y_ - 1); |
107 } | 108 } |
108 | 109 |
109 int TilingData::LastBorderTileXIndexFromSrcCoord(int src_position) const { | 110 int TilingData::LastBorderTileXIndexFromSrcCoord(int src_position) const { |
110 if (num_tiles_x_ <= 1) | 111 if (num_tiles_x_ <= 1) |
111 return 0; | 112 return 0; |
112 | 113 |
113 DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); | 114 int x = src_position / borderless_max_texture_size_.width(); |
114 int inner_tile_size = max_texture_size_.width() - 2 * border_texels_; | |
115 int x = src_position / inner_tile_size; | |
116 return std::min(std::max(x, 0), num_tiles_x_ - 1); | 115 return std::min(std::max(x, 0), num_tiles_x_ - 1); |
117 } | 116 } |
118 | 117 |
119 int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const { | 118 int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const { |
120 if (num_tiles_y_ <= 1) | 119 if (num_tiles_y_ <= 1) |
121 return 0; | 120 return 0; |
122 | 121 |
123 DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); | 122 int y = src_position / borderless_max_texture_size_.height(); |
124 int inner_tile_size = max_texture_size_.height() - 2 * border_texels_; | |
125 int y = src_position / inner_tile_size; | |
126 return std::min(std::max(y, 0), num_tiles_y_ - 1); | 123 return std::min(std::max(y, 0), num_tiles_y_ - 1); |
127 } | 124 } |
128 | 125 |
129 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds( | 126 gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds( |
130 const gfx::Rect& rect) const { | 127 const gfx::Rect& rect) const { |
131 if (rect.IsEmpty() || has_empty_bounds()) | 128 if (rect.IsEmpty() || has_empty_bounds()) |
132 return gfx::Rect(); | 129 return gfx::Rect(); |
133 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height()) | 130 if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height()) |
134 return gfx::Rect(); | 131 return gfx::Rect(); |
135 int index_x = TileXIndexFromSrcCoord(rect.x()); | 132 int index_x = TileXIndexFromSrcCoord(rect.x()); |
(...skipping 18 matching lines...) Expand all Loading... |
154 int index_bottom = LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1); | 151 int index_bottom = LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1); |
155 | 152 |
156 gfx::Rect rect_top_left(TileBounds(index_x, index_y)); | 153 gfx::Rect rect_top_left(TileBounds(index_x, index_y)); |
157 gfx::Rect rect_bottom_right(TileBounds(index_right, index_bottom)); | 154 gfx::Rect rect_bottom_right(TileBounds(index_right, index_bottom)); |
158 | 155 |
159 return gfx::UnionRects(rect_top_left, rect_bottom_right); | 156 return gfx::UnionRects(rect_top_left, rect_bottom_right); |
160 } | 157 } |
161 | 158 |
162 gfx::Rect TilingData::TileBounds(int i, int j) const { | 159 gfx::Rect TilingData::TileBounds(int i, int j) const { |
163 AssertTile(i, j); | 160 AssertTile(i, j); |
164 int max_texture_size_x = max_texture_size_.width() - 2 * border_texels_; | |
165 int max_texture_size_y = max_texture_size_.height() - 2 * border_texels_; | |
166 | 161 |
167 int lo_x = max_texture_size_x * i; | 162 int lo_x = borderless_max_texture_size_.width() * i; |
168 if (i != 0) | 163 if (i != 0) |
169 lo_x += border_texels_; | 164 lo_x += border_texels_; |
170 | 165 |
171 int lo_y = max_texture_size_y * j; | 166 int lo_y = borderless_max_texture_size_.height() * j; |
172 if (j != 0) | 167 if (j != 0) |
173 lo_y += border_texels_; | 168 lo_y += border_texels_; |
174 | 169 |
175 int hi_x = max_texture_size_x * (i + 1) + border_texels_; | 170 int hi_x = borderless_max_texture_size_.width() * (i + 1) + border_texels_; |
176 if (i + 1 == num_tiles_x_) | 171 if (i + 1 == num_tiles_x_) |
177 hi_x += border_texels_; | 172 hi_x += border_texels_; |
178 | 173 |
179 int hi_y = max_texture_size_y * (j + 1) + border_texels_; | 174 int hi_y = borderless_max_texture_size_.height() * (j + 1) + border_texels_; |
180 if (j + 1 == num_tiles_y_) | 175 if (j + 1 == num_tiles_y_) |
181 hi_y += border_texels_; | 176 hi_y += border_texels_; |
182 | 177 |
183 hi_x = std::min(hi_x, tiling_size_.width()); | 178 hi_x = std::min(hi_x, tiling_size_.width()); |
184 hi_y = std::min(hi_y, tiling_size_.height()); | 179 hi_y = std::min(hi_y, tiling_size_.height()); |
185 | 180 |
186 int x = lo_x; | 181 int x = lo_x; |
187 int y = lo_y; | 182 int y = lo_y; |
188 int width = hi_x - lo_x; | 183 int width = hi_x - lo_x; |
189 int height = hi_y - lo_y; | 184 int height = hi_y - lo_y; |
190 DCHECK_GE(x, 0); | 185 DCHECK_GE(x, 0); |
191 DCHECK_GE(y, 0); | 186 DCHECK_GE(y, 0); |
192 DCHECK_GE(width, 0); | 187 DCHECK_GE(width, 0); |
193 DCHECK_GE(height, 0); | 188 DCHECK_GE(height, 0); |
194 DCHECK_LE(x, tiling_size_.width()); | 189 DCHECK_LE(x, tiling_size_.width()); |
195 DCHECK_LE(y, tiling_size_.height()); | 190 DCHECK_LE(y, tiling_size_.height()); |
196 return gfx::Rect(x, y, width, height); | 191 return gfx::Rect(x, y, width, height); |
197 } | 192 } |
198 | 193 |
199 gfx::Rect TilingData::TileBoundsWithBorder(int i, int j) const { | 194 gfx::Rect TilingData::TileBoundsWithBorder(int i, int j) const { |
200 AssertTile(i, j); | 195 AssertTile(i, j); |
201 int max_texture_size_x = max_texture_size_.width() - 2 * border_texels_; | |
202 int max_texture_size_y = max_texture_size_.height() - 2 * border_texels_; | |
203 | 196 |
204 int lo_x = max_texture_size_x * i; | 197 int lo_x = borderless_max_texture_size_.width() * i; |
205 int lo_y = max_texture_size_y * j; | 198 int lo_y = borderless_max_texture_size_.height() * j; |
206 | 199 |
207 int hi_x = lo_x + max_texture_size_x + 2 * border_texels_; | 200 int hi_x = lo_x + borderless_max_texture_size_.width() + 2 * border_texels_; |
208 int hi_y = lo_y + max_texture_size_y + 2 * border_texels_; | 201 int hi_y = lo_y + borderless_max_texture_size_.height() + 2 * border_texels_; |
209 | 202 |
210 hi_x = std::min(hi_x, tiling_size_.width()); | 203 hi_x = std::min(hi_x, tiling_size_.width()); |
211 hi_y = std::min(hi_y, tiling_size_.height()); | 204 hi_y = std::min(hi_y, tiling_size_.height()); |
212 | 205 |
213 int x = lo_x; | 206 int x = lo_x; |
214 int y = lo_y; | 207 int y = lo_y; |
215 int width = hi_x - lo_x; | 208 int width = hi_x - lo_x; |
216 int height = hi_y - lo_y; | 209 int height = hi_y - lo_y; |
217 DCHECK_GE(x, 0); | 210 DCHECK_GE(x, 0); |
218 DCHECK_GE(y, 0); | 211 DCHECK_GE(y, 0); |
219 DCHECK_GE(width, 0); | 212 DCHECK_GE(width, 0); |
220 DCHECK_GE(height, 0); | 213 DCHECK_GE(height, 0); |
221 DCHECK_LE(x, tiling_size_.width()); | 214 DCHECK_LE(x, tiling_size_.width()); |
222 DCHECK_LE(y, tiling_size_.height()); | 215 DCHECK_LE(y, tiling_size_.height()); |
223 return gfx::Rect(x, y, width, height); | 216 return gfx::Rect(x, y, width, height); |
224 } | 217 } |
225 | 218 |
226 int TilingData::TilePositionX(int x_index) const { | 219 int TilingData::TilePositionX(int x_index) const { |
227 DCHECK_GE(x_index, 0); | 220 DCHECK_GE(x_index, 0); |
228 DCHECK_LT(x_index, num_tiles_x_); | 221 DCHECK_LT(x_index, num_tiles_x_); |
229 | 222 |
230 int pos = (max_texture_size_.width() - 2 * border_texels_) * x_index; | 223 int pos = (borderless_max_texture_size_.width()) * x_index; |
231 if (x_index != 0) | 224 if (x_index != 0) |
232 pos += border_texels_; | 225 pos += border_texels_; |
233 | 226 |
234 return pos; | 227 return pos; |
235 } | 228 } |
236 | 229 |
237 int TilingData::TilePositionY(int y_index) const { | 230 int TilingData::TilePositionY(int y_index) const { |
238 DCHECK_GE(y_index, 0); | 231 DCHECK_GE(y_index, 0); |
239 DCHECK_LT(y_index, num_tiles_y_); | 232 DCHECK_LT(y_index, num_tiles_y_); |
240 | 233 |
241 int pos = (max_texture_size_.height() - 2 * border_texels_) * y_index; | 234 int pos = (borderless_max_texture_size_.height()) * y_index; |
242 if (y_index != 0) | 235 if (y_index != 0) |
243 pos += border_texels_; | 236 pos += border_texels_; |
244 | 237 |
245 return pos; | 238 return pos; |
246 } | 239 } |
247 | 240 |
248 int TilingData::TileSizeX(int x_index) const { | 241 int TilingData::TileSizeX(int x_index) const { |
249 DCHECK_GE(x_index, 0); | 242 DCHECK_GE(x_index, 0); |
250 DCHECK_LT(x_index, num_tiles_x_); | 243 DCHECK_LT(x_index, num_tiles_x_); |
251 | 244 |
252 if (!x_index && num_tiles_x_ == 1) | 245 if (!x_index && num_tiles_x_ == 1) |
253 return tiling_size_.width(); | 246 return tiling_size_.width(); |
254 if (!x_index && num_tiles_x_ > 1) | 247 if (!x_index && num_tiles_x_ > 1) |
255 return max_texture_size_.width() - border_texels_; | 248 return max_texture_size_.width() - border_texels_; |
256 if (x_index < num_tiles_x_ - 1) | 249 if (x_index < num_tiles_x_ - 1) |
257 return max_texture_size_.width() - 2 * border_texels_; | 250 return borderless_max_texture_size_.width(); |
258 if (x_index == num_tiles_x_ - 1) | 251 if (x_index == num_tiles_x_ - 1) |
259 return tiling_size_.width() - TilePositionX(x_index); | 252 return tiling_size_.width() - TilePositionX(x_index); |
260 | 253 |
261 NOTREACHED(); | 254 NOTREACHED(); |
262 return 0; | 255 return 0; |
263 } | 256 } |
264 | 257 |
265 int TilingData::TileSizeY(int y_index) const { | 258 int TilingData::TileSizeY(int y_index) const { |
266 DCHECK_GE(y_index, 0); | 259 DCHECK_GE(y_index, 0); |
267 DCHECK_LT(y_index, num_tiles_y_); | 260 DCHECK_LT(y_index, num_tiles_y_); |
268 | 261 |
269 if (!y_index && num_tiles_y_ == 1) | 262 if (!y_index && num_tiles_y_ == 1) |
270 return tiling_size_.height(); | 263 return tiling_size_.height(); |
271 if (!y_index && num_tiles_y_ > 1) | 264 if (!y_index && num_tiles_y_ > 1) |
272 return max_texture_size_.height() - border_texels_; | 265 return max_texture_size_.height() - border_texels_; |
273 if (y_index < num_tiles_y_ - 1) | 266 if (y_index < num_tiles_y_ - 1) |
274 return max_texture_size_.height() - 2 * border_texels_; | 267 return borderless_max_texture_size_.height(); |
275 if (y_index == num_tiles_y_ - 1) | 268 if (y_index == num_tiles_y_ - 1) |
276 return tiling_size_.height() - TilePositionY(y_index); | 269 return tiling_size_.height() - TilePositionY(y_index); |
277 | 270 |
278 NOTREACHED(); | 271 NOTREACHED(); |
279 return 0; | 272 return 0; |
280 } | 273 } |
281 | 274 |
282 gfx::Vector2d TilingData::TextureOffset(int x_index, int y_index) const { | 275 gfx::Vector2d TilingData::TextureOffset(int x_index, int y_index) const { |
283 int left = (!x_index || num_tiles_x_ == 1) ? 0 : border_texels_; | 276 int left = (!x_index || num_tiles_x_ == 1) ? 0 : border_texels_; |
284 int top = (!y_index || num_tiles_y_ == 1) ? 0 : border_texels_; | 277 int top = (!y_index || num_tiles_y_ == 1) ? 0 : border_texels_; |
285 | 278 |
286 return gfx::Vector2d(left, top); | 279 return gfx::Vector2d(left, top); |
287 } | 280 } |
288 | 281 |
289 void TilingData::RecomputeNumTiles() { | 282 void TilingData::RecomputeNumTiles() { |
290 num_tiles_x_ = ComputeNumTiles( | 283 num_tiles_x_ = ComputeNumTiles( |
291 max_texture_size_.width(), tiling_size_.width(), border_texels_); | 284 max_texture_size_.width(), tiling_size_.width(), border_texels_); |
292 num_tiles_y_ = ComputeNumTiles( | 285 num_tiles_y_ = ComputeNumTiles( |
293 max_texture_size_.height(), tiling_size_.height(), border_texels_); | 286 max_texture_size_.height(), tiling_size_.height(), border_texels_); |
| 287 |
| 288 borderless_max_texture_size_.set_width(max_texture_size_.width() - |
| 289 2 * border_texels_); |
| 290 borderless_max_texture_size_.set_height(max_texture_size_.height() - |
| 291 2 * border_texels_); |
| 292 DCHECK_GE(borderless_max_texture_size_.width(), 0); |
| 293 DCHECK_GE(borderless_max_texture_size_.height(), 0); |
294 } | 294 } |
295 | 295 |
296 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { | 296 TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) { |
297 } | 297 } |
298 | 298 |
299 TilingData::Iterator::Iterator() { | 299 TilingData::Iterator::Iterator() { |
300 done(); | 300 done(); |
301 } | 301 } |
302 | 302 |
303 TilingData::Iterator::Iterator(const TilingData* tiling_data, | 303 TilingData::Iterator::Iterator(const TilingData* tiling_data, |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 | 858 |
859 // We should always end up in an around rect at some point. | 859 // We should always end up in an around rect at some point. |
860 // Since the direction is now vertical, we have to ensure that we will | 860 // Since the direction is now vertical, we have to ensure that we will |
861 // advance. | 861 // advance. |
862 DCHECK_GE(horizontal_step_count_, 1); | 862 DCHECK_GE(horizontal_step_count_, 1); |
863 DCHECK_GE(vertical_step_count_, 1); | 863 DCHECK_GE(vertical_step_count_, 1); |
864 } | 864 } |
865 } | 865 } |
866 | 866 |
867 } // namespace cc | 867 } // namespace cc |
OLD | NEW |