| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "ui/compositor/layer.h" | 5 #include "ui/compositor/layer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
| 13 #include "base/lazy_instance.h" | |
| 14 #include "base/logging.h" | 13 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
| 17 #include "cc/layers/layer_settings.h" | 16 #include "cc/layers/layer_settings.h" |
| 18 #include "cc/layers/nine_patch_layer.h" | 17 #include "cc/layers/nine_patch_layer.h" |
| 19 #include "cc/layers/picture_layer.h" | 18 #include "cc/layers/picture_layer.h" |
| 20 #include "cc/layers/solid_color_layer.h" | 19 #include "cc/layers/solid_color_layer.h" |
| 21 #include "cc/layers/surface_layer.h" | 20 #include "cc/layers/surface_layer.h" |
| 22 #include "cc/layers/texture_layer.h" | 21 #include "cc/layers/texture_layer.h" |
| 23 #include "cc/output/copy_output_request.h" | 22 #include "cc/output/copy_output_request.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 39 #include "ui/gfx/interpolated_transform.h" | 38 #include "ui/gfx/interpolated_transform.h" |
| 40 | 39 |
| 41 namespace { | 40 namespace { |
| 42 | 41 |
| 43 const ui::Layer* GetRoot(const ui::Layer* layer) { | 42 const ui::Layer* GetRoot(const ui::Layer* layer) { |
| 44 while (layer->parent()) | 43 while (layer->parent()) |
| 45 layer = layer->parent(); | 44 layer = layer->parent(); |
| 46 return layer; | 45 return layer; |
| 47 } | 46 } |
| 48 | 47 |
| 49 base::LazyInstance<cc::LayerSettings> g_ui_layer_settings = | |
| 50 LAZY_INSTANCE_INITIALIZER; | |
| 51 | |
| 52 } // namespace | 48 } // namespace |
| 53 | 49 |
| 54 namespace ui { | 50 namespace ui { |
| 55 | 51 |
| 56 Layer::Layer() | 52 Layer::Layer() |
| 57 : type_(LAYER_TEXTURED), | 53 : type_(LAYER_TEXTURED), |
| 58 compositor_(NULL), | 54 compositor_(NULL), |
| 59 parent_(NULL), | 55 parent_(NULL), |
| 60 visible_(true), | 56 visible_(true), |
| 61 force_render_surface_(false), | 57 force_render_surface_(false), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 if (layer_mask_) | 109 if (layer_mask_) |
| 114 SetMaskLayer(NULL); | 110 SetMaskLayer(NULL); |
| 115 if (layer_mask_back_link_) | 111 if (layer_mask_back_link_) |
| 116 layer_mask_back_link_->SetMaskLayer(NULL); | 112 layer_mask_back_link_->SetMaskLayer(NULL); |
| 117 for (size_t i = 0; i < children_.size(); ++i) | 113 for (size_t i = 0; i < children_.size(); ++i) |
| 118 children_[i]->parent_ = NULL; | 114 children_[i]->parent_ = NULL; |
| 119 | 115 |
| 120 cc_layer_->RemoveFromParent(); | 116 cc_layer_->RemoveFromParent(); |
| 121 } | 117 } |
| 122 | 118 |
| 123 // static | |
| 124 const cc::LayerSettings& Layer::UILayerSettings() { | |
| 125 return g_ui_layer_settings.Get(); | |
| 126 } | |
| 127 | |
| 128 // static | |
| 129 void Layer::InitializeUILayerSettings() { | |
| 130 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
| 131 g_ui_layer_settings.Get().use_compositor_animation_timelines = | |
| 132 !command_line->HasSwitch( | |
| 133 switches::kUIDisableCompositorAnimationTimelines); | |
| 134 } | |
| 135 | |
| 136 const Compositor* Layer::GetCompositor() const { | 119 const Compositor* Layer::GetCompositor() const { |
| 137 return GetRoot(this)->compositor_; | 120 return GetRoot(this)->compositor_; |
| 138 } | 121 } |
| 139 | 122 |
| 140 float Layer::opacity() const { | 123 float Layer::opacity() const { |
| 141 return cc_layer_->opacity(); | 124 return cc_layer_->opacity(); |
| 142 } | 125 } |
| 143 | 126 |
| 144 void Layer::SetCompositor(Compositor* compositor, | 127 void Layer::SetCompositor(Compositor* compositor, |
| 145 scoped_refptr<cc::Layer> root_layer) { | 128 scoped_refptr<cc::Layer> root_layer) { |
| 146 // This function must only be called to set the compositor on the root ui | 129 // This function must only be called to set the compositor on the root ui |
| 147 // layer. | 130 // layer. |
| 148 DCHECK(compositor); | 131 DCHECK(compositor); |
| 149 DCHECK(!compositor_); | 132 DCHECK(!compositor_); |
| 150 DCHECK(compositor->root_layer() == this); | 133 DCHECK(compositor->root_layer() == this); |
| 151 DCHECK(!parent_); | 134 DCHECK(!parent_); |
| 152 | 135 |
| 153 compositor_ = compositor; | 136 compositor_ = compositor; |
| 154 OnDeviceScaleFactorChanged(compositor->device_scale_factor()); | 137 OnDeviceScaleFactorChanged(compositor->device_scale_factor()); |
| 155 | 138 |
| 156 root_layer->AddChild(cc_layer_); | 139 root_layer->AddChild(cc_layer_); |
| 157 SetCompositorForAnimatorsInTree(compositor); | 140 SetCompositorForAnimatorsInTree(compositor); |
| 158 SendPendingThreadedAnimations(); | |
| 159 } | 141 } |
| 160 | 142 |
| 161 void Layer::ResetCompositor() { | 143 void Layer::ResetCompositor() { |
| 162 DCHECK(!parent_); | 144 DCHECK(!parent_); |
| 163 if (compositor_) { | 145 if (compositor_) { |
| 164 ResetCompositorForAnimatorsInTree(compositor_); | 146 ResetCompositorForAnimatorsInTree(compositor_); |
| 165 compositor_ = nullptr; | 147 compositor_ = nullptr; |
| 166 } | 148 } |
| 167 } | 149 } |
| 168 | 150 |
| 169 void Layer::Add(Layer* child) { | 151 void Layer::Add(Layer* child) { |
| 170 DCHECK(!child->compositor_); | 152 DCHECK(!child->compositor_); |
| 171 if (child->parent_) | 153 if (child->parent_) |
| 172 child->parent_->Remove(child); | 154 child->parent_->Remove(child); |
| 173 child->parent_ = this; | 155 child->parent_ = this; |
| 174 children_.push_back(child); | 156 children_.push_back(child); |
| 175 cc_layer_->AddChild(child->cc_layer_); | 157 cc_layer_->AddChild(child->cc_layer_); |
| 176 child->OnDeviceScaleFactorChanged(device_scale_factor_); | 158 child->OnDeviceScaleFactorChanged(device_scale_factor_); |
| 177 Compositor* compositor = GetCompositor(); | 159 Compositor* compositor = GetCompositor(); |
| 178 if (compositor) { | 160 if (compositor) |
| 179 child->SetCompositorForAnimatorsInTree(compositor); | 161 child->SetCompositorForAnimatorsInTree(compositor); |
| 180 child->SendPendingThreadedAnimations(); | |
| 181 } | |
| 182 } | 162 } |
| 183 | 163 |
| 184 void Layer::Remove(Layer* child) { | 164 void Layer::Remove(Layer* child) { |
| 185 // Current bounds are used to calculate offsets when layers are reparented. | 165 // Current bounds are used to calculate offsets when layers are reparented. |
| 186 // Stop (and complete) an ongoing animation to update the bounds immediately. | 166 // Stop (and complete) an ongoing animation to update the bounds immediately. |
| 187 LayerAnimator* child_animator = child->animator_.get(); | 167 LayerAnimator* child_animator = child->animator_.get(); |
| 188 if (child_animator) | 168 if (child_animator) |
| 189 child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); | 169 child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS); |
| 190 | 170 |
| 191 Compositor* compositor = GetCompositor(); | 171 Compositor* compositor = GetCompositor(); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_); | 509 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_); |
| 530 cc_layer_->SetForceRenderSurface(force_render_surface_); | 510 cc_layer_->SetForceRenderSurface(force_render_surface_); |
| 531 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); | 511 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); |
| 532 cc_layer_->SetHideLayerAndSubtree(!visible_); | 512 cc_layer_->SetHideLayerAndSubtree(!visible_); |
| 533 | 513 |
| 534 SetLayerFilters(); | 514 SetLayerFilters(); |
| 535 SetLayerBackgroundFilters(); | 515 SetLayerBackgroundFilters(); |
| 536 } | 516 } |
| 537 | 517 |
| 538 bool Layer::HasPendingThreadedAnimationsForTesting() const { | 518 bool Layer::HasPendingThreadedAnimationsForTesting() const { |
| 539 if (UILayerSettings().use_compositor_animation_timelines) | 519 return animator_->HasPendingThreadedAnimationsForTesting(); |
| 540 return animator_->HasPendingThreadedAnimationsForTesting(); | |
| 541 else | |
| 542 return !pending_threaded_animations_.empty(); | |
| 543 } | 520 } |
| 544 | 521 |
| 545 void Layer::SwitchCCLayerForTest() { | 522 void Layer::SwitchCCLayerForTest() { |
| 546 scoped_refptr<cc::Layer> new_layer = | 523 scoped_refptr<cc::Layer> new_layer = |
| 547 cc::PictureLayer::Create(UILayerSettings(), this); | 524 cc::PictureLayer::Create(cc::LayerSettings(), this); |
| 548 SwitchToLayer(new_layer); | 525 SwitchToLayer(new_layer); |
| 549 content_layer_ = new_layer; | 526 content_layer_ = new_layer; |
| 550 } | 527 } |
| 551 | 528 |
| 552 void Layer::SetTextureMailbox( | 529 void Layer::SetTextureMailbox( |
| 553 const cc::TextureMailbox& mailbox, | 530 const cc::TextureMailbox& mailbox, |
| 554 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 531 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 555 gfx::Size texture_size_in_dip) { | 532 gfx::Size texture_size_in_dip) { |
| 556 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR); | 533 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR); |
| 557 DCHECK(mailbox.IsValid()); | 534 DCHECK(mailbox.IsValid()); |
| 558 DCHECK(release_callback); | 535 DCHECK(release_callback); |
| 559 if (!texture_layer_.get()) { | 536 if (!texture_layer_.get()) { |
| 560 scoped_refptr<cc::TextureLayer> new_layer = | 537 scoped_refptr<cc::TextureLayer> new_layer = |
| 561 cc::TextureLayer::CreateForMailbox(UILayerSettings(), this); | 538 cc::TextureLayer::CreateForMailbox(cc::LayerSettings(), this); |
| 562 new_layer->SetFlipped(true); | 539 new_layer->SetFlipped(true); |
| 563 SwitchToLayer(new_layer); | 540 SwitchToLayer(new_layer); |
| 564 texture_layer_ = new_layer; | 541 texture_layer_ = new_layer; |
| 565 // Reset the frame_size_in_dip_ so that SetTextureSize() will not early out, | 542 // Reset the frame_size_in_dip_ so that SetTextureSize() will not early out, |
| 566 // the frame_size_in_dip_ was for a previous (different) |texture_layer_|. | 543 // the frame_size_in_dip_ was for a previous (different) |texture_layer_|. |
| 567 frame_size_in_dip_ = gfx::Size(); | 544 frame_size_in_dip_ = gfx::Size(); |
| 568 } | 545 } |
| 569 if (mailbox_release_callback_) | 546 if (mailbox_release_callback_) |
| 570 mailbox_release_callback_->Run(gpu::SyncToken(), false); | 547 mailbox_release_callback_->Run(gpu::SyncToken(), false); |
| 571 mailbox_release_callback_ = std::move(release_callback); | 548 mailbox_release_callback_ = std::move(release_callback); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 595 void Layer::SetShowSurface( | 572 void Layer::SetShowSurface( |
| 596 cc::SurfaceId surface_id, | 573 cc::SurfaceId surface_id, |
| 597 const cc::SurfaceLayer::SatisfyCallback& satisfy_callback, | 574 const cc::SurfaceLayer::SatisfyCallback& satisfy_callback, |
| 598 const cc::SurfaceLayer::RequireCallback& require_callback, | 575 const cc::SurfaceLayer::RequireCallback& require_callback, |
| 599 gfx::Size surface_size, | 576 gfx::Size surface_size, |
| 600 float scale, | 577 float scale, |
| 601 gfx::Size frame_size_in_dip) { | 578 gfx::Size frame_size_in_dip) { |
| 602 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR); | 579 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR); |
| 603 | 580 |
| 604 scoped_refptr<cc::SurfaceLayer> new_layer = cc::SurfaceLayer::Create( | 581 scoped_refptr<cc::SurfaceLayer> new_layer = cc::SurfaceLayer::Create( |
| 605 UILayerSettings(), satisfy_callback, require_callback); | 582 cc::LayerSettings(), satisfy_callback, require_callback); |
| 606 new_layer->SetSurfaceId(surface_id, scale, surface_size); | 583 new_layer->SetSurfaceId(surface_id, scale, surface_size); |
| 607 SwitchToLayer(new_layer); | 584 SwitchToLayer(new_layer); |
| 608 surface_layer_ = new_layer; | 585 surface_layer_ = new_layer; |
| 609 | 586 |
| 610 frame_size_in_dip_ = frame_size_in_dip; | 587 frame_size_in_dip_ = frame_size_in_dip; |
| 611 RecomputeDrawsContentAndUVRect(); | 588 RecomputeDrawsContentAndUVRect(); |
| 612 } | 589 } |
| 613 | 590 |
| 614 void Layer::SetShowSolidColorContent() { | 591 void Layer::SetShowSolidColorContent() { |
| 615 DCHECK_EQ(type_, LAYER_SOLID_COLOR); | 592 DCHECK_EQ(type_, LAYER_SOLID_COLOR); |
| 616 | 593 |
| 617 if (solid_color_layer_.get()) | 594 if (solid_color_layer_.get()) |
| 618 return; | 595 return; |
| 619 | 596 |
| 620 scoped_refptr<cc::SolidColorLayer> new_layer = | 597 scoped_refptr<cc::SolidColorLayer> new_layer = |
| 621 cc::SolidColorLayer::Create(UILayerSettings()); | 598 cc::SolidColorLayer::Create(cc::LayerSettings()); |
| 622 SwitchToLayer(new_layer); | 599 SwitchToLayer(new_layer); |
| 623 solid_color_layer_ = new_layer; | 600 solid_color_layer_ = new_layer; |
| 624 | 601 |
| 625 mailbox_ = cc::TextureMailbox(); | 602 mailbox_ = cc::TextureMailbox(); |
| 626 if (mailbox_release_callback_) { | 603 if (mailbox_release_callback_) { |
| 627 mailbox_release_callback_->Run(gpu::SyncToken(), false); | 604 mailbox_release_callback_->Run(gpu::SyncToken(), false); |
| 628 mailbox_release_callback_.reset(); | 605 mailbox_release_callback_.reset(); |
| 629 } | 606 } |
| 630 RecomputeDrawsContentAndUVRect(); | 607 RecomputeDrawsContentAndUVRect(); |
| 631 } | 608 } |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 // The NULL check is here since this is invoked regardless of whether we have | 941 // The NULL check is here since this is invoked regardless of whether we have |
| 965 // been configured as LAYER_SOLID_COLOR. | 942 // been configured as LAYER_SOLID_COLOR. |
| 966 return solid_color_layer_.get() ? | 943 return solid_color_layer_.get() ? |
| 967 solid_color_layer_->background_color() : SK_ColorBLACK; | 944 solid_color_layer_->background_color() : SK_ColorBLACK; |
| 968 } | 945 } |
| 969 | 946 |
| 970 float Layer::GetDeviceScaleFactor() const { | 947 float Layer::GetDeviceScaleFactor() const { |
| 971 return device_scale_factor_; | 948 return device_scale_factor_; |
| 972 } | 949 } |
| 973 | 950 |
| 974 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) { | |
| 975 DCHECK(cc_layer_); | |
| 976 DCHECK(!UILayerSettings().use_compositor_animation_timelines); | |
| 977 // Until this layer has a compositor (and hence cc_layer_ has a | |
| 978 // LayerTreeHost), addAnimation will fail. | |
| 979 if (GetCompositor()) { | |
| 980 cc_layer_->AddAnimation(std::move(animation)); | |
| 981 } else { | |
| 982 pending_threaded_animations_.push_back(std::move(animation)); | |
| 983 } | |
| 984 } | |
| 985 | |
| 986 void Layer::RemoveThreadedAnimation(int animation_id) { | |
| 987 DCHECK(cc_layer_); | |
| 988 DCHECK(!UILayerSettings().use_compositor_animation_timelines); | |
| 989 if (pending_threaded_animations_.size() == 0) { | |
| 990 cc_layer_->RemoveAnimation(animation_id); | |
| 991 return; | |
| 992 } | |
| 993 | |
| 994 pending_threaded_animations_.erase( | |
| 995 std::remove_if( | |
| 996 pending_threaded_animations_.begin(), | |
| 997 pending_threaded_animations_.end(), | |
| 998 [animation_id](const scoped_ptr<cc::Animation>& animation) { | |
| 999 return animation->id() == animation_id; | |
| 1000 }), | |
| 1001 pending_threaded_animations_.end()); | |
| 1002 } | |
| 1003 | |
| 1004 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() { | 951 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() { |
| 1005 Compositor* compositor = GetCompositor(); | 952 Compositor* compositor = GetCompositor(); |
| 1006 return compositor ? compositor->layer_animator_collection() : NULL; | 953 return compositor ? compositor->layer_animator_collection() : NULL; |
| 1007 } | 954 } |
| 1008 | 955 |
| 1009 cc::Layer* Layer::GetCcLayer() const { | 956 cc::Layer* Layer::GetCcLayer() const { |
| 1010 return cc_layer_; | 957 return cc_layer_; |
| 1011 } | 958 } |
| 1012 | 959 |
| 1013 LayerThreadedAnimationDelegate* Layer::GetThreadedAnimationDelegate() { | 960 LayerThreadedAnimationDelegate* Layer::GetThreadedAnimationDelegate() { |
| 1014 if (UILayerSettings().use_compositor_animation_timelines) { | 961 DCHECK(animator_); |
| 1015 DCHECK(animator_); | 962 return animator_.get(); |
| 1016 return animator_.get(); | |
| 1017 } else { | |
| 1018 return this; | |
| 1019 } | |
| 1020 } | |
| 1021 | |
| 1022 void Layer::SendPendingThreadedAnimations() { | |
| 1023 if (UILayerSettings().use_compositor_animation_timelines) { | |
| 1024 DCHECK(pending_threaded_animations_.empty()); | |
| 1025 return; | |
| 1026 } | |
| 1027 | |
| 1028 for (auto& animation : pending_threaded_animations_) | |
| 1029 cc_layer_->AddAnimation(std::move(animation)); | |
| 1030 pending_threaded_animations_.clear(); | |
| 1031 | |
| 1032 for (auto* child : children_) | |
| 1033 child->SendPendingThreadedAnimations(); | |
| 1034 } | 963 } |
| 1035 | 964 |
| 1036 void Layer::CreateCcLayer() { | 965 void Layer::CreateCcLayer() { |
| 1037 if (type_ == LAYER_SOLID_COLOR) { | 966 if (type_ == LAYER_SOLID_COLOR) { |
| 1038 solid_color_layer_ = cc::SolidColorLayer::Create(UILayerSettings()); | 967 solid_color_layer_ = cc::SolidColorLayer::Create(cc::LayerSettings()); |
| 1039 cc_layer_ = solid_color_layer_.get(); | 968 cc_layer_ = solid_color_layer_.get(); |
| 1040 } else if (type_ == LAYER_NINE_PATCH) { | 969 } else if (type_ == LAYER_NINE_PATCH) { |
| 1041 nine_patch_layer_ = cc::NinePatchLayer::Create(UILayerSettings()); | 970 nine_patch_layer_ = cc::NinePatchLayer::Create(cc::LayerSettings()); |
| 1042 cc_layer_ = nine_patch_layer_.get(); | 971 cc_layer_ = nine_patch_layer_.get(); |
| 1043 } else { | 972 } else { |
| 1044 content_layer_ = cc::PictureLayer::Create(UILayerSettings(), this); | 973 content_layer_ = cc::PictureLayer::Create(cc::LayerSettings(), this); |
| 1045 cc_layer_ = content_layer_.get(); | 974 cc_layer_ = content_layer_.get(); |
| 1046 } | 975 } |
| 1047 cc_layer_->SetTransformOrigin(gfx::Point3F()); | 976 cc_layer_->SetTransformOrigin(gfx::Point3F()); |
| 1048 cc_layer_->SetContentsOpaque(true); | 977 cc_layer_->SetContentsOpaque(true); |
| 1049 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); | 978 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); |
| 1050 cc_layer_->SetLayerClient(this); | 979 cc_layer_->SetLayerClient(this); |
| 1051 RecomputePosition(); | 980 RecomputePosition(); |
| 1052 } | 981 } |
| 1053 | 982 |
| 1054 gfx::Transform Layer::transform() const { | 983 gfx::Transform Layer::transform() const { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 animator_->ResetCompositor(compositor); | 1027 animator_->ResetCompositor(compositor); |
| 1099 if (animator_->is_animating()) | 1028 if (animator_->is_animating()) |
| 1100 animator_->RemoveFromCollection(collection); | 1029 animator_->RemoveFromCollection(collection); |
| 1101 } | 1030 } |
| 1102 | 1031 |
| 1103 for (auto* child : children_) | 1032 for (auto* child : children_) |
| 1104 child->ResetCompositorForAnimatorsInTree(compositor); | 1033 child->ResetCompositorForAnimatorsInTree(compositor); |
| 1105 } | 1034 } |
| 1106 | 1035 |
| 1107 } // namespace ui | 1036 } // namespace ui |
| OLD | NEW |