1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
// Copyright 2014 The Chromium Authors
// 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 <vector>
#include "base/lazy_instance.h"
#include "cc/slim/filter.h"
#include "cc/slim/layer.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::slim::Layer> layer,
float alpha) {
const auto& children = layer->children();
if (!children.empty()) {
layer->SetOpacity(1.0f);
for (const auto& child : children) {
SetOpacityOnLeaf(child, alpha);
}
} else {
layer->SetOpacity(alpha);
}
}
static cc::slim::Layer* GetDrawsContentLeaf(
scoped_refptr<cc::slim::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 auto& children = layer->children();
for (const auto& child : children) {
cc::slim::Layer* leaf = GetDrawsContentLeaf(child);
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::slim::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;
}
layer_->RemoveAllChildren();
if (live_layer.get()) {
live_layer->SetMasksToBounds(should_clip);
live_layer->SetBounds(clip.size());
// Don't override the opacity for layers internal to the WebContents.
live_layer->SetOpacity(content_opacity);
layer_->AddChild(live_layer);
}
if (static_opacity > 0) {
ThumbnailLayer* static_layer = tab_content_manager_->GetStaticLayer(id);
if (static_layer) {
static_layer->layer()->SetIsDrawable(true);
if (should_clip) {
static_layer->Clip(clip);
} else {
static_layer->ClearClip();
}
// TOOD(liuwilliam): The opacity should only need to be set on the static
// layer, instead of all its children. The recursive setting was a
// workaround for some old CC bug.
SetOpacityOnLeaf(static_layer->layer(), static_opacity);
std::vector<cc::slim::Filter> filters;
if (saturation < 1.0f) {
filters.push_back(cc::slim::Filter::CreateSaturation(saturation));
}
static_layer->layer()->SetFilters(std::move(filters));
layer_->AddChild(static_layer->layer());
}
}
}
gfx::Size ContentLayer::ComputeSize(int id) const {
gfx::Size size;
scoped_refptr<cc::slim::Layer> live_layer =
tab_content_manager_->GetLiveLayer(id);
cc::slim::Layer* leaf_that_draws = GetDrawsContentLeaf(live_layer);
if (leaf_that_draws) {
size.SetToMax(leaf_that_draws->bounds());
}
ThumbnailLayer* static_layer = tab_content_manager_->GetStaticLayer(id);
if (static_layer && GetDrawsContentLeaf(static_layer->layer())) {
size.SetToMax(static_layer->layer()->bounds());
}
return size;
}
scoped_refptr<cc::slim::Layer> ContentLayer::layer() {
return layer_;
}
ContentLayer::ContentLayer(TabContentManager* tab_content_manager)
: layer_(cc::slim::Layer::Create()),
tab_content_manager_(tab_content_manager) {}
ContentLayer::~ContentLayer() = default;
} // namespace android
|