blob: d40948f8a57006a62698083ae433c08544729e79 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/compositor/layer/content_layer.h"
#include "base/lazy_instance.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_collections.h"
#include "cc/paint/filter_operations.h"
#include "chrome/browser/android/compositor/layer/thumbnail_layer.h"
#include "chrome/browser/android/compositor/tab_content_manager.h"
#include "ui/gfx/geometry/size.h"
namespace android {
// static
scoped_refptr<ContentLayer> ContentLayer::Create(
TabContentManager* tab_content_manager) {
return base::WrapRefCounted(new ContentLayer(tab_content_manager));
}
static void SetOpacityOnLeaf(scoped_refptr<cc::Layer> layer, float alpha) {
const cc::LayerList& children = layer->children();
if (children.size() > 0) {
layer->SetOpacity(1.0f);
for (uint i = 0; i < children.size(); ++i)
SetOpacityOnLeaf(children[i], alpha);
} else {
layer->SetOpacity(alpha);
}
}
static cc::Layer* GetDrawsContentLeaf(scoped_refptr<cc::Layer> layer) {
if (!layer.get())
return nullptr;
// If the subtree is hidden, then any layers in this tree will not be drawn.
if (layer->hide_layer_and_subtree())
return nullptr;
if (layer->opacity() == 0.0f)
return nullptr;
if (layer->draws_content())
return layer.get();
const cc::LayerList& children = layer->children();
for (unsigned i = 0; i < children.size(); i++) {
cc::Layer* leaf = GetDrawsContentLeaf(children[i]);
if (leaf)
return leaf;
}
return nullptr;
}
void ContentLayer::SetProperties(int id,
bool can_use_live_layer,
float static_to_view_blend,
bool should_override_content_alpha,
float content_alpha_override,
float saturation,
bool should_clip,
const gfx::Rect& clip) {
scoped_refptr<cc::Layer> live_layer = tab_content_manager_->GetLiveLayer(id);
if (live_layer)
live_layer->SetHideLayerAndSubtree(!can_use_live_layer);
bool live_layer_draws = GetDrawsContentLeaf(live_layer);
float content_opacity =
should_override_content_alpha ? content_alpha_override : 1.0f;
float static_opacity =
should_override_content_alpha ? content_alpha_override : 1.0f;
if (live_layer_draws)
static_opacity = static_to_view_blend;
const cc::LayerList& layer_children = layer_->children();
for (unsigned i = 0; i < layer_children.size(); i++)
layer_children[i]->RemoveFromParent();
if (live_layer.get()) {
live_layer->SetMasksToBounds(should_clip);
live_layer->SetBounds(clip.size());
SetOpacityOnLeaf(live_layer, content_opacity);
layer_->AddChild(live_layer);
}
if (static_opacity > 0) {
scoped_refptr<ThumbnailLayer> static_layer =
tab_content_manager_->GetOrCreateStaticLayer(id, !live_layer_draws);
if (static_layer.get()) {
static_layer->layer()->SetIsDrawable(true);
if (should_clip)
static_layer->Clip(clip);
else
static_layer->ClearClip();
SetOpacityOnLeaf(static_layer->layer(), static_opacity);
cc::FilterOperations static_filter_operations;
if (saturation < 1.0f) {
static_filter_operations.Append(
cc::FilterOperation::CreateSaturateFilter(saturation));
}
static_layer->layer()->SetFilters(static_filter_operations);
layer_->AddChild(static_layer->layer());
}
}
}
gfx::Size ContentLayer::ComputeSize(int id) const {
gfx::Size size;
scoped_refptr<cc::Layer> live_layer = tab_content_manager_->GetLiveLayer(id);
cc::Layer* leaf_that_draws = GetDrawsContentLeaf(live_layer);
if (leaf_that_draws)
size.SetToMax(leaf_that_draws->bounds());
scoped_refptr<ThumbnailLayer> static_layer =
tab_content_manager_->GetStaticLayer(id);
if (static_layer.get() && GetDrawsContentLeaf(static_layer->layer()))
size.SetToMax(static_layer->layer()->bounds());
return size;
}
scoped_refptr<cc::Layer> ContentLayer::layer() {
return layer_;
}
ContentLayer::ContentLayer(TabContentManager* tab_content_manager)
: layer_(cc::Layer::Create()),
tab_content_manager_(tab_content_manager) {}
ContentLayer::~ContentLayer() {
}
} // namespace android