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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_SURFACE_TREE_HOST_H_
#define COMPONENTS_EXO_SURFACE_TREE_HOST_H_
#include <memory>
#include <set>
#include "base/containers/queue.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/exo/surface.h"
#include "components/exo/surface_delegate.h"
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "ui/display/display_observer.h"
#include "ui/display/types/display_constants.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
namespace aura {
class Window;
} // namespace aura
namespace viz {
class RasterContextProvider;
}
namespace exo {
class LayerTreeFrameSinkHolder;
// This class provides functionality for hosting a surface tree. The surface
// tree is hosted in the |host_window_|.
class SurfaceTreeHost : public SurfaceDelegate,
public display::DisplayObserver,
public ui::LayerOwner::Observer,
public viz::ContextLostObserver {
public:
explicit SurfaceTreeHost(const std::string& window_name);
SurfaceTreeHost(const std::string& window_name,
std::unique_ptr<aura::Window> host_window);
SurfaceTreeHost(const SurfaceTreeHost&) = delete;
SurfaceTreeHost& operator=(const SurfaceTreeHost&) = delete;
~SurfaceTreeHost() override;
// Sets a root surface of a surface tree. This surface tree will be hosted in
// the |host_window_|.
virtual void SetRootSurface(Surface* root_surface);
// Returns false if the hit test region is empty.
bool HasHitTestRegion() const;
// Sets |mask| to the path that delineates the hit test region of the hosted
// surface tree.
void GetHitTestMask(SkPath* mask) const;
// Call this to indicate that the previous CompositorFrame is processed and
// the surface is being scheduled for a draw.
virtual void DidReceiveCompositorFrameAck();
// Call this to indicate that the CompositorFrame with given
// |presentation_token| has been first time presented to user.
void DidPresentCompositorFrame(uint32_t presentation_token,
const gfx::PresentationFeedback& feedback);
// Sets the scale factor for all buffers associated with this surface. This
// affects all future commits.
void SetScaleFactor(float scale_factor);
aura::Window* host_window() { return host_window_.get(); }
const aura::Window* host_window() const { return host_window_.get(); }
Surface* root_surface() { return root_surface_; }
const Surface* root_surface() const { return root_surface_; }
const gfx::Point& root_surface_origin_pixel() const {
return root_surface_origin_pixel_;
}
LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder() {
return layer_tree_frame_sink_holder_.get();
}
using PresentationCallbacks = std::list<Surface::PresentationCallback>;
base::queue<std::list<Surface::FrameCallback>>&
GetFrameCallbacksForTesting() {
return frame_callbacks_;
}
base::flat_map<uint32_t, PresentationCallbacks>&
GetActivePresentationCallbacksForTesting() {
return active_presentation_callbacks_;
}
uint32_t GenerateNextFrameToken() { return ++next_token_; }
// SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override;
bool IsInputEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override {}
void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override {
}
void OnSetParent(Surface* parent, const gfx::Point& position) override {}
void OnSetStartupId(const char* startup_id) override {}
void OnSetApplicationId(const char* application_id) override {}
void SetUseImmersiveForFullscreen(bool value) override {}
void OnActivationRequested() override {}
void OnNewOutputAdded() override;
void OnSetServerStartResize() override {}
void ShowSnapPreviewToPrimary() override {}
void ShowSnapPreviewToSecondary() override {}
void HideSnapPreview() override {}
void SetSnapPrimary(float snap_ratio) override {}
void SetSnapSecondary(float snap_ratio) override {}
void UnsetSnap() override {}
void SetCanGoBack() override {}
void UnsetCanGoBack() override {}
void SetPip() override {}
void UnsetPip() override {}
void SetFloatToLocation(
chromeos::FloatStartLocation float_start_location) override {}
void SetAspectRatio(const gfx::SizeF& aspect_ratio) override {}
void MoveToDesk(int desk_index) override {}
void SetVisibleOnAllWorkspaces() override {}
void SetInitialWorkspace(const char* initial_workspace) override {}
void Pin(bool trusted) override {}
void Unpin() override {}
void SetSystemModal(bool system_modal) override {}
void SetTopInset(int height) override {}
SecurityDelegate* GetSecurityDelegate() override;
// display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
// viz::ContextLostObserver:
void OnContextLost() override;
void set_client_submits_surfaces_in_pixel_coordinates(bool enabled) {
client_submits_surfaces_in_pixel_coordinates_ = enabled;
}
void SetSecurityDelegate(SecurityDelegate* security_delegate);
void SubmitCompositorFrameForTesting(viz::CompositorFrame frame);
using LayerTreeFrameSinkHolderFactory =
base::RepeatingCallback<std::unique_ptr<LayerTreeFrameSinkHolder>()>;
// It should only be used at initialization time before any frames are
// submitted.
void SetLayerTreeFrameSinkHolderFactoryForTesting(
LayerTreeFrameSinkHolderFactory frame_sink_holder_factory);
// Creates a LayerTreeFrameSink for the |host_window_|.
std::unique_ptr<cc::mojo_embedder::AsyncLayerTreeFrameSink>
CreateLayerTreeFrameSink();
// Overridden from ui::LayerOwner::Observer
void OnLayerRecreated(ui::Layer* old_layer) override;
// Applies rounded_corner_bounds (bounds + radii_in_dps) to the surface tree.
// `rounded_corner_bounds` should be in the coordinate space of the
void ApplyRoundedCornersToSurfaceTree(
const gfx::RectF& bounds,
const gfx::RoundedCornersF& radii_in_dps);
protected:
void UpdateDisplayOnTree();
// Call this after a buffer has been committed but before a compositor frame
// has been submitted.
void WillCommit();
// Call this to submit a compositor frame.
void SubmitCompositorFrame();
// Call this to submit an empty compositor frame. This may be useful if
// the surface tree is becoming invisible but the resources (e.g. buffers)
// need to be released back to the client.
void SubmitEmptyCompositorFrame();
// Updates the host window's size to cover surfaces that must be visible and
// not clipped.
// It also updates root surface origin accordingly to the origin.
void UpdateHostWindowSizeAndRootSurfaceOrigin();
bool client_submits_surfaces_in_pixel_coordinates() const {
return client_submits_surfaces_in_pixel_coordinates_;
}
bool bounds_is_dirty() const { return bounds_is_dirty_; }
void set_bounds_is_dirty(bool bounds_is_dirty) {
bounds_is_dirty_ = bounds_is_dirty;
}
// If the client has submitted a scale factor, we use that. Otherwise we use
// the host window's layer's scale factor.
virtual float GetScaleFactor() const;
virtual float GetPendingScaleFactor() const;
bool HasDoubleBufferedPendingScaleFactor() const;
// Sets the appropriate transform for the given scale factor.
// NOTE: This should only be done if the client submits in pixel coordinates.
void SetScaleFactorTransform(float scale_factor);
// Once a configure is acknowledged, accept the parent portion of the
// local_surface_id from the |host_window_|.
void UpdateLocalSurfaceIdFromParent(
const viz::LocalSurfaceId& parent_local_surface_id);
// Changes the local_surface_id as the viz::Surface property will change.
void AllocateLocalSurfaceId();
// If local_surface_id is newer than |host_window_|'s ui layer, push the
// current local_surface_id to |host_window_| and its ui layer to produce a
// different SurfaceDrawQuad.
void MaybeActivateSurface();
// Returns the primary SurfaceId.
viz::SurfaceId GetSurfaceId() const;
private:
void InitHostWindow(const std::string& window_name);
viz::CompositorFrame PrepareToSubmitCompositorFrame();
// The local_surface_id that the |frame_sink_| is submitting with, it should
// never be older than the local_surface_id of |host_window_|'s layer.
const viz::LocalSurfaceId& GetCurrentLocalSurfaceId() const;
void HandleContextLost();
void CleanUpCallbacks();
float CalculateScaleFactor(const absl::optional<float>& scale_factor) const;
// Applies `rounded_corner_bounds` to the `surface` and propagates the bounds
// to its subsurfaces. `rounded_corner_bounds` should be in the local
// coordinates of the `surface`.
void ApplyAndPropagateRoundedCornersToSurfaceTree(
Surface* surface,
const gfx::RRectF& rounded_corners_bounds);
std::unique_ptr<LayerTreeFrameSinkHolder> CreateLayerTreeFrameSinkHolder();
// The FrameSinkId associated with this.
viz::FrameSinkId frame_sink_id_;
std::unique_ptr<viz::ChildLocalSurfaceIdAllocator>
child_local_surface_id_allocator_;
raw_ptr<Surface, ExperimentalAsh> root_surface_ = nullptr;
// Position of root surface relative to topmost, leftmost sub-surface. The
// host window should be translated by the negation of this vector.
// The coordinates is Pixel.
gfx::Point root_surface_origin_pixel_;
// The coordinates is DP.
std::unique_ptr<aura::Window> host_window_;
std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_;
LayerTreeFrameSinkHolderFactory frame_sink_holder_factory_;
// This queue contains lists the callbacks to notify the client when it is a
// good time to start producing a new frame. Each list corresponds to a
// compositor frame, in the order of submission to
// `layer_tree_frame_sink_holder_`.
//
// These callbacks move to |frame_callbacks_| when Commit() is called. They
// fire when the effect of the Commit() is scheduled to be drawn.
base::queue<std::list<Surface::FrameCallback>> frame_callbacks_;
// These lists contain the callbacks to notify the client when surface
// contents have been presented.
base::flat_map<uint32_t, PresentationCallbacks>
active_presentation_callbacks_;
// When a client calls set_scale_factor they're actually setting the scale
// factor for all future commits.
absl::optional<float> pending_scale_factor_;
// This is the client-set scale factor that is being used for the current
// buffer.
absl::optional<float> scale_factor_;
viz::FrameTokenGenerator next_token_;
scoped_refptr<viz::RasterContextProvider> context_provider_;
display::ScopedDisplayObserver display_observer_{this};
int64_t display_id_ = display::kInvalidDisplayId;
bool client_submits_surfaces_in_pixel_coordinates_ = false;
raw_ptr<SecurityDelegate, ExperimentalAsh> security_delegate_ = nullptr;
std::set<gpu::SyncToken> prev_frame_verified_tokens_;
bool bounds_is_dirty_ = true;
base::WeakPtrFactory<SurfaceTreeHost> weak_ptr_factory_{this};
};
} // namespace exo
#endif // COMPONENTS_EXO_SURFACE_TREE_HOST_H_
|