OLD | NEW |
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 "cc/picture_layer_tiling.h" | 5 #include "cc/picture_layer_tiling.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "cc/math_util.h" | 10 #include "cc/math_util.h" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 bottom_(-1) { | 183 bottom_(-1) { |
184 } | 184 } |
185 | 185 |
186 PictureLayerTiling::Iterator::Iterator(const PictureLayerTiling* tiling, | 186 PictureLayerTiling::Iterator::Iterator(const PictureLayerTiling* tiling, |
187 float dest_scale, | 187 float dest_scale, |
188 gfx::Rect dest_rect, | 188 gfx::Rect dest_rect, |
189 LayerDeviceAlignment layerDeviceAlignment
) | 189 LayerDeviceAlignment layerDeviceAlignment
) |
190 : tiling_(tiling), | 190 : tiling_(tiling), |
191 dest_rect_(dest_rect), | 191 dest_rect_(dest_rect), |
192 current_tile_(NULL), | 192 current_tile_(NULL), |
193 dest_to_content_scale_x_(0), | 193 dest_to_content_scale_(0), |
194 dest_to_content_scale_y_(0), | |
195 tile_i_(0), | 194 tile_i_(0), |
196 tile_j_(0), | 195 tile_j_(0), |
197 left_(0), | 196 left_(0), |
198 top_(0), | 197 top_(0), |
199 right_(-1), | 198 right_(-1), |
200 bottom_(-1) { | 199 bottom_(-1) { |
201 DCHECK(tiling_); | 200 DCHECK(tiling_); |
202 if (dest_rect_.IsEmpty()) | 201 if (dest_rect_.IsEmpty()) |
203 return; | 202 return; |
204 | 203 |
205 float dest_to_content_scale = tiling_->contents_scale_ / dest_scale; | 204 dest_to_content_scale_ = tiling_->contents_scale_ / dest_scale; |
206 // This is the maximum size that the dest rect can be, given the content size. | 205 // This is the maximum size that the dest rect can be, given the content size. |
207 gfx::Size dest_content_size = gfx::ToCeiledSize(gfx::ScaleSize( | 206 gfx::Size dest_content_size = gfx::ToCeiledSize(gfx::ScaleSize( |
208 tiling_->ContentRect().size(), | 207 tiling_->ContentRect().size(), |
209 1 / dest_to_content_scale, | 208 1 / dest_to_content_scale_, |
210 1 / dest_to_content_scale)); | 209 1 / dest_to_content_scale_)); |
211 | |
212 // The last row/column of texels may not have full rasterization coverage, | |
213 // which can happen if the ceiled content size does not equal the floored | |
214 // content size. These texels will sample outside of the recording to | |
215 // generate their pixels. Use the floored size here to ignore them. | |
216 gfx::Size content_size_floor = gfx::ToFlooredSize(tiling->ContentSizeF()); | |
217 dest_to_content_scale_x_ = content_size_floor.width() / | |
218 static_cast<float>(dest_content_size.width()); | |
219 dest_to_content_scale_y_ = content_size_floor.height() / | |
220 static_cast<float>(dest_content_size.height()); | |
221 | |
222 // It's possible that when drawing a quad with texel:pixel ratio < 1 | |
223 // GL_LINEAR will cause us to blend in invalid texels. | |
224 // We stretch the content a little more to prevent sampling past the | |
225 // middle of the last texel. | |
226 if (layerDeviceAlignment == LayerAlignedToDevice){ | |
227 if (dest_to_content_scale_x_ < 1.0) | |
228 dest_to_content_scale_x_ -= 0.5f / dest_content_size.width(); | |
229 if (dest_to_content_scale_y_ < 1.0) | |
230 dest_to_content_scale_y_ -= 0.5f / dest_content_size.height(); | |
231 } | |
232 else if (layerDeviceAlignment == LayerNotAlignedToDevice) { | |
233 dest_to_content_scale_x_ -= 0.5f / dest_content_size.width(); | |
234 dest_to_content_scale_y_ -= 0.5f / dest_content_size.height(); | |
235 } | |
236 | 210 |
237 gfx::Rect content_rect = | 211 gfx::Rect content_rect = |
238 gfx::ToEnclosingRect(gfx::ScaleRect(dest_rect_, | 212 gfx::ToEnclosingRect(gfx::ScaleRect(dest_rect_, |
239 dest_to_content_scale_x_, | 213 dest_to_content_scale_, |
240 dest_to_content_scale_y_)); | 214 dest_to_content_scale_)); |
241 // IndexFromSrcCoord clamps to valid tile ranges, so it's necessary to | 215 // IndexFromSrcCoord clamps to valid tile ranges, so it's necessary to |
242 // check for non-intersection first. | 216 // check for non-intersection first. |
243 content_rect.Intersect(gfx::Rect(tiling_->tiling_data_.total_size())); | 217 content_rect.Intersect(gfx::Rect(tiling_->tiling_data_.total_size())); |
244 if (content_rect.IsEmpty()) | 218 if (content_rect.IsEmpty()) |
245 return; | 219 return; |
246 | 220 |
247 left_ = tiling_->tiling_data_.TileXIndexFromSrcCoord(content_rect.x()); | 221 left_ = tiling_->tiling_data_.TileXIndexFromSrcCoord(content_rect.x()); |
248 top_ = tiling_->tiling_data_.TileYIndexFromSrcCoord(content_rect.y()); | 222 top_ = tiling_->tiling_data_.TileYIndexFromSrcCoord(content_rect.y()); |
249 right_ = tiling_->tiling_data_.TileXIndexFromSrcCoord( | 223 right_ = tiling_->tiling_data_.TileXIndexFromSrcCoord( |
250 content_rect.right() - 1); | 224 content_rect.right() - 1); |
(...skipping 28 matching lines...) Expand all Loading... |
279 current_tile_ = tiling_->TileAt(tile_i_, tile_j_); | 253 current_tile_ = tiling_->TileAt(tile_i_, tile_j_); |
280 | 254 |
281 // Calculate the current geometry rect. Due to floating point rounding | 255 // Calculate the current geometry rect. Due to floating point rounding |
282 // and ToEnclosingRect, tiles might overlap in destination space on the | 256 // and ToEnclosingRect, tiles might overlap in destination space on the |
283 // edges. | 257 // edges. |
284 gfx::Rect last_geometry_rect = current_geometry_rect_; | 258 gfx::Rect last_geometry_rect = current_geometry_rect_; |
285 | 259 |
286 gfx::Rect content_rect = tiling_->tiling_data_.TileBounds(tile_i_, tile_j_); | 260 gfx::Rect content_rect = tiling_->tiling_data_.TileBounds(tile_i_, tile_j_); |
287 | 261 |
288 current_geometry_rect_ = gfx::ToEnclosingRect( | 262 current_geometry_rect_ = gfx::ToEnclosingRect( |
289 gfx::ScaleRect(content_rect, 1 / dest_to_content_scale_x_, | 263 gfx::ScaleRect(content_rect, 1 / dest_to_content_scale_, |
290 1 / dest_to_content_scale_y_)); | 264 1 / dest_to_content_scale_)); |
291 | 265 |
292 current_geometry_rect_.Intersect(dest_rect_); | 266 current_geometry_rect_.Intersect(dest_rect_); |
293 | 267 |
294 if (first_time) | 268 if (first_time) |
295 return *this; | 269 return *this; |
296 | 270 |
297 // Iteration happens left->right, top->bottom. Running off the bottom-right | 271 // Iteration happens left->right, top->bottom. Running off the bottom-right |
298 // edge is handled by the intersection above with dest_rect_. Here we make | 272 // edge is handled by the intersection above with dest_rect_. Here we make |
299 // sure that the new current geometry rect doesn't overlap with the last. | 273 // sure that the new current geometry rect doesn't overlap with the last. |
300 int min_left; | 274 int min_left; |
(...skipping 28 matching lines...) Expand all Loading... |
329 rect.set_size(tiling_->tiling_data_.max_texture_size()); | 303 rect.set_size(tiling_->tiling_data_.max_texture_size()); |
330 return rect; | 304 return rect; |
331 } | 305 } |
332 | 306 |
333 gfx::RectF PictureLayerTiling::Iterator::texture_rect() const { | 307 gfx::RectF PictureLayerTiling::Iterator::texture_rect() const { |
334 gfx::PointF tex_origin = | 308 gfx::PointF tex_origin = |
335 tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin(); | 309 tiling_->tiling_data_.TileBoundsWithBorder(tile_i_, tile_j_).origin(); |
336 | 310 |
337 // Convert from dest space => content space => texture space. | 311 // Convert from dest space => content space => texture space. |
338 gfx::RectF texture_rect(current_geometry_rect_); | 312 gfx::RectF texture_rect(current_geometry_rect_); |
339 texture_rect.Scale(dest_to_content_scale_x_, | 313 texture_rect.Scale(dest_to_content_scale_, |
340 dest_to_content_scale_y_); | 314 dest_to_content_scale_); |
341 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 315 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |
342 texture_rect.Intersect(tiling_->ContentRect()); | 316 texture_rect.Intersect(tiling_->ContentRect()); |
343 | 317 |
344 return texture_rect; | 318 return texture_rect; |
345 } | 319 } |
346 | 320 |
347 gfx::Size PictureLayerTiling::Iterator::texture_size() const { | 321 gfx::Size PictureLayerTiling::Iterator::texture_size() const { |
348 return tiling_->tiling_data_.max_texture_size(); | 322 return tiling_->tiling_data_.max_texture_size(); |
349 } | 323 } |
350 | 324 |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 (bottom_complete ? 1 : 0); | 720 (bottom_complete ? 1 : 0); |
747 if (num_edges_complete == 4) | 721 if (num_edges_complete == 4) |
748 return working_rect; | 722 return working_rect; |
749 } | 723 } |
750 | 724 |
751 NOTREACHED(); | 725 NOTREACHED(); |
752 return starting_rect; | 726 return starting_rect; |
753 } | 727 } |
754 | 728 |
755 } // namespace cc | 729 } // namespace cc |
OLD | NEW |