blob: 4f084e9d6fa07c331a395461fd812f771af37dbe [file] [log] [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_ROUNDED_DISPLAY_ROUNDED_DISPLAY_PROVIDER_H_
#define ASH_ROUNDED_DISPLAY_ROUNDED_DISPLAY_PROVIDER_H_
#include <memory>
#include <vector>
#include "ash/ash_export.h"
#include "base/memory/weak_ptr.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
namespace aura {
class Window;
} // namespace aura
namespace ash {
class RoundedDisplayGutter;
class RoundedDisplayGutterFactory;
class RoundedDisplayProviderTestApi;
class RoundedDisplayHost;
// Provides an API to create software-based rounded corners for a given display.
// It manages the rounded corners for the display and renders them by submitting
// independent compositor frame to the display compositor.
class ASH_EXPORT RoundedDisplayProvider {
public:
// Strategy decides the direction in which RoundedDisplayGutters are created.
enum class Strategy {
// Overlay gutters are created is the scanout direction of the display
// panel.
kScanout,
// Overlay gutters are created is the direction that is perpendicular to the
// scanout direction of display_panel.
kOther
};
static std::unique_ptr<RoundedDisplayProvider> Create(int64_t display_id);
RoundedDisplayProvider(
const int64_t display_id,
std::unique_ptr<RoundedDisplayGutterFactory> gutter_factory);
RoundedDisplayProvider(const RoundedDisplayProvider&) = delete;
RoundedDisplayProvider& operator=(const RoundedDisplayProvider&) = delete;
~RoundedDisplayProvider();
// Creates RoundedDisplayGutter based on the specified `strategy` for the
// display and initializes the `RoundedDisplayHost`. Note: Need to call
// `UpdateRoundedDisplaySurface()` to show the rounded-display masks.
void Init(const gfx::RoundedCornersF& panel_radii, Strategy strategy);
// Update the window hierarchy to which the `host_window_` is attached to.
// Needed to be called when the window_tree_host for the display is updated
// and swapped with the window_tree_host of another display.
void UpdateHostParent();
bool UpdateRoundedDisplaySurface();
int64_t display_id() const { return display_id_; }
private:
friend class RoundedDisplayProviderTestApi;
// Returns gutters in draw order. Gutters in the front are drawn on top.
// Note: `DeleteGutters()` and `CreateGutters()` invalidates the pointers.
void GetGuttersInDrawOrder(std::vector<RoundedDisplayGutter*>& gutters) const;
bool ShouldSubmitNewCompositorFrame(const display::Display& display) const;
// Creates RoundedDisplayGutters if needed and returns true if we created
// gutters else returns false.
// To minimize the use of overlay planes, we only create a gutter if it has
// at least a single non-zero corner mask drawn into it.
// For example, for a display that doesn't have rounded bottom edges, and
// based on the `strategy_`, we need to create upper and lower OverlayGutters,
// we will skip the creation of the lower OverlayGutter.
bool CreateGutters(const display::Display& display,
const gfx::RoundedCornersF& panel_radii);
// Initialize the `RoundedDisplayHost`, attach the `host_window_` to the
// window hierarchy of the display.
void InitializeHost();
// The id of the display for which the provider creates rounded corners
// for.
const int64_t display_id_;
// The current display state for which rounded display is enabled.
float current_device_scale_factor_ = 0.0;
display::Display::Rotation current_logical_rotation_ =
display::Display::Rotation::ROTATE_0;
gfx::RoundedCornersF current_panel_radii_;
// The specified strategy to determine direction of overlay gutters.
Strategy strategy_ = Strategy::kScanout;
// Stores the overlay gutters that are created based on the `strategy_`.
std::vector<std::unique_ptr<RoundedDisplayGutter>> overlay_gutters_;
// OverlayRoundedDisplayGutter creation is delegated to this factory.
std::unique_ptr<RoundedDisplayGutterFactory> gutter_factory_;
// Represents the surface on which the `host_` render the mask textures of the
// rounded-display corners.
std::unique_ptr<aura::Window> host_window_;
// Responsible to render the mask textures by submitting compositor frames.
std::unique_ptr<RoundedDisplayHost> host_;
base::WeakPtrFactory<RoundedDisplayProvider> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_ROUNDED_DISPLAY_ROUNDED_DISPLAY_PROVIDER_H_