| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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/layer_tree_host.h" | 5 #include "cc/trees/layer_tree_host.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <stack> | 8 #include <stack> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 164 } |
| 165 | 165 |
| 166 if (root_layer_.get()) { | 166 if (root_layer_.get()) { |
| 167 // The layer tree must be destroyed before the layer tree host. We've | 167 // The layer tree must be destroyed before the layer tree host. We've |
| 168 // made a contract with our animation controllers that the registrar | 168 // made a contract with our animation controllers that the registrar |
| 169 // will outlive them, and we must make good. | 169 // will outlive them, and we must make good. |
| 170 root_layer_ = NULL; | 170 root_layer_ = NULL; |
| 171 } | 171 } |
| 172 } | 172 } |
| 173 | 173 |
| 174 namespace { |
| 175 |
| 176 void FindLayerByIdRecursive(const Layer* layer, |
| 177 const int id, |
| 178 const Layer*& found_layer) { |
| 179 DCHECK(layer); |
| 180 |
| 181 if (layer->id() == id) |
| 182 found_layer = layer; |
| 183 |
| 184 for (LayerList::const_iterator it = layer->children().begin(); |
| 185 !found_layer && it != layer->children().end(); |
| 186 ++it) |
| 187 FindLayerByIdRecursive(it->get(), id, found_layer); |
| 188 } |
| 189 |
| 190 } // anonymous namespace |
| 191 |
| 192 const Layer* LayerTreeHost::LayerById(const int id) const { |
| 193 const Layer* root_layer = root_layer_.get(); |
| 194 if (id == Layer::INVALID_ID || !root_layer) |
| 195 return NULL; |
| 196 |
| 197 const Layer* found_layer = NULL; |
| 198 FindLayerByIdRecursive(root_layer, id, found_layer); |
| 199 |
| 200 return found_layer; |
| 201 } |
| 202 |
| 174 void LayerTreeHost::SetLayerTreeHostClientReady() { | 203 void LayerTreeHost::SetLayerTreeHostClientReady() { |
| 175 proxy_->SetLayerTreeHostClientReady(); | 204 proxy_->SetLayerTreeHostClientReady(); |
| 176 } | 205 } |
| 177 | 206 |
| 178 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) { | 207 static void LayerTreeHostOnOutputSurfaceCreatedCallback(Layer* layer) { |
| 179 layer->OnOutputSurfaceCreated(); | 208 layer->OnOutputSurfaceCreated(); |
| 180 } | 209 } |
| 181 | 210 |
| 182 LayerTreeHost::CreateResult | 211 LayerTreeHost::CreateResult |
| 183 LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) { | 212 LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree( | 360 LayerImpl* hud_impl = LayerTreeHostCommon::FindLayerInSubtree( |
| 332 sync_tree->root_layer(), hud_layer_->id()); | 361 sync_tree->root_layer(), hud_layer_->id()); |
| 333 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl)); | 362 sync_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl)); |
| 334 } else { | 363 } else { |
| 335 sync_tree->set_hud_layer(NULL); | 364 sync_tree->set_hud_layer(NULL); |
| 336 } | 365 } |
| 337 | 366 |
| 338 sync_tree->set_background_color(background_color_); | 367 sync_tree->set_background_color(background_color_); |
| 339 sync_tree->set_has_transparent_background(has_transparent_background_); | 368 sync_tree->set_has_transparent_background(has_transparent_background_); |
| 340 | 369 |
| 341 sync_tree->FindRootScrollLayer(); | 370 if (page_scale_layer_ && inner_viewport_scroll_layer_) { |
| 342 | |
| 343 // TODO(wjmaclean) For now, not all LTH clients will register viewports, so | |
| 344 // only set them when available.. | |
| 345 if (page_scale_layer_) { | |
| 346 DCHECK(inner_viewport_scroll_layer_); | |
| 347 sync_tree->SetViewportLayersFromIds( | 371 sync_tree->SetViewportLayersFromIds( |
| 348 page_scale_layer_->id(), | 372 page_scale_layer_->id(), |
| 349 inner_viewport_scroll_layer_->id(), | 373 inner_viewport_scroll_layer_->id(), |
| 350 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id() | 374 outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id() |
| 351 : Layer::INVALID_ID); | 375 : Layer::INVALID_ID); |
| 352 } else { | 376 } else { |
| 353 sync_tree->ClearViewportLayers(); | 377 sync_tree->ClearViewportLayers(); |
| 354 } | 378 } |
| 355 | 379 |
| 356 float page_scale_delta, sent_page_scale_delta; | 380 float page_scale_delta, sent_page_scale_delta; |
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 | 1062 |
| 1039 in_paint_layer_contents_ = false; | 1063 in_paint_layer_contents_ = false; |
| 1040 | 1064 |
| 1041 occlusion_tracker.overdraw_metrics()->RecordMetrics(this); | 1065 occlusion_tracker.overdraw_metrics()->RecordMetrics(this); |
| 1042 } | 1066 } |
| 1043 | 1067 |
| 1044 void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) { | 1068 void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) { |
| 1045 if (!root_layer_.get()) | 1069 if (!root_layer_.get()) |
| 1046 return; | 1070 return; |
| 1047 | 1071 |
| 1048 gfx::Vector2d root_scroll_delta; | 1072 gfx::Vector2d inner_viewport_scroll_delta; |
| 1049 Layer* root_scroll_layer = FindFirstScrollableLayer(root_layer_.get()); | 1073 gfx::Vector2d outer_viewport_scroll_delta; |
| 1050 | 1074 |
| 1051 for (size_t i = 0; i < info.scrolls.size(); ++i) { | 1075 for (size_t i = 0; i < info.scrolls.size(); ++i) { |
| 1052 Layer* layer = | 1076 Layer* layer = |
| 1053 LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(), | 1077 LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(), |
| 1054 info.scrolls[i].layer_id); | 1078 info.scrolls[i].layer_id); |
| 1055 if (!layer) | 1079 if (!layer) |
| 1056 continue; | 1080 continue; |
| 1057 if (layer == root_scroll_layer) { | 1081 if (layer == outer_viewport_scroll_layer_.get()) { |
| 1058 root_scroll_delta += info.scrolls[i].scroll_delta; | 1082 outer_viewport_scroll_delta += info.scrolls[i].scroll_delta; |
| 1083 } else if (layer == inner_viewport_scroll_layer_.get()) { |
| 1084 inner_viewport_scroll_delta += info.scrolls[i].scroll_delta; |
| 1059 } else { | 1085 } else { |
| 1060 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() + | 1086 layer->SetScrollOffsetFromImplSide(layer->scroll_offset() + |
| 1061 info.scrolls[i].scroll_delta); | 1087 info.scrolls[i].scroll_delta); |
| 1062 } | 1088 } |
| 1063 } | 1089 } |
| 1064 | 1090 |
| 1065 if (!root_scroll_delta.IsZero() || info.page_scale_delta != 1.f) { | 1091 if (!inner_viewport_scroll_delta.IsZero() || |
| 1092 !outer_viewport_scroll_delta.IsZero() || |
| 1093 info.page_scale_delta != 1.f) { |
| 1066 // SetScrollOffsetFromImplSide above could have destroyed the tree, | 1094 // SetScrollOffsetFromImplSide above could have destroyed the tree, |
| 1067 // so re-get this layer before doing anything to it. | 1095 // so re-get this layer before doing anything to it. |
| 1068 root_scroll_layer = FindFirstScrollableLayer(root_layer_.get()); | |
| 1069 | 1096 |
| 1070 // Preemptively apply the scroll offset and scale delta here before sending | 1097 // Preemptively apply the scroll offset and scale delta here before sending |
| 1071 // it to the client. If the client comes back and sets it to the same | 1098 // it to the client. If the client comes back and sets it to the same |
| 1072 // value, then the layer can early out without needing a full commit. | 1099 // value, then the layer can early out without needing a full commit. |
| 1073 if (root_scroll_layer) { | 1100 DCHECK(inner_viewport_scroll_layer_); // We should always have this. |
| 1074 root_scroll_layer->SetScrollOffsetFromImplSide( | 1101 |
| 1075 root_scroll_layer->scroll_offset() + root_scroll_delta); | 1102 inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide( |
| 1103 inner_viewport_scroll_layer_->scroll_offset() + |
| 1104 inner_viewport_scroll_delta); |
| 1105 if (outer_viewport_scroll_layer_) { |
| 1106 outer_viewport_scroll_layer_->SetScrollOffsetFromImplSide( |
| 1107 outer_viewport_scroll_layer_->scroll_offset() + |
| 1108 outer_viewport_scroll_delta); |
| 1076 } | 1109 } |
| 1077 ApplyPageScaleDeltaFromImplSide(info.page_scale_delta); | 1110 ApplyPageScaleDeltaFromImplSide(info.page_scale_delta); |
| 1078 client_->ApplyScrollAndScale(root_scroll_delta, info.page_scale_delta); | 1111 |
| 1112 client_->ApplyScrollAndScale( |
| 1113 inner_viewport_scroll_delta + outer_viewport_scroll_delta, |
| 1114 info.page_scale_delta); |
| 1079 } | 1115 } |
| 1080 } | 1116 } |
| 1081 | 1117 |
| 1118 gfx::Vector2d LayerTreeHost::DistributeScrollOffsetToViewports( |
| 1119 const gfx::Vector2d offset, |
| 1120 Layer* layer) { |
| 1121 DCHECK(layer); |
| 1122 if (layer != outer_viewport_scroll_layer_.get()) |
| 1123 return offset; |
| 1124 |
| 1125 gfx::Vector2d inner_viewport_offset = |
| 1126 inner_viewport_scroll_layer_->scroll_offset(); |
| 1127 gfx::Vector2d outer_viewport_offset = |
| 1128 outer_viewport_scroll_layer_->scroll_offset(); |
| 1129 |
| 1130 if (offset == inner_viewport_offset + outer_viewport_offset) { |
| 1131 // In this case, nothing should change, so we just return to the outer |
| 1132 // viewport the offset is already has. |
| 1133 return outer_viewport_offset; |
| 1134 } |
| 1135 |
| 1136 // In the spirit of document-scrolls-first, we always want any change to |
| 1137 // go to the outer viewport first. |
| 1138 gfx::Vector2d max_outer_viewport_scroll_offset = |
| 1139 outer_viewport_scroll_layer_->MaxScrollOffset(); |
| 1140 #if ENABLE_DCHECK |
| 1141 // TODO(wjmaclean) The DCHECK below is triggering during zoom-out. |
| 1142 // crbug.com/336574 |
| 1143 /* |
| 1144 gfx::Vector2d maxInnerViewportScrollOffset = |
| 1145 inner_viewport_scroll_layer_->MaxScrollOffset(); |
| 1146 |
| 1147 gfx::Vector2d totalMaxScrollOffset = |
| 1148 max_outer_viewport_scroll_offset + maxInnerViewportScrollOffset; |
| 1149 DCHECK(totalMaxScrollOffset.x() >= offset.x() && |
| 1150 totalMaxScrollOffset.y() >= offset.y()); |
| 1151 */ |
| 1152 #endif |
| 1153 |
| 1154 outer_viewport_offset = offset - inner_viewport_offset; |
| 1155 outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset); |
| 1156 outer_viewport_offset.SetToMax(gfx::Vector2d()); |
| 1157 |
| 1158 inner_viewport_offset = offset - outer_viewport_offset; |
| 1159 inner_viewport_scroll_layer_->SetScrollOffset(inner_viewport_offset); |
| 1160 |
| 1161 return outer_viewport_offset; |
| 1162 } |
| 1163 |
| 1082 void LayerTreeHost::StartRateLimiter() { | 1164 void LayerTreeHost::StartRateLimiter() { |
| 1083 if (animating_) | 1165 if (animating_) |
| 1084 return; | 1166 return; |
| 1085 | 1167 |
| 1086 if (!rate_limit_timer_.IsRunning()) { | 1168 if (!rate_limit_timer_.IsRunning()) { |
| 1087 rate_limit_timer_.Start(FROM_HERE, | 1169 rate_limit_timer_.Start(FROM_HERE, |
| 1088 base::TimeDelta(), | 1170 base::TimeDelta(), |
| 1089 this, | 1171 this, |
| 1090 &LayerTreeHost::RateLimit); | 1172 &LayerTreeHost::RateLimit); |
| 1091 } | 1173 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 swap_promise_list_.push_back(swap_promise.Pass()); | 1354 swap_promise_list_.push_back(swap_promise.Pass()); |
| 1273 } | 1355 } |
| 1274 | 1356 |
| 1275 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) { | 1357 void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) { |
| 1276 for (size_t i = 0; i < swap_promise_list_.size(); i++) | 1358 for (size_t i = 0; i < swap_promise_list_.size(); i++) |
| 1277 swap_promise_list_[i]->DidNotSwap(reason); | 1359 swap_promise_list_[i]->DidNotSwap(reason); |
| 1278 swap_promise_list_.clear(); | 1360 swap_promise_list_.clear(); |
| 1279 } | 1361 } |
| 1280 | 1362 |
| 1281 } // namespace cc | 1363 } // namespace cc |
| OLD | NEW |