kodi
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  public IInputHandler,
51 {
52 public:
54  ~CWinSystemWayland() noexcept override;
55 
56  const std::string GetName() override { return "wayland"; }
57 
58  bool InitWindowSystem() override;
59  bool DestroyWindowSystem() override;
60 
61  bool CreateNewWindow(const std::string& name,
62  bool fullScreen,
63  RESOLUTION_INFO& res) override;
64 
65  bool DestroyWindow() override;
66 
67  bool ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop) override;
68  bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override;
69  void FinishModeChange(RESOLUTION res) override;
70  void FinishWindowResize(int newWidth, int newHeight) override;
71 
72  bool UseLimitedColor() override;
73 
74  void UpdateResolutions() override;
75 
76  bool CanDoWindowed() override;
77  bool Minimize() override;
78 
79  bool HasCursor() override;
80  void ShowOSMouse(bool show) override;
81 
82  std::string GetClipboardText() override;
83 
84  float GetSyncOutputRefreshRate();
85  float GetDisplayLatency() override;
86  float GetFrameLatencyAdjustment() override;
87  std::unique_ptr<CVideoSync> GetVideoSync(CVideoReferenceClock* clock) override;
88 
89  void Register(IDispResource* resource) override;
90  void Unregister(IDispResource* resource) override;
91 
92  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 */)>;
93  CSignalRegistration RegisterOnPresentationFeedback(const PresentationFeedbackHandler& handler);
94 
95  std::vector<std::string> GetConnectedOutputs() override;
96 
97  // winevents override
98  bool MessagePump() override;
99 
100 protected:
101  std::unique_ptr<KODI::WINDOWING::IOSScreenSaver> GetOSScreenSaverImpl() override;
102  CSizeInt GetBufferSize() const
103  {
104  return m_bufferSize;
105  }
106  std::unique_ptr<CConnection> const& GetConnection()
107  {
108  return m_connection;
109  }
110  wayland::surface_t GetMainSurface()
111  {
112  return m_surface;
113  }
114  IShellSurface* GetShellSurface() { return m_shellSurface.get(); }
115 
116  void PrepareFramePresentation();
117  void FinishFramePresentation();
118  virtual void SetContextSize(CSizeInt size) = 0;
119  virtual IShellSurface* CreateShellSurface(const std::string& name);
120 
121  // IShellSurfaceHandler
122  void OnConfigure(std::uint32_t serial, CSizeInt size, IShellSurface::StateBitset state) override;
123  void OnClose() override;
124 
125  virtual std::unique_ptr<CSeat> CreateSeat(std::uint32_t name, wayland::seat_t& seat);
126 
127 private:
128  // IInputHandler
129  void OnEnter(InputType type) override;
130  void OnLeave(InputType type) override;
131  void OnEvent(InputType type, XBMC_Event& event) override;
132  void OnSetCursor(std::uint32_t seatGlobalName, std::uint32_t serial) override;
133 
134  // IWindowDecorationHandler
135  void OnWindowMove(const wayland::seat_t& seat, std::uint32_t serial) override;
136  void OnWindowResize(const wayland::seat_t& seat, std::uint32_t serial, wayland::shell_surface_resize edge) override;
137  void OnWindowShowContextMenu(const wayland::seat_t& seat, std::uint32_t serial, CPointInt position) override;
138  void OnWindowClose() override;
139  void OnWindowMaximize() override;
140  void OnWindowMinimize() override;
141 
142  // Registry handlers
143  void OnSeatAdded(std::uint32_t name, wayland::proxy_t&& seat);
144  void OnSeatRemoved(std::uint32_t name);
145  void OnOutputAdded(std::uint32_t name, wayland::proxy_t&& output);
146  void OnOutputRemoved(std::uint32_t name);
147 
148  void LoadDefaultCursor();
149  void SendFocusChange(bool focus);
150  bool SetResolutionExternal(bool fullScreen, RESOLUTION_INFO const& res);
151  void SetResolutionInternal(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration, bool mustAck = false, std::uint32_t configureSerial = 0u);
152  struct Sizes
153  {
154  CSizeInt surfaceSize;
155  CSizeInt bufferSize;
156  CSizeInt configuredSize;
157  };
158  Sizes CalculateSizes(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration);
159  struct SizeUpdateInformation
160  {
161  bool surfaceSizeChanged : 1;
162  bool bufferSizeChanged : 1;
163  bool configuredSizeChanged : 1;
164  bool bufferScaleChanged : 1;
165  };
166  SizeUpdateInformation UpdateSizeVariables(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration);
167  void ApplySizeUpdate(SizeUpdateInformation update);
168  void ApplyNextState();
169 
170  std::string UserFriendlyOutputName(std::shared_ptr<COutput> const& output);
171  std::shared_ptr<COutput> FindOutputByUserFriendlyName(std::string const& name);
172  std::shared_ptr<COutput> FindOutputByWaylandOutput(wayland::output_t const& output);
173 
174  // Called when wl_output::done is received for an output, i.e. associated
175  // information like modes is available
176  void OnOutputDone(std::uint32_t name);
177  void UpdateBufferScale();
178  void ApplyBufferScale();
179  void ApplyOpaqueRegion();
180  void ApplyWindowGeometry();
181  void UpdateTouchDpi();
182  void ApplyShellSurfaceState(IShellSurface::StateBitset state);
183 
184  void ProcessMessages();
185  void AckConfigure(std::uint32_t serial);
186 
187  timespec GetPresentationClockTime();
188 
189  // Globals
190  // -------
191  std::unique_ptr<CConnection> m_connection;
192  std::unique_ptr<CRegistry> m_registry;
199  std::unique_ptr<CRegistry> m_seatRegistry;
200  wayland::compositor_t m_compositor;
201  wayland::shm_t m_shm;
202  wayland::presentation_t m_presentation;
203 
204  std::unique_ptr<IShellSurface> m_shellSurface;
205 
206  // Frame callback handling
207  // -----------------------
208  wayland::callback_t m_frameCallback;
209  CEvent m_frameCallbackEvent;
210 
211  // Seat handling
212  // -------------
213  std::map<std::uint32_t, std::unique_ptr<CSeat>> m_seats;
214  CCriticalSection m_seatsMutex;
215  std::unique_ptr<CSeatInputProcessing> m_seatInputProcessing;
216  std::map<std::uint32_t, std::shared_ptr<COutput>> m_outputs;
218  std::map<std::uint32_t, std::shared_ptr<COutput>> m_outputsInPreparation;
219  CCriticalSection m_outputsMutex;
220 
221  // Windowed mode
222  // -------------
223  std::unique_ptr<CWindowDecorator> m_windowDecorator;
224 
225  // Cursor
226  // ------
227  bool m_osCursorVisible{true};
228  wayland::cursor_theme_t m_cursorTheme;
229  wayland::buffer_t m_cursorBuffer;
230  wayland::cursor_image_t m_cursorImage;
231  wayland::surface_t m_cursorSurface;
232 
233  // Presentation feedback
234  // ---------------------
235  clockid_t m_presentationClock;
236  struct SurfaceSubmission
237  {
238  timespec submissionTime;
239  float latency;
240  wayland::presentation_feedback_t feedback;
241  SurfaceSubmission(timespec const& submissionTime, wayland::presentation_feedback_t const& feedback);
242  };
243  std::list<SurfaceSubmission> m_surfaceSubmissions;
244  CCriticalSection m_surfaceSubmissionsMutex;
246  std::uint32_t m_syncOutputID;
248  std::atomic<float> m_syncOutputRefreshRate{0.0f};
249  static constexpr int LATENCY_MOVING_AVERAGE_SIZE{30};
250  std::atomic<float> m_latencyMovingAverage;
251  CSignalHandlerList<PresentationFeedbackHandler> m_presentationFeedbackHandlers;
252 
253  std::chrono::steady_clock::time_point m_frameStartTime{};
254 
255  // IDispResource
256  // -------------
257  std::set<IDispResource*> m_dispResources;
258  CCriticalSection m_dispResourcesMutex;
259 
260  // Surface state
261  // -------------
262  wayland::surface_t m_surface;
263  wayland::output_t m_lastSetOutput;
266  std::set<std::shared_ptr<COutput>> m_surfaceOutputs;
267  CCriticalSection m_surfaceOutputsMutex;
270  CSizeInt m_surfaceSize;
272  CSizeInt m_bufferSize;
274  CSizeInt m_configuredSize;
276  int m_scale{1};
278  IShellSurface::StateBitset m_shellSurfaceState;
280  bool m_shellSurfaceInitializing{false};
281  struct
282  {
283  bool mustBeAcked{false};
284  std::uint32_t configureSerial{};
285  CSizeInt configuredSize;
286  int scale{1};
287  IShellSurface::StateBitset shellSurfaceState;
288  } m_next;
289  bool m_waitingForApply{false};
290 
291  // Internal communication
292  // ----------------------
294  Actor::Protocol m_protocol;
295 
296  // Configure state
297  // ---------------
298  bool m_firstSerialAcked{false};
299  std::uint32_t m_lastAckedSerial{0u};
301  bool m_isInitialSetFullScreen{true};
302 };
303 
304 
305 }
306 }
307 }
This is an Event class built from a ConditionVariable.
Definition: Event.h:35
Definition: WinSystemWayland.h:47
Definition: ActorProtocol.h:73
Definition: WinSystem.h:49
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:1445
Definition: AudioDecoder.h:18
Handler interface for input events from CSeatInputProcessor.
Definition: SeatInputProcessing.h:39
Definition: VideoReferenceClock.h:19
Abstraction for shell surfaces to support multiple protocols such as wl_shell (for compatibility) and...
Definition: ShellSurface.h:34
Definition: Signals.h:31
Definition: XBMC_events.h:117
float GetDisplayLatency() override
Get average display latency.
Definition: WinSystemWayland.cpp:1452
Handler for reacting to events originating in window decorations, such as moving the window by clicki...
Definition: WindowDecorationHandler.h:26