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
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_OUTPUT_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_OUTPUT_H_
#include <cstdint>
#include <ostream>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/display/types/native_display_delegate.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
namespace ui {
class XDGOutput;
class WaylandZcrColorManager;
class WaylandZcrColorManagementOutput;
class WaylandConnection;
// WaylandOutput objects keep track of wl_output information received through
// the Wayland protocol, along with other related protocol extensions, such as,
// xdg-output.
class WaylandOutput : public wl::GlobalObjectRegistrar<WaylandOutput> {
public:
// Instances of this class are identified by an 32-bit unsigned int value,
// corresponding to its global wl_output object 'name' value. On
// wayland-linux, it is mostly used interchangeably with WaylandScreen's
// `display::Display::id1` property, which is an int64_t instead, though it is
// worth bearing in mind they are slightly different, under the hood.
using Id = uint32_t;
static constexpr char kInterfaceName[] = "wl_output";
static void Instantiate(WaylandConnection* connection,
wl_registry* registry,
uint32_t name,
const std::string& interface,
uint32_t version);
// All parameters are in DIP screen coordinates/units except |physical_size|,
// which is in physical pixels.
struct Metrics {
// TODO(aluh): Remove explicit constructors/destructor to enable aggregate
// initialization if chromium-style check for complex struct is removed.
// See:
// https://groups.google.com/a/google.com/g/chromeos-chatty-eng/c/nM1_QC6qcuA
Metrics();
Metrics(Id output_id,
int64_t display_id,
gfx::Point origin,
gfx::Size logical_size,
gfx::Size physical_size,
gfx::Insets insets,
gfx::Insets physical_overscan_insets,
float scale_factor,
int32_t panel_transform,
int32_t logical_transform,
const std::string& description);
Metrics(const Metrics&);
Metrics& operator=(const Metrics&);
Metrics(Metrics&&);
Metrics& operator=(Metrics&&);
~Metrics();
bool operator==(const Metrics&) const = default;
Id output_id = 0;
int64_t display_id = -1;
gfx::Point origin;
gfx::Size logical_size;
gfx::Size physical_size;
// Work area insets in DIP.
gfx::Insets insets;
// Overscan insets in physical pixels.
gfx::Insets physical_overscan_insets;
float scale_factor = 0.0;
int32_t panel_transform = 0;
int32_t logical_transform = 0;
std::string name;
std::string description;
void DumpState(std::ostream& out) const;
};
class Delegate {
public:
virtual void OnOutputHandleMetrics(const Metrics& metrics) = 0;
protected:
virtual ~Delegate() = default;
};
WaylandOutput(Id output_id, wl_output* output, WaylandConnection* connection);
WaylandOutput(const WaylandOutput&) = delete;
WaylandOutput& operator=(const WaylandOutput&) = delete;
~WaylandOutput();
void Initialize(Delegate* delegate);
void InitializeXdgOutput(zxdg_output_manager_v1* manager);
void InitializeColorManagementOutput(WaylandZcrColorManager* manager);
const Metrics& GetMetrics() const;
void SetMetrics(const Metrics& metrics);
// TODO(tuluk): Metrics getters below are rendundant and should be replaced
// with calls to GetMetrics().
Id output_id() const { return output_id_; }
float scale_factor() const;
WaylandZcrColorManagementOutput* color_management_output() const {
return color_management_output_.get();
}
// Returns true if the output has all the state information available
// necessary to represent its associated display. This information arrives
// asynchronously via events across potentially multiple wayland objects.
bool IsReady() const;
wl_output* get_output() { return output_.get(); }
void SetScaleFactorForTesting(float scale_factor);
void TriggerDelegateNotifications();
void DumpState(std::ostream& out) const;
void set_delegate_for_testing(Delegate* delegate) { delegate_ = delegate; }
XDGOutput* xdg_output_for_testing() { return xdg_output_.get(); }
private:
FRIEND_TEST_ALL_PREFIXES(WaylandOutputTest, NameAndDescriptionFallback);
FRIEND_TEST_ALL_PREFIXES(WaylandOutputTest, ScaleFactorCalculation);
FRIEND_TEST_ALL_PREFIXES(WaylandOutputTest, ScaleFactorFallback);
FRIEND_TEST_ALL_PREFIXES(WaylandOutputTest, ScaleFactorCalculationNoop);
static constexpr int32_t kDefaultScaleFactor = 1;
// Called when the wl_output.done event is received and atomically updates
// `metrics_` based on the previously received output state events.
void UpdateMetrics();
// wl_output_listener callbacks:
static void OnGeometry(void* data,
wl_output* output,
int32_t x,
int32_t y,
int32_t physical_width,
int32_t physical_height,
int32_t subpixel,
const char* make,
const char* model,
int32_t output_transform);
static void OnMode(void* data,
wl_output* output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh);
static void OnDone(void* data, wl_output* output);
static void OnScale(void* data, wl_output* output, int32_t factor);
static void OnName(void* data, wl_output* output, const char* name);
static void OnDescription(void* data,
wl_output* output,
const char* description);
// Tracks whether this wl_output is considered "ready". I.e. it has received
// all of its relevant state from the server followed by a wl_output.done
// event.
bool is_ready_ = false;
// Metrics represents the current state of the display represented by this
// output object. This state is updated atomically after the client has
// received the wl_output.done event.
Metrics metrics_;
const Id output_id_ = 0;
wl::Object<wl_output> output_;
std::unique_ptr<XDGOutput> xdg_output_;
std::unique_ptr<WaylandZcrColorManagementOutput> color_management_output_;
float scale_factor_ = kDefaultScaleFactor;
int32_t panel_transform_ = WL_OUTPUT_TRANSFORM_NORMAL;
// Origin of the output in DIP screen coordinate.
gfx::Point origin_;
// Size of the output in physical pixels.
gfx::Size physical_size_;
// Fallback name and description.
// The XDG output specification suggests using it as the primary source of
// the information about the output. Two attributes below are used if
// xdg_output_ is not present.
// See https://wayland.app/protocols/xdg-output-unstable-v1
std::string name_;
std::string description_;
raw_ptr<Delegate> delegate_ = nullptr;
raw_ptr<WaylandConnection> connection_ = nullptr;
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_OUTPUT_H_
|