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  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 private:
126  // IInputHandler
127  void OnEnter(InputType type) override;
128  void OnLeave(InputType type) override;
129  void OnEvent(InputType type, XBMC_Event& event) override;
130  void OnSetCursor(std::uint32_t seatGlobalName, std::uint32_t serial) override;
131 
132  // IWindowDecorationHandler
133  void OnWindowMove(const wayland::seat_t& seat, std::uint32_t serial) override;
134  void OnWindowResize(const wayland::seat_t& seat, std::uint32_t serial, wayland::shell_surface_resize edge) override;
135  void OnWindowShowContextMenu(const wayland::seat_t& seat, std::uint32_t serial, CPointInt position) override;
136  void OnWindowClose() override;
137  void OnWindowMaximize() override;
138  void OnWindowMinimize() override;
139 
140  // Registry handlers
141  void OnSeatAdded(std::uint32_t name, wayland::proxy_t&& seat);
142  void OnSeatRemoved(std::uint32_t name);
143  void OnOutputAdded(std::uint32_t name, wayland::proxy_t&& output);
144  void OnOutputRemoved(std::uint32_t name);
145 
146  void LoadDefaultCursor();
147  void SendFocusChange(bool focus);
148  bool SetResolutionExternal(bool fullScreen, RESOLUTION_INFO const& res);
149  void SetResolutionInternal(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration, bool mustAck = false, std::uint32_t configureSerial = 0u);
150  struct Sizes
151  {
152  CSizeInt surfaceSize;
153  CSizeInt bufferSize;
154  CSizeInt configuredSize;
155  };
156  Sizes CalculateSizes(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration);
157  struct SizeUpdateInformation
158  {
159  bool surfaceSizeChanged : 1;
160  bool bufferSizeChanged : 1;
161  bool configuredSizeChanged : 1;
162  bool bufferScaleChanged : 1;
163  };
164  SizeUpdateInformation UpdateSizeVariables(CSizeInt size, int scale, IShellSurface::StateBitset state, bool sizeIncludesDecoration);
165  void ApplySizeUpdate(SizeUpdateInformation update);
166  void ApplyNextState();
167 
168  std::string UserFriendlyOutputName(std::shared_ptr<COutput> const& output);
169  std::shared_ptr<COutput> FindOutputByUserFriendlyName(std::string const& name);
170  std::shared_ptr<COutput> FindOutputByWaylandOutput(wayland::output_t const& output);
171 
172  // Called when wl_output::done is received for an output, i.e. associated
173  // information like modes is available
174  void OnOutputDone(std::uint32_t name);
175  void UpdateBufferScale();
176  void ApplyBufferScale();
177  void ApplyOpaqueRegion();
178  void ApplyWindowGeometry();
179  void UpdateTouchDpi();
180  void ApplyShellSurfaceState(IShellSurface::StateBitset state);
181 
182  void ProcessMessages();
183  void AckConfigure(std::uint32_t serial);
184 
185  timespec GetPresentationClockTime();
186 
187  // Globals
188  // -------
189  std::unique_ptr<CConnection> m_connection;
190  std::unique_ptr<CRegistry> m_registry;
197  std::unique_ptr<CRegistry> m_seatRegistry;
198  wayland::compositor_t m_compositor;
199  wayland::shm_t m_shm;
200  wayland::presentation_t m_presentation;
201 
202  std::unique_ptr<IShellSurface> m_shellSurface;
203 
204  // Frame callback handling
205  // -----------------------
206  wayland::callback_t m_frameCallback;
207  CEvent m_frameCallbackEvent;
208 
209  // Seat handling
210  // -------------
211  std::map<std::uint32_t, CSeat> m_seats;
212  CCriticalSection m_seatsMutex;
213  std::unique_ptr<CSeatInputProcessing> m_seatInputProcessing;
214  std::map<std::uint32_t, std::shared_ptr<COutput>> m_outputs;
216  std::map<std::uint32_t, std::shared_ptr<COutput>> m_outputsInPreparation;
217  CCriticalSection m_outputsMutex;
218 
219  // Windowed mode
220  // -------------
221  std::unique_ptr<CWindowDecorator> m_windowDecorator;
222 
223  // Cursor
224  // ------
225  bool m_osCursorVisible{true};
226  wayland::cursor_theme_t m_cursorTheme;
227  wayland::buffer_t m_cursorBuffer;
228  wayland::cursor_image_t m_cursorImage;
229  wayland::surface_t m_cursorSurface;
230 
231  // Presentation feedback
232  // ---------------------
233  clockid_t m_presentationClock;
234  struct SurfaceSubmission
235  {
236  timespec submissionTime;
237  float latency;
238  wayland::presentation_feedback_t feedback;
239  SurfaceSubmission(timespec const& submissionTime, wayland::presentation_feedback_t const& feedback);
240  };
241  std::list<SurfaceSubmission> m_surfaceSubmissions;
242  CCriticalSection m_surfaceSubmissionsMutex;
244  std::uint32_t m_syncOutputID;
246  std::atomic<float> m_syncOutputRefreshRate{0.0f};
247  static constexpr int LATENCY_MOVING_AVERAGE_SIZE{30};
248  std::atomic<float> m_latencyMovingAverage;
249  CSignalHandlerList<PresentationFeedbackHandler> m_presentationFeedbackHandlers;
250 
251  std::chrono::steady_clock::time_point m_frameStartTime{};
252 
253  // IDispResource
254  // -------------
255  std::set<IDispResource*> m_dispResources;
256  CCriticalSection m_dispResourcesMutex;
257 
258  // Surface state
259  // -------------
260  wayland::surface_t m_surface;
261  wayland::output_t m_lastSetOutput;
264  std::set<std::shared_ptr<COutput>> m_surfaceOutputs;
265  CCriticalSection m_surfaceOutputsMutex;
268  CSizeInt m_surfaceSize;
270  CSizeInt m_bufferSize;
272  CSizeInt m_configuredSize;
274  int m_scale{1};
276  IShellSurface::StateBitset m_shellSurfaceState;
278  bool m_shellSurfaceInitializing{false};
279  struct
280  {
281  bool mustBeAcked{false};
282  std::uint32_t configureSerial{};
283  CSizeInt configuredSize;
284  int scale{1};
285  IShellSurface::StateBitset shellSurfaceState;
286  } m_next;
287  bool m_waitingForApply{false};
288 
289  // Internal communication
290  // ----------------------
292  Actor::Protocol m_protocol;
293 
294  // Configure state
295  // ---------------
296  bool m_firstSerialAcked{false};
297  std::uint32_t m_lastAckedSerial{0u};
299  bool m_isInitialSetFullScreen{true};
300 };
301 
302 
303 }
304 }
305 }
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:1442
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:114
float GetDisplayLatency() override
Get average display latency.
Definition: WinSystemWayland.cpp:1449
Handler for reacting to events originating in window decorations, such as moving the window by clicki...
Definition: WindowDecorationHandler.h:26