OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/trees/draw_property_utils.h" | 5 #include "cc/trees/draw_property_utils.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "cc/base/math_util.h" | 9 #include "cc/base/math_util.h" |
10 #include "cc/layers/layer.h" | 10 #include "cc/layers/layer.h" |
| 11 #include "cc/layers/layer_impl.h" |
11 #include "cc/trees/property_tree.h" | 12 #include "cc/trees/property_tree.h" |
12 #include "cc/trees/property_tree_builder.h" | 13 #include "cc/trees/property_tree_builder.h" |
13 #include "ui/gfx/geometry/rect_conversions.h" | 14 #include "ui/gfx/geometry/rect_conversions.h" |
14 | 15 |
15 namespace cc { | 16 namespace cc { |
16 | 17 |
17 namespace { | 18 namespace { |
18 | 19 |
| 20 template <typename LayerType> |
19 void CalculateVisibleRects( | 21 void CalculateVisibleRects( |
20 const std::vector<Layer*>& layers_that_need_visible_rects, | 22 const std::vector<LayerType*>& layers_that_need_visible_rects, |
21 const ClipTree& clip_tree, | 23 const ClipTree& clip_tree, |
22 const TransformTree& transform_tree) { | 24 const TransformTree& transform_tree) { |
23 for (size_t i = 0; i < layers_that_need_visible_rects.size(); ++i) { | 25 for (size_t i = 0; i < layers_that_need_visible_rects.size(); ++i) { |
24 Layer* layer = layers_that_need_visible_rects[i]; | 26 LayerType* layer = layers_that_need_visible_rects[i]; |
25 | 27 |
26 // TODO(ajuma): Compute content_scale rather than using it. Note that for | 28 // TODO(ajuma): Compute content_scale rather than using it. Note that for |
27 // PictureLayer and PictureImageLayers, content_bounds == bounds and | 29 // PictureLayer and PictureImageLayers, content_bounds == bounds and |
28 // content_scale_x == content_scale_y == 1.0, so once impl painting is on | 30 // content_scale_x == content_scale_y == 1.0, so once impl painting is on |
29 // everywhere, this code will be unnecessary. | 31 // everywhere, this code will be unnecessary. |
30 gfx::Size layer_content_bounds = layer->content_bounds(); | 32 gfx::Size layer_content_bounds = layer->content_bounds(); |
31 float contents_scale_x = layer->contents_scale_x(); | 33 float contents_scale_x = layer->contents_scale_x(); |
32 float contents_scale_y = layer->contents_scale_y(); | 34 float contents_scale_y = layer->contents_scale_y(); |
33 const bool has_clip = layer->clip_tree_index() > 0; | 35 const bool has_clip = layer->clip_tree_index() > 0; |
34 const TransformNode* transform_node = | 36 const TransformNode* transform_node = |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 visible_rect.Intersect(gfx::Rect(layer_content_bounds)); | 129 visible_rect.Intersect(gfx::Rect(layer_content_bounds)); |
128 | 130 |
129 layer->set_visible_rect_from_property_trees(visible_rect); | 131 layer->set_visible_rect_from_property_trees(visible_rect); |
130 } else { | 132 } else { |
131 layer->set_visible_rect_from_property_trees( | 133 layer->set_visible_rect_from_property_trees( |
132 gfx::Rect(layer_content_bounds)); | 134 gfx::Rect(layer_content_bounds)); |
133 } | 135 } |
134 } | 136 } |
135 } | 137 } |
136 | 138 |
137 static bool IsRootLayerOfNewRenderingContext(Layer* layer) { | 139 template <typename LayerType> |
| 140 static bool IsRootLayerOfNewRenderingContext(LayerType* layer) { |
138 if (layer->parent()) | 141 if (layer->parent()) |
139 return !layer->parent()->Is3dSorted() && layer->Is3dSorted(); | 142 return !layer->parent()->Is3dSorted() && layer->Is3dSorted(); |
140 return layer->Is3dSorted(); | 143 return layer->Is3dSorted(); |
141 } | 144 } |
142 | 145 |
143 static inline bool LayerIsInExisting3DRenderingContext(Layer* layer) { | 146 template <typename LayerType> |
| 147 static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) { |
144 return layer->Is3dSorted() && layer->parent() && | 148 return layer->Is3dSorted() && layer->parent() && |
145 layer->parent()->Is3dSorted(); | 149 layer->parent()->Is3dSorted(); |
146 } | 150 } |
147 | 151 |
148 static bool TransformToScreenIsKnown(Layer* layer, const TransformTree& tree) { | 152 template <typename LayerType> |
| 153 static bool TransformToScreenIsKnown(LayerType* layer, |
| 154 const TransformTree& tree) { |
149 const TransformNode* node = tree.Node(layer->transform_tree_index()); | 155 const TransformNode* node = tree.Node(layer->transform_tree_index()); |
150 return !node->data.to_screen_is_animated; | 156 return !node->data.to_screen_is_animated; |
151 } | 157 } |
152 | 158 |
153 static bool IsLayerBackFaceExposed(Layer* layer, const TransformTree& tree) { | 159 template <typename LayerType> |
| 160 static bool IsLayerBackFaceExposed(LayerType* layer, |
| 161 const TransformTree& tree) { |
154 if (!TransformToScreenIsKnown(layer, tree)) | 162 if (!TransformToScreenIsKnown(layer, tree)) |
155 return false; | 163 return false; |
156 if (LayerIsInExisting3DRenderingContext(layer)) | 164 if (LayerIsInExisting3DRenderingContext(layer)) |
157 return layer->draw_transform_from_property_trees(tree).IsBackFaceVisible(); | 165 return DrawTransformFromPropertyTrees(layer, tree).IsBackFaceVisible(); |
158 return layer->transform().IsBackFaceVisible(); | 166 return layer->transform().IsBackFaceVisible(); |
159 } | 167 } |
160 | 168 |
161 static bool IsSurfaceBackFaceExposed(Layer* layer, | 169 template <typename LayerType> |
| 170 static bool IsSurfaceBackFaceExposed(LayerType* layer, |
162 const TransformTree& tree) { | 171 const TransformTree& tree) { |
163 if (!TransformToScreenIsKnown(layer, tree)) | 172 if (!TransformToScreenIsKnown(layer, tree)) |
164 return false; | 173 return false; |
165 if (LayerIsInExisting3DRenderingContext(layer)) | 174 if (LayerIsInExisting3DRenderingContext(layer)) |
166 return layer->draw_transform_from_property_trees(tree).IsBackFaceVisible(); | 175 return DrawTransformFromPropertyTrees(layer, tree).IsBackFaceVisible(); |
167 | 176 |
168 if (IsRootLayerOfNewRenderingContext(layer)) | 177 if (IsRootLayerOfNewRenderingContext(layer)) |
169 return layer->transform().IsBackFaceVisible(); | 178 return layer->transform().IsBackFaceVisible(); |
170 | 179 |
171 // If the render_surface is not part of a new or existing rendering context, | 180 // If the render_surface is not part of a new or existing rendering context, |
172 // then the layers that contribute to this surface will decide back-face | 181 // then the layers that contribute to this surface will decide back-face |
173 // visibility for themselves. | 182 // visibility for themselves. |
174 return false; | 183 return false; |
175 } | 184 } |
176 | 185 |
177 static bool HasSingularTransform(Layer* layer, const TransformTree& tree) { | 186 template <typename LayerType> |
| 187 static bool HasSingularTransform(LayerType* layer, const TransformTree& tree) { |
178 const TransformNode* node = tree.Node(layer->transform_tree_index()); | 188 const TransformNode* node = tree.Node(layer->transform_tree_index()); |
179 return !node->data.is_invertible || !node->data.ancestors_are_invertible; | 189 return !node->data.is_invertible || !node->data.ancestors_are_invertible; |
180 } | 190 } |
181 | 191 |
182 static bool IsBackFaceInvisible(Layer* layer, const TransformTree& tree) { | 192 template <typename LayerType> |
183 Layer* backface_test_layer = layer; | 193 static bool IsBackFaceInvisible(LayerType* layer, const TransformTree& tree) { |
| 194 LayerType* backface_test_layer = layer; |
184 if (layer->use_parent_backface_visibility()) { | 195 if (layer->use_parent_backface_visibility()) { |
185 DCHECK(layer->parent()); | 196 DCHECK(layer->parent()); |
186 DCHECK(!layer->parent()->use_parent_backface_visibility()); | 197 DCHECK(!layer->parent()->use_parent_backface_visibility()); |
187 backface_test_layer = layer->parent(); | 198 backface_test_layer = layer->parent(); |
188 } | 199 } |
189 return !backface_test_layer->double_sided() && | 200 return !backface_test_layer->double_sided() && |
190 IsLayerBackFaceExposed(backface_test_layer, tree); | 201 IsLayerBackFaceExposed(backface_test_layer, tree); |
191 } | 202 } |
192 | 203 |
193 static bool IsAnimatingTransformToScreen(Layer* layer, | 204 template <typename LayerType> |
| 205 static bool IsAnimatingTransformToScreen(LayerType* layer, |
194 const TransformTree& tree) { | 206 const TransformTree& tree) { |
195 const TransformNode* node = tree.Node(layer->transform_tree_index()); | 207 const TransformNode* node = tree.Node(layer->transform_tree_index()); |
196 return node->data.to_screen_is_animated; | 208 return node->data.to_screen_is_animated; |
197 } | 209 } |
198 | 210 |
199 static bool IsInvisibleDueToTransform(Layer* layer, const TransformTree& tree) { | 211 template <typename LayerType> |
| 212 static bool IsInvisibleDueToTransform(LayerType* layer, |
| 213 const TransformTree& tree) { |
200 if (IsAnimatingTransformToScreen(layer, tree)) | 214 if (IsAnimatingTransformToScreen(layer, tree)) |
201 return false; | 215 return false; |
202 return HasSingularTransform(layer, tree) || IsBackFaceInvisible(layer, tree); | 216 return HasSingularTransform(layer, tree) || IsBackFaceInvisible(layer, tree); |
203 } | 217 } |
204 | 218 |
205 void FindLayersThatNeedVisibleRects(Layer* layer, | 219 bool LayerIsInvisible(const Layer* layer) { |
| 220 return !layer->opacity() && !layer->OpacityIsAnimating() && |
| 221 !layer->OpacityCanAnimateOnImplThread(); |
| 222 } |
| 223 |
| 224 bool LayerIsInvisible(const LayerImpl* layer) { |
| 225 return !layer->opacity() && !layer->OpacityIsAnimating(); |
| 226 } |
| 227 |
| 228 template <typename LayerType> |
| 229 void FindLayersThatNeedVisibleRects(LayerType* layer, |
206 const TransformTree& tree, | 230 const TransformTree& tree, |
207 bool subtree_is_visible_from_ancestor, | 231 bool subtree_is_visible_from_ancestor, |
208 std::vector<Layer*>* layers_to_update) { | 232 std::vector<LayerType*>* layers_to_update) { |
209 const bool layer_is_invisible = | 233 const bool layer_is_invisible = LayerIsInvisible(layer); |
210 (!layer->opacity() && !layer->OpacityIsAnimating() && | |
211 !layer->OpacityCanAnimateOnImplThread()); | |
212 const bool layer_is_backfacing = | 234 const bool layer_is_backfacing = |
213 (layer->has_render_surface() && !layer->double_sided() && | 235 (layer->has_render_surface() && !layer->double_sided() && |
214 IsSurfaceBackFaceExposed(layer, tree)); | 236 IsSurfaceBackFaceExposed(layer, tree)); |
215 | 237 |
216 const bool subtree_is_invisble = layer_is_invisible || layer_is_backfacing; | 238 const bool subtree_is_invisble = layer_is_invisible || layer_is_backfacing; |
217 if (subtree_is_invisble) | 239 if (subtree_is_invisble) |
218 return; | 240 return; |
219 | 241 |
220 bool layer_is_drawn = | 242 bool layer_is_drawn = |
221 layer->HasCopyRequest() || | 243 layer->HasCopyRequest() || |
222 (subtree_is_visible_from_ancestor && !layer->hide_layer_and_subtree()); | 244 (subtree_is_visible_from_ancestor && !layer->hide_layer_and_subtree()); |
223 | 245 |
224 if (layer_is_drawn && layer->DrawsContent()) { | 246 if (layer_is_drawn && layer->DrawsContent()) { |
225 const bool visible = !IsInvisibleDueToTransform(layer, tree); | 247 const bool visible = !IsInvisibleDueToTransform(layer, tree); |
226 if (visible) | 248 if (visible) |
227 layers_to_update->push_back(layer); | 249 layers_to_update->push_back(layer); |
228 } | 250 } |
229 | 251 |
230 for (size_t i = 0; i < layer->children().size(); ++i) { | 252 for (size_t i = 0; i < layer->children().size(); ++i) { |
231 FindLayersThatNeedVisibleRects(layer->children()[i].get(), | 253 FindLayersThatNeedVisibleRects(layer->child_at(i), tree, layer_is_drawn, |
232 tree, | |
233 layer_is_drawn, | |
234 layers_to_update); | 254 layers_to_update); |
235 } | 255 } |
236 } | 256 } |
237 | 257 |
238 } // namespace | 258 } // namespace |
239 | 259 |
240 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { | 260 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) { |
241 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { | 261 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) { |
242 ClipNode* clip_node = clip_tree->Node(i); | 262 ClipNode* clip_node = clip_tree->Node(i); |
243 | 263 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 339 |
320 clip_node->data.combined_clip.Intersect(clip_node->data.clip); | 340 clip_node->data.combined_clip.Intersect(clip_node->data.clip); |
321 } | 341 } |
322 } | 342 } |
323 | 343 |
324 void ComputeTransforms(TransformTree* transform_tree) { | 344 void ComputeTransforms(TransformTree* transform_tree) { |
325 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) | 345 for (int i = 1; i < static_cast<int>(transform_tree->size()); ++i) |
326 transform_tree->UpdateTransforms(i); | 346 transform_tree->UpdateTransforms(i); |
327 } | 347 } |
328 | 348 |
329 void ComputeVisibleRectsUsingPropertyTrees( | 349 template <typename LayerType> |
| 350 void ComputeVisibleRectsUsingPropertyTreesInternal( |
| 351 LayerType* root_layer, |
| 352 PropertyTrees* property_trees) { |
| 353 ComputeTransforms(&property_trees->transform_tree); |
| 354 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree); |
| 355 |
| 356 std::vector<LayerType*> layers_to_update; |
| 357 const bool subtree_is_visible_from_ancestor = true; |
| 358 FindLayersThatNeedVisibleRects(root_layer, property_trees->transform_tree, |
| 359 subtree_is_visible_from_ancestor, |
| 360 &layers_to_update); |
| 361 CalculateVisibleRects(layers_to_update, property_trees->clip_tree, |
| 362 property_trees->transform_tree); |
| 363 } |
| 364 |
| 365 void BuildPropertyTreesAndComputeVisibleRects( |
330 Layer* root_layer, | 366 Layer* root_layer, |
331 const Layer* page_scale_layer, | 367 const Layer* page_scale_layer, |
332 float page_scale_factor, | 368 float page_scale_factor, |
333 float device_scale_factor, | 369 float device_scale_factor, |
334 const gfx::Rect& viewport, | 370 const gfx::Rect& viewport, |
335 const gfx::Transform& device_transform, | 371 const gfx::Transform& device_transform, |
336 PropertyTrees* property_trees) { | 372 PropertyTrees* property_trees) { |
337 PropertyTreeBuilder::BuildPropertyTrees( | 373 PropertyTreeBuilder::BuildPropertyTrees( |
338 root_layer, page_scale_layer, page_scale_factor, device_scale_factor, | 374 root_layer, page_scale_layer, page_scale_factor, device_scale_factor, |
339 viewport, device_transform, property_trees); | 375 viewport, device_transform, property_trees); |
340 ComputeTransforms(&property_trees->transform_tree); | 376 ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees); |
341 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree); | 377 } |
342 | 378 |
343 std::vector<Layer*> layers_to_update; | 379 void BuildPropertyTreesAndComputeVisibleRects( |
344 const bool subtree_is_visible_from_ancestor = true; | 380 LayerImpl* root_layer, |
345 FindLayersThatNeedVisibleRects(root_layer, property_trees->transform_tree, | 381 const LayerImpl* page_scale_layer, |
346 subtree_is_visible_from_ancestor, | 382 float page_scale_factor, |
347 &layers_to_update); | 383 float device_scale_factor, |
348 CalculateVisibleRects(layers_to_update, property_trees->clip_tree, | 384 const gfx::Rect& viewport, |
349 property_trees->transform_tree); | 385 const gfx::Transform& device_transform, |
| 386 PropertyTrees* property_trees) { |
| 387 PropertyTreeBuilder::BuildPropertyTrees( |
| 388 root_layer, page_scale_layer, page_scale_factor, device_scale_factor, |
| 389 viewport, device_transform, property_trees); |
| 390 ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees); |
| 391 } |
| 392 |
| 393 void ComputeVisibleRectsUsingPropertyTrees(Layer* root_layer, |
| 394 PropertyTrees* property_trees) { |
| 395 ComputeVisibleRectsUsingPropertyTreesInternal(root_layer, property_trees); |
| 396 } |
| 397 |
| 398 void ComputeVisibleRectsUsingPropertyTrees(LayerImpl* root_layer, |
| 399 PropertyTrees* property_trees) { |
| 400 ComputeVisibleRectsUsingPropertyTreesInternal(root_layer, property_trees); |
| 401 } |
| 402 |
| 403 template <typename LayerType> |
| 404 gfx::Transform DrawTransformFromPropertyTreesInternal( |
| 405 const LayerType* layer, |
| 406 const TransformTree& tree) { |
| 407 const TransformNode* node = tree.Node(layer->transform_tree_index()); |
| 408 // TODO(vollick): ultimately we'll need to find this information (whether or |
| 409 // not we establish a render surface) somewhere other than the layer. |
| 410 const TransformNode* target_node = |
| 411 layer->render_surface() ? node : tree.Node(node->data.content_target_id); |
| 412 |
| 413 gfx::Transform xform; |
| 414 const bool owns_non_root_surface = layer->parent() && layer->render_surface(); |
| 415 if (!owns_non_root_surface) { |
| 416 // If you're not the root, or you don't own a surface, you need to apply |
| 417 // your local offset. |
| 418 xform = node->data.to_target; |
| 419 if (layer->should_flatten_transform_from_property_tree()) |
| 420 xform.FlattenTo2d(); |
| 421 xform.Translate(layer->offset_to_transform_parent().x(), |
| 422 layer->offset_to_transform_parent().y()); |
| 423 // A fixed-position layer does not necessarily have the same render target |
| 424 // as its transform node. In particular, its transform node may be an |
| 425 // ancestor of its render target's transform node. For example, given layer |
| 426 // tree R->S->F, suppose F is fixed and S owns a render surface (e.g., say S |
| 427 // has opacity 0.9 and both S and F draw content). Then F's transform node |
| 428 // is the root node, so the target space transform from that node is defined |
| 429 // with respect to the root render surface. But F will render to S's |
| 430 // surface, so must apply a change of basis transform to the target space |
| 431 // transform from its transform node. |
| 432 if (layer->position_constraint().is_fixed_position()) { |
| 433 gfx::Transform tree_target_to_render_target; |
| 434 tree.ComputeTransform(node->data.content_target_id, |
| 435 layer->render_target()->transform_tree_index(), |
| 436 &tree_target_to_render_target); |
| 437 xform.ConcatTransform(tree_target_to_render_target); |
| 438 } |
| 439 } else { |
| 440 // Surfaces need to apply their sublayer scale. |
| 441 xform.Scale(target_node->data.sublayer_scale.x(), |
| 442 target_node->data.sublayer_scale.y()); |
| 443 } |
| 444 xform.Scale(1.0 / layer->contents_scale_x(), 1.0 / layer->contents_scale_y()); |
| 445 return xform; |
| 446 } |
| 447 |
| 448 gfx::Transform DrawTransformFromPropertyTrees(const Layer* layer, |
| 449 const TransformTree& tree) { |
| 450 return DrawTransformFromPropertyTreesInternal(layer, tree); |
| 451 } |
| 452 |
| 453 gfx::Transform DrawTransformFromPropertyTrees(const LayerImpl* layer, |
| 454 const TransformTree& tree) { |
| 455 return DrawTransformFromPropertyTreesInternal(layer, tree); |
| 456 } |
| 457 |
| 458 template <typename LayerType> |
| 459 gfx::Transform ScreenSpaceTransformFromPropertyTreesInternal( |
| 460 LayerType* layer, |
| 461 const TransformTree& tree) { |
| 462 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), |
| 463 layer->offset_to_transform_parent().y()); |
| 464 if (layer->transform_tree_index() >= 0) { |
| 465 gfx::Transform ssxform = |
| 466 tree.Node(layer->transform_tree_index())->data.to_screen; |
| 467 xform.ConcatTransform(ssxform); |
| 468 if (layer->should_flatten_transform_from_property_tree()) |
| 469 xform.FlattenTo2d(); |
| 470 } |
| 471 xform.Scale(1.0 / layer->contents_scale_x(), 1.0 / layer->contents_scale_y()); |
| 472 return xform; |
| 473 } |
| 474 |
| 475 gfx::Transform ScreenSpaceTransformFromPropertyTrees( |
| 476 const Layer* layer, |
| 477 const TransformTree& tree) { |
| 478 return ScreenSpaceTransformFromPropertyTreesInternal(layer, tree); |
| 479 } |
| 480 |
| 481 gfx::Transform ScreenSpaceTransformFromPropertyTrees( |
| 482 const LayerImpl* layer, |
| 483 const TransformTree& tree) { |
| 484 return ScreenSpaceTransformFromPropertyTreesInternal(layer, tree); |
| 485 } |
| 486 |
| 487 template <typename LayerType> |
| 488 float DrawOpacityFromPropertyTreesInternal(LayerType layer, |
| 489 const OpacityTree& tree) { |
| 490 if (!layer->render_target()) |
| 491 return 0.f; |
| 492 |
| 493 const OpacityNode* target_node = |
| 494 tree.Node(layer->render_target()->opacity_tree_index()); |
| 495 const OpacityNode* node = tree.Node(layer->opacity_tree_index()); |
| 496 if (node == target_node) |
| 497 return 1.f; |
| 498 |
| 499 float draw_opacity = 1.f; |
| 500 while (node != target_node) { |
| 501 draw_opacity *= node->data; |
| 502 node = tree.parent(node); |
| 503 } |
| 504 return draw_opacity; |
| 505 } |
| 506 |
| 507 float DrawOpacityFromPropertyTrees(const Layer* layer, |
| 508 const OpacityTree& tree) { |
| 509 return DrawOpacityFromPropertyTreesInternal(layer, tree); |
| 510 } |
| 511 |
| 512 float DrawOpacityFromPropertyTrees(const LayerImpl* layer, |
| 513 const OpacityTree& tree) { |
| 514 return DrawOpacityFromPropertyTreesInternal(layer, tree); |
350 } | 515 } |
351 | 516 |
352 } // namespace cc | 517 } // namespace cc |
OLD | NEW |