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_common.h" | 5 #include "cc/trees/layer_tree_host_common.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "cc/base/math_util.h" | 10 #include "cc/base/math_util.h" |
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1105 *combined_maximum_animation_contents_scale = 0.f; | 1105 *combined_maximum_animation_contents_scale = 0.f; |
1106 return; | 1106 return; |
1107 } | 1107 } |
1108 gfx::Vector2dF ancestor_transform_scales = | 1108 gfx::Vector2dF ancestor_transform_scales = |
1109 MathUtil::ComputeTransform2dScaleComponents(ancestor_transform, 0.f); | 1109 MathUtil::ComputeTransform2dScaleComponents(ancestor_transform, 0.f); |
1110 *combined_maximum_animation_contents_scale = | 1110 *combined_maximum_animation_contents_scale = |
1111 layer_maximum_animated_scale * | 1111 layer_maximum_animated_scale * |
1112 std::max(ancestor_transform_scales.x(), ancestor_transform_scales.y()); | 1112 std::max(ancestor_transform_scales.x(), ancestor_transform_scales.y()); |
1113 } | 1113 } |
1114 | 1114 |
1115 static inline RenderSurface* CreateOrReuseRenderSurface(Layer* layer) { | 1115 template <typename LayerType> |
1116 // The render surface should always be new on the main thread, as the | 1116 static inline typename LayerType::RenderSurfaceType* CreateOrReuseRenderSurface( |
1117 // RenderSurfaceLayerList should be a new empty list when given to | 1117 LayerType* layer) { |
1118 // CalculateDrawProperties. | |
1119 DCHECK(!layer->render_surface()); | |
1120 layer->CreateRenderSurface(); | |
1121 return layer->render_surface(); | |
1122 } | |
1123 | |
1124 static inline RenderSurfaceImpl* CreateOrReuseRenderSurface(LayerImpl* layer) { | |
1125 if (!layer->render_surface()) { | 1118 if (!layer->render_surface()) { |
1126 layer->CreateRenderSurface(); | 1119 layer->CreateRenderSurface(); |
1127 return layer->render_surface(); | 1120 return layer->render_surface(); |
1128 } | 1121 } |
1129 | 1122 |
1130 layer->render_surface()->ClearLayerLists(); | 1123 layer->render_surface()->ClearLayerLists(); |
1131 return layer->render_surface(); | 1124 return layer->render_surface(); |
1132 } | 1125 } |
1133 | 1126 |
1134 template <typename LayerType> | 1127 template <typename LayerType> |
1135 static inline void RemoveSurfaceForEarlyExit( | 1128 static inline void RemoveSurfaceForEarlyExit( |
1136 LayerType* layer_to_remove, | 1129 LayerType* layer_to_remove, |
1137 typename LayerType::RenderSurfaceListType* render_surface_layer_list) { | 1130 typename LayerType::RenderSurfaceListType* render_surface_layer_list) { |
1138 DCHECK(layer_to_remove->render_surface()); | 1131 DCHECK(layer_to_remove->render_surface()); |
1139 // Technically, we know that the layer we want to remove should be | 1132 // Technically, we know that the layer we want to remove should be |
1140 // at the back of the render_surface_layer_list. However, we have had | 1133 // at the back of the render_surface_layer_list. However, we have had |
1141 // bugs before that added unnecessary layers here | 1134 // bugs before that added unnecessary layers here |
1142 // (https://bugs.webkit.org/show_bug.cgi?id=74147), but that causes | 1135 // (https://bugs.webkit.org/show_bug.cgi?id=74147), but that causes |
1143 // things to crash. So here we proactively remove any additional | 1136 // things to crash. So here we proactively remove any additional |
1144 // layers from the end of the list. | 1137 // layers from the end of the list. |
1145 while (render_surface_layer_list->back() != layer_to_remove) { | 1138 while (render_surface_layer_list->back() != layer_to_remove) { |
1146 render_surface_layer_list->back()->ClearRenderSurface(); | 1139 render_surface_layer_list->back()->ClearRenderSurfaceLayerList(); |
1147 render_surface_layer_list->pop_back(); | 1140 render_surface_layer_list->pop_back(); |
1148 } | 1141 } |
1149 DCHECK_EQ(render_surface_layer_list->back(), layer_to_remove); | 1142 DCHECK_EQ(render_surface_layer_list->back(), layer_to_remove); |
1150 render_surface_layer_list->pop_back(); | 1143 render_surface_layer_list->pop_back(); |
1151 layer_to_remove->ClearRenderSurface(); | 1144 layer_to_remove->ClearRenderSurfaceLayerList(); |
1152 } | 1145 } |
1153 | 1146 |
1154 struct PreCalculateMetaInformationRecursiveData { | 1147 struct PreCalculateMetaInformationRecursiveData { |
1155 bool layer_or_descendant_has_copy_request; | 1148 bool layer_or_descendant_has_copy_request; |
1156 int num_unclipped_descendants; | 1149 int num_unclipped_descendants; |
1157 | 1150 |
1158 PreCalculateMetaInformationRecursiveData() | 1151 PreCalculateMetaInformationRecursiveData() |
1159 : layer_or_descendant_has_copy_request(false), | 1152 : layer_or_descendant_has_copy_request(false), |
1160 num_unclipped_descendants(0) {} | 1153 num_unclipped_descendants(0) {} |
1161 | 1154 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1374 | 1367 |
1375 template <typename LayerType> | 1368 template <typename LayerType> |
1376 static void GetNewRenderSurfacesStartIndexAndCount(LayerType* layer, | 1369 static void GetNewRenderSurfacesStartIndexAndCount(LayerType* layer, |
1377 size_t* start_index, | 1370 size_t* start_index, |
1378 size_t* count) { | 1371 size_t* count) { |
1379 *start_index = layer->draw_properties() | 1372 *start_index = layer->draw_properties() |
1380 .index_of_first_render_surface_layer_list_addition; | 1373 .index_of_first_render_surface_layer_list_addition; |
1381 *count = layer->draw_properties().num_render_surfaces_added; | 1374 *count = layer->draw_properties().num_render_surfaces_added; |
1382 } | 1375 } |
1383 | 1376 |
1384 template <typename LayerType, | 1377 // We need to extract a list from the the two flavors of RenderSurfaceListType |
1385 typename GetIndexAndCountType> | 1378 // for use in the sorting function below. |
1379 static LayerList* GetLayerListForSorting(RenderSurfaceLayerList* rsll) { | |
1380 return &rsll->AsLayerList(); | |
1381 } | |
1382 | |
1383 static LayerImplList* GetLayerListForSorting(LayerImplList* layer_list) { | |
1384 return layer_list; | |
1385 } | |
1386 | |
1387 template <typename LayerType, typename GetIndexAndCountType> | |
1386 static void SortLayerListContributions( | 1388 static void SortLayerListContributions( |
1387 const LayerType& parent, | 1389 const LayerType& parent, |
1388 typename LayerType::RenderSurfaceListType* unsorted, | 1390 typename LayerType::LayerListType* unsorted, |
1389 size_t start_index_for_all_contributions, | 1391 size_t start_index_for_all_contributions, |
1390 GetIndexAndCountType get_index_and_count) { | 1392 GetIndexAndCountType get_index_and_count) { |
1391 | |
1392 typename LayerType::LayerListType buffer; | 1393 typename LayerType::LayerListType buffer; |
1393 for (size_t i = 0; i < parent.children().size(); ++i) { | 1394 for (size_t i = 0; i < parent.children().size(); ++i) { |
1394 LayerType* child = | 1395 LayerType* child = |
1395 LayerTreeHostCommon::get_child_as_raw_ptr(parent.children(), i); | 1396 LayerTreeHostCommon::get_child_as_raw_ptr(parent.children(), i); |
1396 | 1397 |
1397 size_t start_index = 0; | 1398 size_t start_index = 0; |
1398 size_t count = 0; | 1399 size_t count = 0; |
1399 get_index_and_count(child, &start_index, &count); | 1400 get_index_and_count(child, &start_index, &count); |
1400 for (size_t j = start_index; j < start_index + count; ++j) | 1401 for (size_t j = start_index; j < start_index + count; ++j) |
1401 buffer.push_back(unsorted->at(j)); | 1402 buffer.push_back(unsorted->at(j)); |
1402 } | 1403 } |
1403 | 1404 |
1404 DCHECK_EQ(buffer.size(), | 1405 DCHECK_EQ(buffer.size(), |
1405 unsorted->size() - start_index_for_all_contributions); | 1406 unsorted->size() - start_index_for_all_contributions); |
1406 | 1407 |
1407 for (size_t i = 0; i < buffer.size(); ++i) | 1408 for (size_t i = 0; i < buffer.size(); ++i) |
1408 (*unsorted)[i + start_index_for_all_contributions] = buffer[i]; | 1409 (*unsorted)[i + start_index_for_all_contributions] = buffer[i]; |
1409 } | 1410 } |
1410 | 1411 |
1411 // Recursively walks the layer tree starting at the given node and computes all | 1412 // Recursively walks the layer tree starting at the given node and computes all |
1412 // the necessary transformations, clip rects, render surfaces, etc. | 1413 // the necessary transformations, clip rects, render surfaces, etc. |
1413 template <typename LayerType> | 1414 template <typename LayerType> |
1414 static void CalculateDrawPropertiesInternal( | 1415 static void CalculateDrawPropertiesInternal( |
1415 LayerType* layer, | 1416 LayerType* layer, |
1416 const SubtreeGlobals<LayerType>& globals, | 1417 const SubtreeGlobals<LayerType>& globals, |
1417 const DataForRecursion<LayerType>& data_from_ancestor, | 1418 const DataForRecursion<LayerType>& data_from_ancestor, |
1418 typename LayerType::RenderSurfaceListType* render_surface_layer_list, | 1419 typename LayerType::RenderSurfaceListType* render_surface_layer_list, |
1419 typename LayerType::RenderSurfaceListType* layer_list, | 1420 typename LayerType::LayerListType* layer_list, |
1420 std::vector<AccumulatedSurfaceState<LayerType> >* | 1421 std::vector<AccumulatedSurfaceState<LayerType> >* |
1421 accumulated_surface_state) { | 1422 accumulated_surface_state) { |
1422 // This function computes the new matrix transformations recursively for this | 1423 // This function computes the new matrix transformations recursively for this |
1423 // layer and all its descendants. It also computes the appropriate render | 1424 // layer and all its descendants. It also computes the appropriate render |
1424 // surfaces. | 1425 // surfaces. |
1425 // Some important points to remember: | 1426 // Some important points to remember: |
1426 // | 1427 // |
1427 // 0. Here, transforms are notated in Matrix x Vector order, and in words we | 1428 // 0. Here, transforms are notated in Matrix x Vector order, and in words we |
1428 // describe what the transform does from left to right. | 1429 // describe what the transform does from left to right. |
1429 // | 1430 // |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1553 // anyway. In this case, we will inform their subtree they are visible to get | 1554 // anyway. In this case, we will inform their subtree they are visible to get |
1554 // the right results. | 1555 // the right results. |
1555 const bool layer_is_visible = | 1556 const bool layer_is_visible = |
1556 data_from_ancestor.subtree_is_visible_from_ancestor && | 1557 data_from_ancestor.subtree_is_visible_from_ancestor && |
1557 !layer->hide_layer_and_subtree(); | 1558 !layer->hide_layer_and_subtree(); |
1558 const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest(); | 1559 const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest(); |
1559 | 1560 |
1560 // The root layer cannot skip CalcDrawProperties. | 1561 // The root layer cannot skip CalcDrawProperties. |
1561 if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) { | 1562 if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) { |
1562 if (layer->render_surface()) | 1563 if (layer->render_surface()) |
1563 layer->ClearRenderSurface(); | 1564 layer->ClearRenderSurfaceLayerList(); |
1564 return; | 1565 return; |
1565 } | 1566 } |
1566 | 1567 |
1567 // We need to circumvent the normal recursive flow of information for clip | 1568 // We need to circumvent the normal recursive flow of information for clip |
1568 // children (they don't inherit their direct ancestor's clip information). | 1569 // children (they don't inherit their direct ancestor's clip information). |
1569 // This is unfortunate, and would be unnecessary if we were to formally | 1570 // This is unfortunate, and would be unnecessary if we were to formally |
1570 // separate the clipping hierarchy from the layer hierarchy. | 1571 // separate the clipping hierarchy from the layer hierarchy. |
1571 bool ancestor_clips_subtree = data_from_ancestor.ancestor_clips_subtree; | 1572 bool ancestor_clips_subtree = data_from_ancestor.ancestor_clips_subtree; |
1572 gfx::Rect ancestor_clip_rect_in_target_space = | 1573 gfx::Rect ancestor_clip_rect_in_target_space = |
1573 data_from_ancestor.clip_rect_in_target_space; | 1574 data_from_ancestor.clip_rect_in_target_space; |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1757 render_to_separate_surface = SubtreeShouldRenderToSeparateSurface( | 1758 render_to_separate_surface = SubtreeShouldRenderToSeparateSurface( |
1758 layer, combined_transform.Preserves2dAxisAlignment()); | 1759 layer, combined_transform.Preserves2dAxisAlignment()); |
1759 } else { | 1760 } else { |
1760 render_to_separate_surface = IsRootLayer(layer); | 1761 render_to_separate_surface = IsRootLayer(layer); |
1761 } | 1762 } |
1762 if (render_to_separate_surface) { | 1763 if (render_to_separate_surface) { |
1763 // Check back-face visibility before continuing with this surface and its | 1764 // Check back-face visibility before continuing with this surface and its |
1764 // subtree | 1765 // subtree |
1765 if (!layer->double_sided() && TransformToParentIsKnown(layer) && | 1766 if (!layer->double_sided() && TransformToParentIsKnown(layer) && |
1766 IsSurfaceBackFaceVisible(layer, combined_transform)) { | 1767 IsSurfaceBackFaceVisible(layer, combined_transform)) { |
1767 layer->ClearRenderSurface(); | 1768 layer->ClearRenderSurfaceLayerList(); |
1768 return; | 1769 return; |
1769 } | 1770 } |
1770 | 1771 |
1771 typename LayerType::RenderSurfaceType* render_surface = | 1772 typename LayerType::RenderSurfaceType* render_surface = |
1772 CreateOrReuseRenderSurface(layer); | 1773 CreateOrReuseRenderSurface(layer); |
1773 | 1774 |
1774 if (IsRootLayer(layer)) { | 1775 if (IsRootLayer(layer)) { |
1775 // The root layer's render surface size is predetermined and so the root | 1776 // The root layer's render surface size is predetermined and so the root |
1776 // layer can't directly support non-identity transforms. It should just | 1777 // layer can't directly support non-identity transforms. It should just |
1777 // forward top-level transforms to the rest of the tree. | 1778 // forward top-level transforms to the rest of the tree. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1990 // is used in the recursion below, so we must set it beforehand. | 1991 // is used in the recursion below, so we must set it beforehand. |
1991 layer_draw_properties.is_clipped = layer_or_ancestor_clips_descendants; | 1992 layer_draw_properties.is_clipped = layer_or_ancestor_clips_descendants; |
1992 if (layer_or_ancestor_clips_descendants) { | 1993 if (layer_or_ancestor_clips_descendants) { |
1993 layer_draw_properties.clip_rect = clip_rect_in_target_space; | 1994 layer_draw_properties.clip_rect = clip_rect_in_target_space; |
1994 } else { | 1995 } else { |
1995 // Initialize the clip rect to a safe value that will not clip the | 1996 // Initialize the clip rect to a safe value that will not clip the |
1996 // layer, just in case clipping is still accidentally used. | 1997 // layer, just in case clipping is still accidentally used. |
1997 layer_draw_properties.clip_rect = rect_in_target_space; | 1998 layer_draw_properties.clip_rect = rect_in_target_space; |
1998 } | 1999 } |
1999 | 2000 |
2000 typename LayerType::RenderSurfaceListType& descendants = | 2001 typename LayerType::LayerListType& descendants = |
2001 (layer->render_surface() ? layer->render_surface()->layer_list() | 2002 (layer->render_surface() ? layer->render_surface()->layer_list() |
2002 : *layer_list); | 2003 : *layer_list); |
2003 | 2004 |
2004 // Any layers that are appended after this point are in the layer's subtree | 2005 // Any layers that are appended after this point are in the layer's subtree |
2005 // and should be included in the sorting process. | 2006 // and should be included in the sorting process. |
2006 size_t sorting_start_index = descendants.size(); | 2007 size_t sorting_start_index = descendants.size(); |
2007 | 2008 |
2008 if (!LayerShouldBeSkipped(layer, layer_is_drawn)) | 2009 if (!LayerShouldBeSkipped(layer, layer_is_drawn)) |
2009 descendants.push_back(layer); | 2010 descendants.push_back(layer); |
2010 | 2011 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2066 child->draw_properties().index_of_first_render_surface_layer_list_addition = | 2067 child->draw_properties().index_of_first_render_surface_layer_list_addition = |
2067 render_surface_layer_list->size(); | 2068 render_surface_layer_list->size(); |
2068 | 2069 |
2069 CalculateDrawPropertiesInternal<LayerType>(child, | 2070 CalculateDrawPropertiesInternal<LayerType>(child, |
2070 globals, | 2071 globals, |
2071 data_for_children, | 2072 data_for_children, |
2072 render_surface_layer_list, | 2073 render_surface_layer_list, |
2073 &descendants, | 2074 &descendants, |
2074 accumulated_surface_state); | 2075 accumulated_surface_state); |
2075 if (child->render_surface() && | 2076 if (child->render_surface() && |
2077 !child->render_surface()->layer_list().empty() && | |
danakj
2014/04/28 15:02:17
How come the render surface's content rect is not
| |
2076 !child->render_surface()->content_rect().IsEmpty()) { | 2078 !child->render_surface()->content_rect().IsEmpty()) { |
2077 descendants.push_back(child); | 2079 descendants.push_back(child); |
2078 } | 2080 } |
2079 | 2081 |
2080 child->draw_properties().num_descendants_added = | 2082 child->draw_properties().num_descendants_added = |
2081 descendants.size() - | 2083 descendants.size() - |
2082 child->draw_properties().index_of_first_descendants_addition; | 2084 child->draw_properties().index_of_first_descendants_addition; |
2083 child->draw_properties().num_render_surfaces_added = | 2085 child->draw_properties().num_render_surfaces_added = |
2084 render_surface_layer_list->size() - | 2086 render_surface_layer_list->size() - |
2085 child->draw_properties() | 2087 child->draw_properties() |
2086 .index_of_first_render_surface_layer_list_addition; | 2088 .index_of_first_render_surface_layer_list_addition; |
2087 } | 2089 } |
2088 | 2090 |
2089 // Add the unsorted layer list contributions, if necessary. | 2091 // Add the unsorted layer list contributions, if necessary. |
2090 if (child_order_changed) { | 2092 if (child_order_changed) { |
2091 SortLayerListContributions( | 2093 SortLayerListContributions( |
2092 *layer, | 2094 *layer, |
2093 render_surface_layer_list, | 2095 GetLayerListForSorting(render_surface_layer_list), |
2094 render_surface_layer_list_child_sorting_start_index, | 2096 render_surface_layer_list_child_sorting_start_index, |
2095 &GetNewRenderSurfacesStartIndexAndCount<LayerType>); | 2097 &GetNewRenderSurfacesStartIndexAndCount<LayerType>); |
2096 | 2098 |
2097 SortLayerListContributions( | 2099 SortLayerListContributions( |
2098 *layer, | 2100 *layer, |
2099 &descendants, | 2101 &descendants, |
2100 layer_list_child_sorting_start_index, | 2102 layer_list_child_sorting_start_index, |
2101 &GetNewDescendantsStartIndexAndCount<LayerType>); | 2103 &GetNewDescendantsStartIndexAndCount<LayerType>); |
2102 } | 2104 } |
2103 | 2105 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2306 data_for_recursion->ancestor_is_animating_scale = false; | 2308 data_for_recursion->ancestor_is_animating_scale = false; |
2307 data_for_recursion->ancestor_clips_subtree = true; | 2309 data_for_recursion->ancestor_clips_subtree = true; |
2308 data_for_recursion->nearest_occlusion_immune_ancestor_surface = NULL; | 2310 data_for_recursion->nearest_occlusion_immune_ancestor_surface = NULL; |
2309 data_for_recursion->in_subtree_of_page_scale_application_layer = false; | 2311 data_for_recursion->in_subtree_of_page_scale_application_layer = false; |
2310 data_for_recursion->subtree_can_use_lcd_text = inputs.can_use_lcd_text; | 2312 data_for_recursion->subtree_can_use_lcd_text = inputs.can_use_lcd_text; |
2311 data_for_recursion->subtree_is_visible_from_ancestor = true; | 2313 data_for_recursion->subtree_is_visible_from_ancestor = true; |
2312 } | 2314 } |
2313 | 2315 |
2314 void LayerTreeHostCommon::CalculateDrawProperties( | 2316 void LayerTreeHostCommon::CalculateDrawProperties( |
2315 CalcDrawPropsMainInputs* inputs) { | 2317 CalcDrawPropsMainInputs* inputs) { |
2316 RenderSurfaceLayerList dummy_layer_list; | 2318 LayerList dummy_layer_list; |
2317 SubtreeGlobals<Layer> globals; | 2319 SubtreeGlobals<Layer> globals; |
2318 DataForRecursion<Layer> data_for_recursion; | 2320 DataForRecursion<Layer> data_for_recursion; |
2319 ProcessCalcDrawPropsInputs(*inputs, &globals, &data_for_recursion); | 2321 ProcessCalcDrawPropsInputs(*inputs, &globals, &data_for_recursion); |
2320 | 2322 |
2321 PreCalculateMetaInformationRecursiveData recursive_data; | 2323 PreCalculateMetaInformationRecursiveData recursive_data; |
2322 PreCalculateMetaInformation(inputs->root_layer, &recursive_data); | 2324 PreCalculateMetaInformation(inputs->root_layer, &recursive_data); |
2323 std::vector<AccumulatedSurfaceState<Layer> > accumulated_surface_state; | 2325 std::vector<AccumulatedSurfaceState<Layer> > accumulated_surface_state; |
2324 CalculateDrawPropertiesInternal<Layer>(inputs->root_layer, | 2326 CalculateDrawPropertiesInternal<Layer>(inputs->root_layer, |
2325 globals, | 2327 globals, |
2326 data_for_recursion, | 2328 data_for_recursion, |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2573 // At this point, we think the point does hit the touch event handler region | 2575 // At this point, we think the point does hit the touch event handler region |
2574 // on the layer, but we need to walk up the parents to ensure that the layer | 2576 // on the layer, but we need to walk up the parents to ensure that the layer |
2575 // was not clipped in such a way that the hit point actually should not hit | 2577 // was not clipped in such a way that the hit point actually should not hit |
2576 // the layer. | 2578 // the layer. |
2577 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl)) | 2579 if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl)) |
2578 return false; | 2580 return false; |
2579 | 2581 |
2580 return true; | 2582 return true; |
2581 } | 2583 } |
2582 } // namespace cc | 2584 } // namespace cc |
OLD | NEW |