Chromium Code Reviews| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/trace_event/trace_event_argument.h" | 12 #include "base/trace_event/trace_event_argument.h" |
| 13 #include "cc/base/math_util.h" | 13 #include "cc/base/math_util.h" |
| 14 #include "cc/input/main_thread_scrolling_reason.h" | 14 #include "cc/input/main_thread_scrolling_reason.h" |
| 15 #include "cc/input/scroll_state.h" | 15 #include "cc/input/scroll_state.h" |
| 16 #include "cc/layers/layer_impl.h" | 16 #include "cc/layers/layer_impl.h" |
| 17 #include "cc/output/copy_output_request.h" | |
| 17 #include "cc/proto/gfx_conversions.h" | 18 #include "cc/proto/gfx_conversions.h" |
| 18 #include "cc/proto/property_tree.pb.h" | 19 #include "cc/proto/property_tree.pb.h" |
| 19 #include "cc/proto/scroll_offset.pb.h" | 20 #include "cc/proto/scroll_offset.pb.h" |
| 20 #include "cc/proto/synced_property_conversions.h" | 21 #include "cc/proto/synced_property_conversions.h" |
| 21 #include "cc/proto/transform.pb.h" | 22 #include "cc/proto/transform.pb.h" |
| 22 #include "cc/proto/vector2df.pb.h" | 23 #include "cc/proto/vector2df.pb.h" |
| 23 #include "cc/trees/layer_tree_host_common.h" | 24 #include "cc/trees/layer_tree_host_common.h" |
| 24 #include "cc/trees/layer_tree_impl.h" | 25 #include "cc/trees/layer_tree_impl.h" |
| 25 #include "cc/trees/property_tree.h" | 26 #include "cc/trees/property_tree.h" |
| 26 #include "ui/gfx/geometry/vector2d_conversions.h" | 27 #include "ui/gfx/geometry/vector2d_conversions.h" |
| (...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1310 } | 1311 } |
| 1311 | 1312 |
| 1312 DCHECK(nodes_affected_by_outer_viewport_bounds_delta_.empty()); | 1313 DCHECK(nodes_affected_by_outer_viewport_bounds_delta_.empty()); |
| 1313 for (int i = 0; i < data.nodes_affected_by_outer_viewport_bounds_delta_size(); | 1314 for (int i = 0; i < data.nodes_affected_by_outer_viewport_bounds_delta_size(); |
| 1314 ++i) { | 1315 ++i) { |
| 1315 nodes_affected_by_outer_viewport_bounds_delta_.push_back( | 1316 nodes_affected_by_outer_viewport_bounds_delta_.push_back( |
| 1316 data.nodes_affected_by_outer_viewport_bounds_delta(i)); | 1317 data.nodes_affected_by_outer_viewport_bounds_delta(i)); |
| 1317 } | 1318 } |
| 1318 } | 1319 } |
| 1319 | 1320 |
| 1321 EffectTree::EffectTree() {} | |
| 1322 | |
| 1323 EffectTree::~EffectTree() {} | |
| 1324 | |
| 1320 float EffectTree::EffectiveOpacity(const EffectNode* node) const { | 1325 float EffectTree::EffectiveOpacity(const EffectNode* node) const { |
| 1321 return node->data.subtree_hidden ? 0.f : node->data.opacity; | 1326 return node->data.subtree_hidden ? 0.f : node->data.opacity; |
| 1322 } | 1327 } |
| 1323 | 1328 |
| 1324 void EffectTree::UpdateOpacities(EffectNode* node, EffectNode* parent_node) { | 1329 void EffectTree::UpdateOpacities(EffectNode* node, EffectNode* parent_node) { |
| 1325 node->data.screen_space_opacity = EffectiveOpacity(node); | 1330 node->data.screen_space_opacity = EffectiveOpacity(node); |
| 1326 | 1331 |
| 1327 if (parent_node) | 1332 if (parent_node) |
| 1328 node->data.screen_space_opacity *= parent_node->data.screen_space_opacity; | 1333 node->data.screen_space_opacity *= parent_node->data.screen_space_opacity; |
| 1329 } | 1334 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1399 void EffectTree::UpdateEffects(int id) { | 1404 void EffectTree::UpdateEffects(int id) { |
| 1400 EffectNode* node = Node(id); | 1405 EffectNode* node = Node(id); |
| 1401 EffectNode* parent_node = parent(node); | 1406 EffectNode* parent_node = parent(node); |
| 1402 | 1407 |
| 1403 UpdateOpacities(node, parent_node); | 1408 UpdateOpacities(node, parent_node); |
| 1404 UpdateIsDrawn(node, parent_node); | 1409 UpdateIsDrawn(node, parent_node); |
| 1405 UpdateEffectChanged(node, parent_node); | 1410 UpdateEffectChanged(node, parent_node); |
| 1406 UpdateBackfaceVisibility(node, parent_node); | 1411 UpdateBackfaceVisibility(node, parent_node); |
| 1407 } | 1412 } |
| 1408 | 1413 |
| 1414 void EffectTree::AddCopyRequest(int node_id, | |
| 1415 std::unique_ptr<CopyOutputRequest> request) { | |
| 1416 copy_requests_.insert(std::make_pair(node_id, std::move(request))); | |
| 1417 } | |
| 1418 | |
| 1419 void EffectTree::PushCopyRequestsTo(EffectTree* other_tree) { | |
| 1420 // If other_tree still has copy requests, this means there was a commit | |
| 1421 // without a draw. This only happens in some edge cases during lost context or | |
| 1422 // visibility changes, so don't try to handle preserving these output | |
| 1423 // requests. | |
| 1424 if (!other_tree->copy_requests_.empty()) { | |
| 1425 // Destroying these copy requests will abort them. | |
| 1426 other_tree->copy_requests_.clear(); | |
| 1427 } | |
| 1428 | |
| 1429 if (copy_requests_.empty()) | |
| 1430 return; | |
| 1431 | |
| 1432 for (auto& request : copy_requests_) { | |
| 1433 other_tree->copy_requests_.insert( | |
| 1434 std::make_pair(request.first, std::move(request.second))); | |
| 1435 } | |
| 1436 copy_requests_.clear(); | |
| 1437 | |
| 1438 // Property trees need to get rebuilt since effect nodes (and render surfaces) | |
| 1439 // that were created only for the copy requests we just pushed are no longer | |
| 1440 // needed. | |
| 1441 if (property_trees()->is_main_thread) | |
| 1442 property_trees()->needs_rebuild = true; | |
| 1443 } | |
| 1444 | |
| 1445 void EffectTree::TakeCopyRequestsAndTransformToSurface( | |
| 1446 int node_id, | |
| 1447 std::vector<std::unique_ptr<CopyOutputRequest>>* requests) { | |
| 1448 EffectNode* effect_node = Node(node_id); | |
| 1449 DCHECK(effect_node->data.has_render_surface); | |
| 1450 DCHECK(effect_node->data.has_copy_request); | |
| 1451 | |
| 1452 auto range = copy_requests_.equal_range(node_id); | |
| 1453 for (auto it = range.first; it != range.second; ++it) | |
| 1454 requests->push_back(std::move(it->second)); | |
| 1455 copy_requests_.erase(range.first, range.second); | |
| 1456 | |
| 1457 for (auto& it : *requests) { | |
| 1458 if (!it->has_area()) | |
| 1459 continue; | |
| 1460 | |
| 1461 // The area needs to be transformed from the space of content that draws to | |
| 1462 // the surface to the space of the surface itself. | |
|
Ian Vollick
2016/05/31 01:47:12
The comments really help, but this is a bit subtle
ajuma
2016/05/31 14:27:08
I've updated this to call ComputeTransformWithDest
| |
| 1463 gfx::Transform transform; | |
| 1464 if (effect_node->parent_id != -1) { | |
| 1465 // For non-root surfaces, transform by sub-layer scale. | |
| 1466 gfx::Vector2dF sublayer_scale = | |
| 1467 property_trees() | |
| 1468 ->transform_tree.Node(effect_node->data.transform_id) | |
| 1469 ->data.sublayer_scale; | |
| 1470 transform.Scale(sublayer_scale.x(), sublayer_scale.y()); | |
| 1471 } else { | |
| 1472 // The root surface doesn't have the notion of sub-layer scale, but | |
| 1473 // instead has a similar notion of transforming from the space of the root | |
| 1474 // layer to the space of the screen. | |
| 1475 property_trees()->transform_tree.ComputeTransform(1, 0, &transform); | |
| 1476 } | |
| 1477 it->set_area(MathUtil::MapEnclosingClippedRect(transform, it->area())); | |
| 1478 } | |
| 1479 } | |
| 1480 | |
| 1481 bool EffectTree::HasCopyRequests() const { | |
| 1482 return !copy_requests_.empty(); | |
| 1483 } | |
| 1484 | |
| 1409 void EffectTree::ClearCopyRequests() { | 1485 void EffectTree::ClearCopyRequests() { |
| 1410 for (auto& node : nodes()) { | 1486 for (auto& node : nodes()) { |
| 1411 node.data.num_copy_requests_in_subtree = 0; | 1487 node.data.num_copy_requests_in_subtree = 0; |
| 1412 node.data.has_copy_request = false; | 1488 node.data.has_copy_request = false; |
| 1413 } | 1489 } |
| 1490 | |
| 1491 // Any copy requests that are still left will be aborted (sending an empty | |
| 1492 // result) on desruction. | |
| 1493 copy_requests_.clear(); | |
| 1414 set_needs_update(true); | 1494 set_needs_update(true); |
| 1415 } | 1495 } |
| 1416 | 1496 |
| 1417 bool EffectTree::ContributesToDrawnSurface(int id) { | 1497 bool EffectTree::ContributesToDrawnSurface(int id) { |
| 1418 // All drawn nodes contribute to drawn surface. | 1498 // All drawn nodes contribute to drawn surface. |
| 1419 // Exception : Nodes that are hidden and are drawn only for the sake of | 1499 // Exception : Nodes that are hidden and are drawn only for the sake of |
| 1420 // copy requests. | 1500 // copy requests. |
| 1421 EffectNode* node = Node(id); | 1501 EffectNode* node = Node(id); |
| 1422 EffectNode* parent_node = parent(node); | 1502 EffectNode* parent_node = parent(node); |
| 1423 return node->data.is_drawn && (!parent_node || parent_node->data.is_drawn); | 1503 return node->data.is_drawn && (!parent_node || parent_node->data.is_drawn); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1470 | 1550 |
| 1471 void ClipTree::FromProtobuf( | 1551 void ClipTree::FromProtobuf( |
| 1472 const proto::PropertyTree& proto, | 1552 const proto::PropertyTree& proto, |
| 1473 std::unordered_map<int, int>* node_id_to_index_map) { | 1553 std::unordered_map<int, int>* node_id_to_index_map) { |
| 1474 DCHECK(proto.has_property_type()); | 1554 DCHECK(proto.has_property_type()); |
| 1475 DCHECK_EQ(proto.property_type(), proto::PropertyTree::Clip); | 1555 DCHECK_EQ(proto.property_type(), proto::PropertyTree::Clip); |
| 1476 | 1556 |
| 1477 PropertyTree::FromProtobuf(proto, node_id_to_index_map); | 1557 PropertyTree::FromProtobuf(proto, node_id_to_index_map); |
| 1478 } | 1558 } |
| 1479 | 1559 |
| 1560 EffectTree& EffectTree::operator=(const EffectTree& from) { | |
| 1561 PropertyTree::operator=(from); | |
| 1562 // copy_requests_ are omitted here, since these need to be moved rather | |
| 1563 // than copied or assigned. | |
| 1564 return *this; | |
| 1565 } | |
| 1566 | |
| 1480 bool EffectTree::operator==(const EffectTree& other) const { | 1567 bool EffectTree::operator==(const EffectTree& other) const { |
| 1481 return PropertyTree::operator==(other); | 1568 return PropertyTree::operator==(other); |
| 1482 } | 1569 } |
| 1483 | 1570 |
| 1484 void EffectTree::ToProtobuf(proto::PropertyTree* proto) const { | 1571 void EffectTree::ToProtobuf(proto::PropertyTree* proto) const { |
| 1485 DCHECK(!proto->has_property_type()); | 1572 DCHECK(!proto->has_property_type()); |
| 1486 proto->set_property_type(proto::PropertyTree::Effect); | 1573 proto->set_property_type(proto::PropertyTree::Effect); |
| 1487 | 1574 |
| 1488 PropertyTree::ToProtobuf(proto); | 1575 PropertyTree::ToProtobuf(proto); |
| 1489 } | 1576 } |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2139 value->EndDictionary(); | 2226 value->EndDictionary(); |
| 2140 | 2227 |
| 2141 value->BeginDictionary("scroll_tree"); | 2228 value->BeginDictionary("scroll_tree"); |
| 2142 scroll_tree.AsValueInto(value.get()); | 2229 scroll_tree.AsValueInto(value.get()); |
| 2143 value->EndDictionary(); | 2230 value->EndDictionary(); |
| 2144 | 2231 |
| 2145 return value; | 2232 return value; |
| 2146 } | 2233 } |
| 2147 | 2234 |
| 2148 } // namespace cc | 2235 } // namespace cc |
| OLD | NEW |