xbmc
WinSystemWayland.h
1 /*
2  * Copyright (C) 2017-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "Connection.h"
12 #include "Output.h"
13 #include "Seat.h"
14 #include "SeatInputProcessing.h"
15 #include "ShellSurface.h"
16 #include "Signals.h"
17 #include "WindowDecorationHandler.h"
18 #include "threads/CriticalSection.h"
19 #include "threads/Event.h"
20 #include "utils/ActorProtocol.h"
21 #include "windowing/WinSystem.h"
22 
23 #include <atomic>
24 #include <chrono>
25 #include <ctime>
26 #include <list>
27 #include <map>
28 #include <set>
29 #include <time.h>
30 
31 #include <wayland-client.hpp>
32 #include <wayland-cursor.hpp>
33 #include <wayland-extra-protocols.hpp>
34 
35 class IDispResource;
36 
37 namespace KODI
38 {
39 namespace WINDOWING
40 {
41 namespace WAYLAND
42 {
43 
44 class CRegistry;
45 class CWindowDecorator;
46 
48 {
49 public:
51  ~CWinSystemWayland() noexcept override;
52 
53  const std::string GetName() override { return "wayland"; }
54 
55  bool InitWindowSystem() override;
56  bool DestroyWindowSystem() override;
57 
58  bool CreateNewWindow(const std::string& name,
59  bool fullScreen,
60  RESOLUTION_INFO& res) override;
61 
62  bool DestroyWindow() override;
63 
64  bool ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) override;
65  bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override;
66  void FinishModeChange(RESOLUTION res) override;
67  void FinishWindowResize(int newWidth, int newHeight) override;
68 
69  bool UseLimitedColor() override;
70 
71  void UpdateResolutions() override;
72 
73  bool CanDoWindowed() override;
74  bool Minimize() override;
75 
76  bool HasCursor() override;
77  void ShowOSMouse(bool show) override;
78 
79  std::string GetClipboardText() override;
80 
81  float GetSyncOutputRefreshRate();
82  float GetDisplayLatency() override;
83  float GetFrameLatencyAdjustment() override;
84  std::unique_ptr<CVideoSync> GetVideoSync(void* clock) override;
85 
86  void Register(IDispResource* resource) override;
87  void Unregister(IDispResource* resource) override;
88 
89  using PresentationFeedbackHandler = std::function<void(timespec /* tv */, std::uint32_t /* refresh */, std::uint32_t /* sync output id */, float /* sync output fps */, std::uint64_t /* msc */)>;
90  CSignalRegistration RegisterOnPresentationFeedback(const PresentationFeedbackHandler& handler);
91 
92  std::vector<std::string> GetConnectedOutputs() override;
93 
94  // winevents override
95  bool MessagePump() override;
96 
97 protected:
98  std::unique_ptr<KODI::WINDOWING::IOSScreenSaver> GetOSScreenSaverImpl() override;
99  CSizeInt GetBufferSize() const
100  {
101  return m_bufferSize;
102  }
103  std::unique_ptr<CConnection> const& GetConnection()
104  {
105  return m_connection;
106  }
107  wayland::surface_t GetMainSurface()
108  {
109  return m_surface;
110  }
111 
112  void PrepareFramePresentation();
113  void FinishFramePresentation();
114  virtual void SetContextSize(CSizeInt size) = 0;
115 
116 private:
117  // IInputHandler
118  void OnEnter(InputType type) override;
119  void OnLeave(InputType type) override;
120  void OnEvent(InputType type, XBMC_Event& event) override;
121  void OnSetCursor(std::uint32_t seatGlobalName, std::uint32_t serial) override;
122 
123  // IWindowDecorationHandler
124  void OnWindowMove(const wayland::seat_t& seat, std::uint32_t serial) override;
125  void OnWindowResize(const wayland::seat_t& seat, std::uint32_t serial, wayland::shell_surface_resize edge) override;
126  void OnWindowShowContextMenu(const wayland::seat_t& seat, std::uint32_t serial, CPointInt position) override;
127  void OnWindowClose() override;
128  void OnWindowMaximize() override;
129  void OnWindowMinimize() override;
130 
131  // IShellSurfaceHandler
132  void OnConfigure(std::uint32_t serial, CSizeInt size, IShellSurface::StateBitset state) override;
133  void OnClose() override;
134 
135  // Registry handlers
136  void OnSeatAdded(std::uint32_t name, wayland::proxy_t&& seat);
137  void OnSeatRemoved(std::uint32_t name);
138  void OnOutputAdded(std::uint32_t name, wayland::proxy_t&& output);
139  void OnOutputRemoved(std::uint32_t name);
140 
141  void LoadDefaultCursor();
142  void SendFocusChange(bool focus);
143  bool SetResolutionExternal(bool fullScreen, RESOLUTION_INFO const& res);
144  void SetResolutionInternal(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration, bool mustAck = false, std::uint32_t configureSerial = 0u);
145  struct Sizes
146  {
147  CSizeInt surfaceSize;
148  CSizeInt bufferSize;
149  CSizeInt configuredSize;
150  };
151  Sizes CalculateSizes(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration);
152  struct SizeUpdateInformation
153  {
154  bool surfaceSizeChanged : 1;
155  bool bufferSizeChanged : 1;
156  bool configuredSizeChanged : 1;
157  bool bufferScaleChanged : 1;
158  };
159  SizeUpdateInformation UpdateSizeVariables(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration);
160  void ApplySizeUpdate(SizeUpdateInformation update);
161  void ApplyNextState();
162 
163  std::string UserFriendlyOutputName(std::shared_ptr<COutput> const& output);
164  std::shared_ptr<COutput> FindOutputByUserFriendlyName(std::string const& name);
165  std::shared_ptr<COutput> FindOutputByWaylandOutput(wayland::output_t const& output);
166 
167  // Called when wl_output::done is received for an output, i.e. associated
168  // information like modes is available
169  void OnOutputDone(std::uint32_t name);
170  void UpdateBufferScale();
171  void ApplyBufferScale();
172  void ApplyOpaqueRegion();
173  void ApplyWindowGeometry();
174  void UpdateTouchDpi();
175  void ApplyShellSurfaceState(IShellSurface::StateBitset state);
176 
177  void ProcessMessages();
178  void AckConfigure(std::uint32_t serial);
179 
180  timespec GetPresentationClockTime();
181 
182  // Globals
183  // -------
184  std::unique_ptr<CConnection> m_connection;
185  std::unique_ptr<CRegistry> m_registry;
192  std::unique_ptr<CRegistry> m_seatRegistry;
193  wayland::compositor_t m_compositor;
194  wayland::shm_t m_shm;
195  wayland::presentation_t m_presentation;
196 
197  std::unique_ptr<IShellSurface> m_shellSurface;
198 
199  // Frame callback handling
200  // -----------------------
201  wayland::callback_t m_frameCallback;
202  CEvent m_frameCallbackEvent;
203 
204  // Seat handling
205  // -------------
206  std::map<std::uint32_t, CSeat> m_seats;
207  CCriticalSection m_seatsMutex;
208  std::unique_ptr<CSeatInputProcessing> m_seatInputProcessing;
209  std::map<std::uint32_t, std::shared_ptr<COutput>> m_outputs;
211  std::map<std::uint32_t, std::shared_ptr<COutput>> m_outputsInPreparation;
212  CCriticalSection m_outputsMutex;
213 
214  // Windowed mode
215  // -------------
216  std::unique_ptr<CWindowDecorator> m_windowDecorator;
217 
218  // Cursor
219  // ------
220  bool m_osCursorVisible{true};
221  wayland::cursor_theme_t m_cursorTheme;
222  wayland::buffer_t m_cursorBuffer;
223  wayland::cursor_image_t m_cursorImage;
224  wayland::surface_t m_cursorSurface;
225 
226  // Presentation feedback
227  // ---------------------
228  clockid_t m_presentationClock;
229  struct SurfaceSubmission
230  {
231  timespec submissionTime;
232  float latency;
233  wayland::presentation_feedback_t feedback;
234  SurfaceSubmission(timespec const& submissionTime, wayland::presentation_feedback_t const& feedback);
235  };
236  std::list<SurfaceSubmission> m_surfaceSubmissions;
237  CCriticalSection m_surfaceSubmissionsMutex;
239  std::uint32_t m_syncOutputID;
241  std::atomic<float> m_syncOutputRefreshRate{0.0f};
242  static constexpr int LATENCY_MOVING_AVERAGE_SIZE{30};
243  std::atomic<float> m_latencyMovingAverage;
244  CSignalHandlerList<PresentationFeedbackHandler> m_presentationFeedbackHandlers;
245 
246  std::chrono::steady_clock::time_point m_frameStartTime{};
247 
248  // IDispResource
249  // -------------
250  std::set<IDispResource*> m_dispResources;
251  CCriticalSection m_dispResourcesMutex;
252 
253  // Surface state
254  // -------------
255  wayland::surface_t m_surface;
256  wayland::output_t m_lastSetOutput;
259  std::set<std::shared_ptr<COutput>> m_surfaceOutputs;
260  CCriticalSection m_surfaceOutputsMutex;
263  CSizeInt m_surfaceSize;
265  CSizeInt m_bufferSize;
267  CSizeInt m_configuredSize;
269  int m_scale{1};
271  IShellSurface::StateBitset m_shellSurfaceState;
273  bool m_shellSurfaceInitializing{false};
274  struct
275  {
276  bool mustBeAcked{false};
277  std::uint32_t configureSerial{};
278  CSizeInt configuredSize;
279  int scale{1};
280  IShellSurface::StateBitset shellSurfaceState;
281  } m_next;
282  bool m_waitingForApply{false};
283 
284  // Internal communication
285  // ----------------------
287  Actor::Protocol m_protocol;
288 
289  // Configure state
290  // ---------------
291  bool m_firstSerialAcked{false};
292  std::uint32_t m_lastAckedSerial{0u};
294  bool m_isInitialSetFullScreen{true};
295 };
296 
297 
298 }
299 }
300 }
This is an Event class built from a ConditionVariable.
Definition: Event.h:35
Definition: WinSystemWayland.h:47
Definition: ActorProtocol.h:73
Definition: WinSystem.h:44
Definition: DispResource.h:14
Provide info of a resolution.
Definition: Resolution.h:66
float GetFrameLatencyAdjustment() override
Get time that should be subtracted from the display latency for this frame in milliseconds.
Definition: WinSystemWayland.cpp:1436
Controller configuration window.
Definition: AudioDecoder.h:18
Handler interface for input events from CSeatInputProcessor.
Definition: SeatInputProcessing.h:39
Definition: Signals.h:31
Definition: XBMC_events.h:109
float GetDisplayLatency() override
Get average display latency.
Definition: WinSystemWayland.cpp:1443
Handler for reacting to events originating in window decorations, such as moving the window by clicki...
Definition: WindowDecorationHandler.h:26