| 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 "chrome/browser/android/compositor/layer/content_layer.h" | 5 #include "chrome/browser/android/compositor/layer/content_layer.h" |
| 6 | 6 |
| 7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "cc/layers/layer.h" | 8 #include "cc/layers/layer.h" |
| 9 #include "cc/layers/layer_collections.h" | 9 #include "cc/layers/layer_collections.h" |
| 10 #include "cc/output/filter_operations.h" |
| 10 #include "chrome/browser/android/compositor/layer/thumbnail_layer.h" | 11 #include "chrome/browser/android/compositor/layer/thumbnail_layer.h" |
| 11 #include "chrome/browser/android/compositor/tab_content_manager.h" | 12 #include "chrome/browser/android/compositor/tab_content_manager.h" |
| 12 #include "content/public/browser/android/compositor.h" | 13 #include "content/public/browser/android/compositor.h" |
| 13 #include "ui/gfx/geometry/size.h" | 14 #include "ui/gfx/geometry/size.h" |
| 14 | 15 |
| 15 namespace android { | 16 namespace android { |
| 16 | 17 |
| 17 // static | 18 // static |
| 18 scoped_refptr<ContentLayer> ContentLayer::Create( | 19 scoped_refptr<ContentLayer> ContentLayer::Create( |
| 19 TabContentManager* tab_content_manager) { | 20 TabContentManager* tab_content_manager) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 } | 55 } |
| 55 return false; | 56 return false; |
| 56 } | 57 } |
| 57 | 58 |
| 58 void ContentLayer::SetProperties(int id, | 59 void ContentLayer::SetProperties(int id, |
| 59 bool can_use_live_layer, | 60 bool can_use_live_layer, |
| 60 float static_to_view_blend, | 61 float static_to_view_blend, |
| 61 bool should_override_content_alpha, | 62 bool should_override_content_alpha, |
| 62 float content_alpha_override, | 63 float content_alpha_override, |
| 63 float saturation, | 64 float saturation, |
| 64 const gfx::Rect& desired_bounds, | 65 bool should_clip, |
| 65 const gfx::Size& content_size) { | 66 const gfx::Rect& clip) { |
| 66 scoped_refptr<cc::Layer> content_layer = | 67 scoped_refptr<cc::Layer> content_layer = |
| 67 tab_content_manager_->GetLiveLayer(id); | 68 tab_content_manager_->GetLiveLayer(id); |
| 68 ClipContentLayer(content_layer, desired_bounds); | |
| 69 bool content_layer_draws = DoesLeafDrawContents(content_layer); | 69 bool content_layer_draws = DoesLeafDrawContents(content_layer); |
| 70 | 70 |
| 71 scoped_refptr<ThumbnailLayer> static_layer = | 71 scoped_refptr<ThumbnailLayer> static_layer = |
| 72 tab_content_manager_->GetStaticLayer( | 72 tab_content_manager_->GetStaticLayer( |
| 73 id, !(can_use_live_layer && content_layer_draws)); | 73 id, !(can_use_live_layer && content_layer_draws)); |
| 74 | 74 |
| 75 ClipStaticLayer(static_layer, desired_bounds); | 75 float content_opacity = |
| 76 should_override_content_alpha ? content_alpha_override : 1.0f; |
| 77 float static_opacity = |
| 78 should_override_content_alpha ? content_alpha_override : 1.0f; |
| 79 if (content_layer.get() && can_use_live_layer && content_layer_draws) |
| 80 static_opacity = static_to_view_blend; |
| 81 if (!can_use_live_layer) |
| 82 content_opacity = 0.0f; |
| 76 | 83 |
| 77 // Reset the attachment logic if the number of children doesn't match the | 84 const cc::LayerList& layer_children = layer_->children(); |
| 78 // boolean flags. At some point while a tab is in the background one or more | 85 for (unsigned i = 0; i < layer_children.size(); i++) |
| 79 // layers may be removed from this tree. | 86 layer_children[i]->RemoveFromParent(); |
| 80 // Note that this needs to be checked *after* we access TabContentManager, as | 87 |
| 81 // that class might remove layers internally, messing up our own tracking. | 88 if (content_layer.get()) { |
| 82 unsigned int expected_layers = 0; | 89 content_layer->SetMasksToBounds(should_clip); |
| 83 expected_layers += content_attached_ ? 1 : 0; | 90 content_layer->SetBounds(clip.size()); |
| 84 expected_layers += static_attached_ ? 1 : 0; | 91 SetOpacityOnLeaf(content_layer, content_opacity); |
| 85 if (layer_->children().size() != expected_layers) { | 92 |
| 86 content_attached_ = false; | 93 layer_->AddChild(content_layer); |
| 87 static_attached_ = false; | |
| 88 const cc::LayerList& layer_children = layer_->children(); | |
| 89 for (unsigned i = 0; i < layer_children.size(); i++) | |
| 90 layer_children[i]->RemoveFromParent(); | |
| 91 } | 94 } |
| 95 if (static_layer.get()) { |
| 96 static_layer->layer()->SetIsDrawable(true); |
| 97 if (should_clip) |
| 98 static_layer->Clip(clip); |
| 99 else |
| 100 static_layer->ClearClip(); |
| 101 SetOpacityOnLeaf(static_layer->layer(), static_opacity); |
| 92 | 102 |
| 93 gfx::Size content_bounds(0, 0); | 103 cc::FilterOperations static_filter_operations; |
| 94 if (!content_layer.get() || !can_use_live_layer) { | |
| 95 SetContentLayer(nullptr); | |
| 96 SetStaticLayer(static_layer); | |
| 97 if (static_layer.get()) | |
| 98 content_bounds = static_layer->layer()->bounds(); | |
| 99 else | |
| 100 content_bounds.set_width(content_size.width()); | |
| 101 } else { | |
| 102 SetContentLayer(content_layer); | |
| 103 content_bounds = content_layer->bounds(); | |
| 104 | |
| 105 if (static_to_view_blend == 0.0f && !content_layer_draws) | |
| 106 static_to_view_blend = 1.0f; | |
| 107 | |
| 108 if (static_to_view_blend != 0.0f && static_layer.get()) { | |
| 109 static_layer->layer()->SetOpacity(static_to_view_blend); | |
| 110 SetStaticLayer(static_layer); | |
| 111 if (content_bounds.GetArea() == 0 || !content_layer_draws) | |
| 112 content_bounds = static_layer->layer()->bounds(); | |
| 113 } else { | |
| 114 SetStaticLayer(nullptr); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 if (should_override_content_alpha) { | |
| 119 for (unsigned int i = 0; i < layer_->children().size(); ++i) | |
| 120 SetOpacityOnLeaf(layer_->children()[i], content_alpha_override); | |
| 121 } | |
| 122 | |
| 123 if (!content_layer_draws && !static_attached_) | |
| 124 content_bounds = gfx::Size(0, 0); | |
| 125 | |
| 126 layer_->SetBounds(content_bounds); | |
| 127 | |
| 128 // Only worry about saturation on the static layer. | |
| 129 if (static_layer.get()) { | |
| 130 static_filter_operations_.Clear(); | |
| 131 if (saturation < 1.0f) { | 104 if (saturation < 1.0f) { |
| 132 static_filter_operations_.Append( | 105 static_filter_operations.Append( |
| 133 cc::FilterOperation::CreateSaturateFilter(saturation)); | 106 cc::FilterOperation::CreateSaturateFilter(saturation)); |
| 134 } | 107 } |
| 135 static_layer->layer()->SetFilters(static_filter_operations_); | 108 static_layer->layer()->SetFilters(static_filter_operations); |
| 109 |
| 110 layer_->AddChild(static_layer->layer()); |
| 136 } | 111 } |
| 137 } | 112 } |
| 138 | 113 |
| 139 gfx::Size ContentLayer::GetContentSize() { | |
| 140 if (content_attached_ && DoesLeafDrawContents(layer()->children()[0])) | |
| 141 return layer_->children()[0]->bounds(); | |
| 142 return gfx::Size(0, 0); | |
| 143 } | |
| 144 | |
| 145 scoped_refptr<cc::Layer> ContentLayer::layer() { | 114 scoped_refptr<cc::Layer> ContentLayer::layer() { |
| 146 return layer_; | 115 return layer_; |
| 147 } | 116 } |
| 148 | 117 |
| 149 ContentLayer::ContentLayer(TabContentManager* tab_content_manager) | 118 ContentLayer::ContentLayer(TabContentManager* tab_content_manager) |
| 150 : layer_(cc::Layer::Create()), | 119 : layer_(cc::Layer::Create()), |
| 151 content_attached_(false), | |
| 152 static_attached_(false), | |
| 153 tab_content_manager_(tab_content_manager) {} | 120 tab_content_manager_(tab_content_manager) {} |
| 154 | 121 |
| 155 ContentLayer::~ContentLayer() { | 122 ContentLayer::~ContentLayer() { |
| 156 } | 123 } |
| 157 | 124 |
| 158 void ContentLayer::SetContentLayer(scoped_refptr<cc::Layer> layer) { | |
| 159 // Check indices | |
| 160 // content_attached_, expect at least 1 child. | |
| 161 DCHECK(!content_attached_ || layer_->children().size() > 0); | |
| 162 | |
| 163 if (!layer.get()) { | |
| 164 if (content_attached_) | |
| 165 layer_->child_at(0)->RemoveFromParent(); | |
| 166 content_attached_ = false; | |
| 167 return; | |
| 168 } | |
| 169 | |
| 170 bool new_layer = false; | |
| 171 if (content_attached_ && layer_->child_at(0)->id() != layer->id()) { | |
| 172 layer_->ReplaceChild(layer_->child_at(0), layer); | |
| 173 new_layer = true; | |
| 174 } else if (!content_attached_) { | |
| 175 layer_->InsertChild(layer, 0); | |
| 176 new_layer = true; | |
| 177 } | |
| 178 | |
| 179 // If this is a new layer, reset it's opacity. | |
| 180 if (new_layer) | |
| 181 SetOpacityOnLeaf(layer, 1.0f); | |
| 182 | |
| 183 content_attached_ = true; | |
| 184 } | |
| 185 | |
| 186 void ContentLayer::SetStaticLayer( | |
| 187 scoped_refptr<ThumbnailLayer> new_static_layer) { | |
| 188 // Make sure child access will be valid. | |
| 189 // !content_attached_ AND !static_attached_, expect 0 children. | |
| 190 // content_attached_ XOR static_attached_, expect 1 child. | |
| 191 // content_attached_ AND static_attached_, expect 2 children. | |
| 192 DCHECK((!content_attached_ && !static_attached_) || | |
| 193 (content_attached_ != static_attached_ && | |
| 194 layer_->children().size() >= 1) || | |
| 195 (content_attached_ && static_attached_ && | |
| 196 layer_->children().size() >= 2)); | |
| 197 | |
| 198 if (!new_static_layer.get()) { | |
| 199 if (static_layer_.get()) { | |
| 200 static_layer_->layer()->RemoveFromParent(); | |
| 201 static_layer_ = nullptr; | |
| 202 } | |
| 203 static_attached_ = false; | |
| 204 return; | |
| 205 } | |
| 206 static_layer_ = new_static_layer; | |
| 207 static_layer_->AddSelfToParentOrReplaceAt(layer_, content_attached_ ? 1 : 0); | |
| 208 static_layer_->layer()->SetIsDrawable(true); | |
| 209 static_attached_ = true; | |
| 210 } | |
| 211 | |
| 212 void ContentLayer::ClipContentLayer(scoped_refptr<cc::Layer> content_layer, | |
| 213 gfx::Rect clipping) { | |
| 214 if (!content_layer.get()) | |
| 215 return; | |
| 216 | |
| 217 content_layer->SetMasksToBounds(true); | |
| 218 content_layer->SetBounds(clipping.size()); | |
| 219 } | |
| 220 | |
| 221 void ContentLayer::ClipStaticLayer(scoped_refptr<ThumbnailLayer> static_layer, | |
| 222 gfx::Rect clipping) { | |
| 223 if (!static_layer.get()) | |
| 224 return; | |
| 225 static_layer->Clip(clipping); | |
| 226 } | |
| 227 | |
| 228 } // namespace android | 125 } // namespace android |
| OLD | NEW |