1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/slim/surface_layer.h"
10 #include "cc/layers/surface_layer.h"
11 #include "cc/slim/features.h"
12 #include "cc/slim/layer_tree_impl.h"
13 #include "components/viz/common/hit_test/hit_test_region_list.h"
14 #include "components/viz/common/quads/compositor_render_pass.h"
15 #include "components/viz/common/quads/solid_color_draw_quad.h"
16 #include "components/viz/common/quads/surface_draw_quad.h"
17 #include "components/viz/common/surfaces/surface_range.h"
22 scoped_refptr<SurfaceLayer> SurfaceLayer::Create() {
23 scoped_refptr<cc::SurfaceLayer> cc_layer;
24 if (!features::IsSlimCompositorEnabled()) {
25 cc_layer = cc::SurfaceLayer::Create();
27 return base::AdoptRef(new SurfaceLayer(std::move(cc_layer)));
30 SurfaceLayer::SurfaceLayer(scoped_refptr<cc::SurfaceLayer> cc_layer)
31 : Layer(std::move(cc_layer)) {
32 if (this->cc_layer()) {
33 this->cc_layer()->SetSurfaceHitTestable(true);
37 SurfaceLayer::~SurfaceLayer() = default;
39 cc::SurfaceLayer* SurfaceLayer::cc_layer() const {
40 return static_cast<cc::SurfaceLayer*>(cc_layer_.get());
43 const viz::SurfaceId& SurfaceLayer::surface_id() const {
44 return cc_layer() ? cc_layer()->surface_id() : surface_range_.end();
47 void SurfaceLayer::SetSurfaceId(const viz::SurfaceId& surface_id,
48 const cc::DeadlinePolicy& deadline_policy) {
50 cc_layer()->SetSurfaceId(surface_id, deadline_policy);
53 if (surface_range_.end() == surface_id &&
54 deadline_policy.use_existing_deadline()) {
58 SetSurfaceRange(viz::SurfaceRange(surface_range_.start(), surface_id));
59 if (!surface_range_.IsValid()) {
60 deadline_in_frames_ = 0u;
61 } else if (!deadline_policy.use_existing_deadline()) {
62 deadline_in_frames_ = deadline_policy.deadline_in_frames();
66 void SurfaceLayer::SetStretchContentToFillBounds(
67 bool stretch_content_to_fill_bounds) {
69 cc_layer()->SetStretchContentToFillBounds(stretch_content_to_fill_bounds);
72 if (stretch_content_to_fill_bounds_ == stretch_content_to_fill_bounds) {
75 stretch_content_to_fill_bounds_ = stretch_content_to_fill_bounds;
76 NotifyPropertyChanged();
79 bool SurfaceLayer::stretch_content_to_fill_bounds() const {
80 return cc_layer() ? cc_layer()->stretch_content_to_fill_bounds()
81 : stretch_content_to_fill_bounds_;
84 void SurfaceLayer::SetMayContainVideo(bool may_contain_video) {
86 cc_layer()->SetMayContainVideo(may_contain_video);
89 // No slim implementation. This method probably should not exist.
93 void SurfaceLayer::SetOldestAcceptableFallback(
94 const viz::SurfaceId& surface_id) {
96 cc_layer()->SetOldestAcceptableFallback(surface_id);
99 // The fallback should never move backwards.
100 DCHECK(!surface_range_.start() ||
101 !surface_range_.start()->IsNewerThan(surface_id));
102 if (surface_range_.start() == surface_id) {
106 SetSurfaceRange(viz::SurfaceRange(
107 surface_id.is_valid() ? absl::optional<viz::SurfaceId>(surface_id)
109 surface_range_.end()));
112 const absl::optional<viz::SurfaceId>& SurfaceLayer::oldest_acceptable_fallback()
114 return cc_layer() ? cc_layer()->oldest_acceptable_fallback()
115 : surface_range_.start();
118 void SurfaceLayer::SetLayerTree(LayerTree* tree) {
120 Layer::SetLayerTree(tree);
124 if (layer_tree() == tree) {
128 if (layer_tree() && surface_range_.IsValid()) {
129 static_cast<LayerTreeImpl*>(layer_tree())
130 ->RemoveSurfaceRange(surface_range_);
132 Layer::SetLayerTree(tree);
133 if (layer_tree() && surface_range_.IsValid()) {
134 static_cast<LayerTreeImpl*>(layer_tree())->AddSurfaceRange(surface_range_);
138 void SurfaceLayer::SetSurfaceRange(const viz::SurfaceRange& surface_range) {
140 if (surface_range_ == surface_range) {
143 if (layer_tree() && surface_range_.IsValid()) {
144 static_cast<LayerTreeImpl*>(layer_tree())
145 ->RemoveSurfaceRange(surface_range_);
147 surface_range_ = surface_range;
148 if (layer_tree() && surface_range_.IsValid()) {
149 static_cast<LayerTreeImpl*>(layer_tree())->AddSurfaceRange(surface_range_);
151 NotifyPropertyChanged();
154 void SurfaceLayer::AppendQuads(viz::CompositorRenderPass& render_pass,
156 const gfx::Transform& transform_to_root,
157 const gfx::Transform& transform_to_target,
158 const gfx::Rect* clip_in_target,
159 const gfx::Rect& visible_rect,
161 viz::SharedQuadState* quad_state =
162 CreateAndAppendSharedQuadState(render_pass, data, transform_to_target,
163 clip_in_target, visible_rect, opacity);
165 if (surface_range_.IsValid()) {
166 auto* quad = render_pass.CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
167 quad->SetNew(quad_state, quad_state->quad_layer_rect,
168 quad_state->visible_quad_layer_rect, surface_range_,
169 background_color(), stretch_content_to_fill_bounds_);
171 data.activation_dependencies.insert(surface_range_.end());
173 if (deadline_in_frames_) {
174 if (!data.deadline_in_frames) {
175 data.deadline_in_frames = 0u;
177 data.deadline_in_frames =
178 std::max(*data.deadline_in_frames, *deadline_in_frames_);
180 data.use_default_lower_bound_deadline = true;
183 auto& hit_test_region = data.hit_test_regions->emplace_back();
184 hit_test_region.flags = viz::HitTestRegionFlags::kHitTestMouse |
185 viz::HitTestRegionFlags::kHitTestTouch |
186 viz::HitTestRegionFlags::kHitTestChildSurface;
187 hit_test_region.frame_sink_id = surface_range_.end().frame_sink_id();
188 hit_test_region.rect = quad_state->visible_quad_layer_rect;
189 // False will set transform to identity.
190 bool rv = transform_to_root.GetInverse(&hit_test_region.transform);
191 if (!rv || !hit_test_region.transform.Preserves2dAxisAlignment()) {
192 hit_test_region.flags |= viz::HitTestRegionFlags::kHitTestAsk;
193 hit_test_region.async_hit_test_reasons |=
194 viz::AsyncHitTestReasons::kIrregularClip;
197 auto* quad = render_pass.CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
198 quad->SetNew(quad_state, quad_state->quad_layer_rect,
199 quad_state->visible_quad_layer_rect, background_color(),
200 false /* force_anti_aliasing_off */);
203 // Unless the client explicitly calls SetSurfaceId again after this
204 // commit, don't block on |surface_range_| again.
205 deadline_in_frames_ = 0u;
208 } // namespace cc::slim