ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / android / compositor / layer / content_layer.cc
blob179e757f92b3f06b772e59e02c3d56ac7f6c05d2
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
3 // found in the LICENSE file.
5 #include "chrome/browser/android/compositor/layer/content_layer.h"
7 #include "cc/layers/layer.h"
8 #include "cc/layers/layer_lists.h"
9 #include "chrome/browser/android/compositor/layer/thumbnail_layer.h"
10 #include "chrome/browser/android/compositor/tab_content_manager.h"
11 #include "ui/gfx/geometry/size.h"
13 namespace chrome {
14 namespace android {
16 // static
17 scoped_refptr<ContentLayer> ContentLayer::Create(
18 TabContentManager* tab_content_manager) {
19 return make_scoped_refptr(new ContentLayer(tab_content_manager));
22 static void SetOpacityOnLeaf(scoped_refptr<cc::Layer> layer, float alpha) {
23 const cc::LayerList& children = layer->children();
24 if (children.size() > 0) {
25 layer->SetOpacity(1.0f);
26 for (uint i = 0; i < children.size(); ++i)
27 SetOpacityOnLeaf(children[i], alpha);
28 } else {
29 layer->SetOpacity(alpha);
33 static bool DoesLeafDrawContents(scoped_refptr<cc::Layer> layer) {
34 if (!layer.get())
35 return false;
37 // TODO: Remove the need for this logic. We can't really guess from
38 // an opaque layer type whether it has valid live contents, or for example
39 // just a background color placeholder. Need to get this from somewhere else
40 // like ContentViewCore or RWHV.
41 if (layer->DrawsContent() && !layer->hide_layer_and_subtree() &&
42 !layer->background_color()) {
43 return true;
46 const cc::LayerList& children = layer->children();
47 for (unsigned i = 0; i < children.size(); i++) {
48 if (DoesLeafDrawContents(children[i]))
49 return true;
51 return false;
54 static gfx::Size GetLeafBounds(scoped_refptr<cc::Layer> layer) {
55 if (layer->children().size() > 0)
56 return GetLeafBounds(layer->children()[0]);
57 return layer->bounds();
60 void ContentLayer::SetProperties(int id,
61 bool can_use_live_layer,
62 bool can_use_ntp_fallback,
63 float static_to_view_blend,
64 bool should_override_content_alpha,
65 float content_alpha_override,
66 float saturation,
67 const gfx::Rect& desired_bounds,
68 const gfx::Size& content_size) {
69 scoped_refptr<cc::Layer> content_layer =
70 tab_content_manager_->GetLiveLayer(id);
71 ClipContentLayer(content_layer, desired_bounds, content_size);
72 bool content_layer_draws = DoesLeafDrawContents(content_layer);
74 scoped_refptr<ThumbnailLayer> static_layer =
75 tab_content_manager_->GetStaticLayer(id, !content_layer_draws);
77 ClipStaticLayer(static_layer, desired_bounds);
79 // Reset the attachment logic if the number of children doesn't match the
80 // boolean flags. At some point while a tab is in the background one or more
81 // layers may be removed from this tree.
82 // Note that this needs to be checked *after* we access TabContentManager, as
83 // that class might remove layers internally, messing up our own tracking.
84 unsigned int expected_layers = 0;
85 expected_layers += content_attached_ ? 1 : 0;
86 expected_layers += static_attached_ ? 1 : 0;
87 if (layer_->children().size() != expected_layers) {
88 content_attached_ = false;
89 static_attached_ = false;
90 const cc::LayerList& layer_children = layer_->children();
91 for (unsigned i = 0; i < layer_children.size(); i++)
92 layer_children[i]->RemoveFromParent();
95 gfx::Size content_bounds(0, 0);
96 if (!content_layer.get() || !can_use_live_layer) {
97 SetContentLayer(nullptr);
98 SetStaticLayer(static_layer);
99 if (static_layer.get())
100 content_bounds = static_layer->layer()->bounds();
101 else
102 content_bounds.set_width(content_size.width());
103 } else {
104 SetContentLayer(content_layer);
105 content_bounds = content_layer->bounds();
107 if (static_to_view_blend == 0.0f && !content_layer_draws)
108 static_to_view_blend = 1.0f;
110 if (static_to_view_blend != 0.0f && static_layer.get()) {
111 static_layer->layer()->SetOpacity(static_to_view_blend);
112 SetStaticLayer(static_layer);
113 if (content_bounds.GetArea() == 0 || !content_layer_draws)
114 content_bounds = static_layer->layer()->bounds();
115 } else {
116 SetStaticLayer(nullptr);
120 if (should_override_content_alpha) {
121 for (unsigned int i = 0; i < layer_->children().size(); ++i)
122 SetOpacityOnLeaf(layer_->children()[i], content_alpha_override);
125 if (!content_layer_draws && !static_attached_)
126 content_bounds = gfx::Size(0, 0);
128 layer_->SetBounds(content_bounds);
130 // Only worry about saturation on the static layer
131 if (static_layer.get()) {
132 if (saturation != saturation_) {
133 saturation_ = saturation;
134 cc::FilterOperations filters;
135 if (saturation_ < 1.0f)
136 filters.Append(cc::FilterOperation::CreateSaturateFilter(saturation_));
137 static_layer->layer()->SetFilters(filters);
142 gfx::Size ContentLayer::GetContentSize() {
143 if (content_attached_ && DoesLeafDrawContents(layer()->children()[0]))
144 return layer_->children()[0]->bounds();
145 return gfx::Size(0, 0);
148 scoped_refptr<cc::Layer> ContentLayer::layer() {
149 return layer_;
152 ContentLayer::ContentLayer(TabContentManager* tab_content_manager)
153 : layer_(cc::Layer::Create()),
154 content_attached_(false),
155 static_attached_(false),
156 saturation_(1.0f),
157 tab_content_manager_(tab_content_manager) {
160 ContentLayer::~ContentLayer() {
163 void ContentLayer::SetContentLayer(scoped_refptr<cc::Layer> layer) {
164 // Check indices
165 // content_attached_, expect at least 1 child.
166 DCHECK(!content_attached_ || layer_->children().size() > 0);
168 if (!layer.get()) {
169 if (content_attached_)
170 layer_->child_at(0)->RemoveFromParent();
171 content_attached_ = false;
172 return;
175 bool new_layer = false;
176 if (content_attached_ && layer_->child_at(0)->id() != layer->id()) {
177 layer_->ReplaceChild(layer_->child_at(0), layer);
178 new_layer = true;
179 } else if (!content_attached_) {
180 layer_->InsertChild(layer, 0);
181 new_layer = true;
184 // If this is a new layer, reset it's opacity.
185 if (new_layer)
186 SetOpacityOnLeaf(layer, 1.0f);
188 content_attached_ = true;
191 void ContentLayer::SetStaticLayer(
192 scoped_refptr<ThumbnailLayer> new_static_layer) {
193 // Make sure child access will be valid.
194 // !content_attached_ AND !static_attached_, expect 0 children.
195 // content_attached_ XOR static_attached_, expect 1 child.
196 // content_attached_ AND static_attached_, expect 2 children.
197 DCHECK((!content_attached_ && !static_attached_) ||
198 (content_attached_ != static_attached_ &&
199 layer_->children().size() >= 1) ||
200 (content_attached_ && static_attached_ &&
201 layer_->children().size() >= 2));
203 if (!new_static_layer.get()) {
204 if (static_layer_.get()) {
205 static_layer_->layer()->RemoveFromParent();
206 static_layer_ = nullptr;
208 static_attached_ = false;
209 return;
211 static_layer_ = new_static_layer;
212 static_layer_->AddSelfToParentOrReplaceAt(layer_, content_attached_ ? 1 : 0);
213 saturation_ = -1.0f;
214 static_layer_->layer()->SetIsDrawable(true);
215 static_attached_ = true;
218 void ContentLayer::ClipContentLayer(scoped_refptr<cc::Layer> content_layer,
219 gfx::Rect clipping,
220 gfx::Size content_size) {
221 if (!content_layer.get())
222 return;
224 gfx::Size bounds(GetLeafBounds(content_layer));
225 content_layer->SetMasksToBounds(true);
226 gfx::Size clamped_bounds(bounds);
227 clamped_bounds.SetToMin(clipping.size());
228 content_layer->SetBounds(clamped_bounds);
230 if (content_layer->children().size() > 0) {
231 gfx::PointF offset(
232 std::min(content_size.width() - bounds.width() - clipping.x(), 0),
233 std::min(content_size.height() - bounds.height() - clipping.y(), 0));
234 content_layer->children()[0]->SetPosition(offset);
238 void ContentLayer::ClipStaticLayer(scoped_refptr<ThumbnailLayer> static_layer,
239 gfx::Rect clipping) {
240 if (!static_layer.get())
241 return;
242 static_layer->Clip(clipping);
245 } // namespace android
246 } // namespace chrome