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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
ash / wm / raster_scale / raster_scale_layer_observer.h [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_RASTER_SCALE_RASTER_SCALE_LAYER_OBSERVER_H_
#define ASH_WM_RASTER_SCALE_RASTER_SCALE_LAYER_OBSERVER_H_
#include "ash/ash_export.h"
#include "ash/wm/raster_scale/raster_scale_controller.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "ui/aura/client/transient_window_client_observer.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/layer_observer.h"
namespace ash {
class RasterScaleLayerObserver;
class ScopedSetRasterScale;
// Lock which will prevent `RasterScaleLayerObserver` from deleting itself
// while it is in scope. This is used to decide when to apply raster scale
// semantics, e.g. in overview mode.
class ScopedRasterScaleLayerObserverLock {
public:
explicit ScopedRasterScaleLayerObserverLock(
base::WeakPtr<RasterScaleLayerObserver> observer);
ScopedRasterScaleLayerObserverLock(ScopedRasterScaleLayerObserverLock&&);
ScopedRasterScaleLayerObserverLock& operator=(
ScopedRasterScaleLayerObserverLock&&);
ScopedRasterScaleLayerObserverLock(
const ScopedRasterScaleLayerObserverLock&) = delete;
ScopedRasterScaleLayerObserverLock& operator=(
const ScopedRasterScaleLayerObserverLock&) = delete;
~ScopedRasterScaleLayerObserverLock();
private:
base::WeakPtr<RasterScaleLayerObserver> observer_;
};
// This class dynamically updates raster scale based on the scale of the given
// window. The scale is observed by looking at changes in layer animations and
// window properties. This is used, for example, in overview mode to dynamically
// reduce the raster scale of lacros windows. Check the comments on member
// variables of this class for more details.
class RasterScaleLayerObserver
: public ui::LayerAnimationObserver,
public aura::WindowObserver,
public aura::client::TransientWindowClientObserver,
public ui::LayerObserver {
public:
explicit RasterScaleLayerObserver(aura::Window* observe_window,
ui::Layer* observe_layer,
aura::Window* apply_window);
RasterScaleLayerObserver(const RasterScaleLayerObserver&) = delete;
RasterScaleLayerObserver& operator=(const RasterScaleLayerObserver&) = delete;
~RasterScaleLayerObserver() override;
ScopedRasterScaleLayerObserverLock Lock() {
return ScopedRasterScaleLayerObserverLock(weak_ptr_factory_.GetWeakPtr());
}
// ui::LayerAnimationObserver
void OnLayerAnimationStarted(ui::LayerAnimationSequence* sequence) override;
void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override;
void OnLayerAnimationWillRepeat(
ui::LayerAnimationSequence* sequence) override;
void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override;
void OnLayerAnimationScheduled(ui::LayerAnimationSequence* sequence) override;
// aura::WindowObserver:
void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
void OnWindowDestroying(aura::Window* window) override;
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) override;
void OnWindowTransformed(aura::Window* window,
ui::PropertyChangeReason reason) override;
void OnWindowLayerRecreated(aura::Window* window) override;
// ui::LayerObserver:
void LayerDestroyed(ui::Layer* layer) override;
// aura::client::TransientWindowClientObserver:
void OnTransientChildWindowAdded(aura::Window* parent,
aura::Window* transient_child) override;
void OnTransientChildWindowRemoved(aura::Window* parent,
aura::Window* transient_child) override;
private:
friend class ScopedRasterScaleLayerObserverLock;
void SetRasterScales(float raster_scale);
void UpdateRasterScaleFromTransform(const gfx::Transform& transform);
void IncrementRefCount();
void DecrementRefCount();
// be careful if this is not the last call in the function.
void MaybeShutdown();
// Window to observe window property changes on. This is
// different to `apply_window_` to handle mirror windows. We want to observe
// the mirrored window, but apply raster scale changes to the original window.
raw_ptr<aura::Window> observe_window_ = nullptr;
// Layer to observe layer animations on. This is not `observe_window_`'s layer
// in the case of mirrored windows. In that case, it is the mirrored layer,
// which is not the same as the layer corresponding to `observe_window_`.
raw_ptr<ui::Layer> observe_layer_ = nullptr;
// Window to apply raster scale changes to. This is the same as
// `observe_window_` if there is no window mirroring occurring. This should
// correspond to a window which can update the underlying raster scale for its
// content.
raw_ptr<aura::Window> apply_window_ = nullptr;
// We need to hold onto transient windows to apply the same raster scale to
// them as the main `apply_window_`, and to unapply them when they are done.
// The raster scale locks for transient windows are held in `raster_scales_`.
base::flat_set<raw_ptr<aura::Window, CtnExperimental>> transient_windows_;
// Holds raster scale locks for windows. This will be `apply_window_` plus any
// transient children windows.
base::flat_map<aura::Window*, std::unique_ptr<ScopedSetRasterScale>>
raster_scales_;
// `RasterScaleLayerObserver` has complicated lifetime semantics. It will stay
// alive (not be deleted) until there are no
// `ScopedRasterScaleLayerObserverLock` locks and there are no animations
// referencing `observe_layer_`. If neither of these conditions is true, it
// will delete itself. The reason for the lock so we only create
// `RasterScaleLayerObserver` when it is necessary (e.g. overview mode) to
// avoid introducing a long tail of unknown situations to raster scale
// updates. The reason for counting animations is that animations may continue
// after locks are destroyed. For example, exiting overview will immediately
// destroy locks, but we need to keep the raster scales until the animation
// finishes.
int animation_count_ = 0;
int ref_count_ = 0;
base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
windows_observation_{this};
base::WeakPtrFactory<RasterScaleLayerObserver> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_WM_RASTER_SCALE_RASTER_SCALE_LAYER_OBSERVER_H_