File: content_layer.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (152 lines) | stat: -rw-r--r-- 4,558 bytes parent folder | download | duplicates (6)
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