blob: a1795941839184aa20e9b819a5ab601b6af2b748 [file] [log] [blame]
fei.dengf7a0cd32023-08-29 09:36:37 +00001/*
2 * Copyright (C) 2021 Amlogic Corporation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef __WAYLAND_DISPLAY_H__
17#define __WAYLAND_DISPLAY_H__
18#include <stdint.h>
19#include <stdlib.h>
20#include <pthread.h>
21#include <poll.h>
22#include <list>
fei.dengf7a0cd32023-08-29 09:36:37 +000023#include <unordered_map>
24#include <wayland-client-protocol.h>
25#include <wayland-client.h>
26#include "xdg-shell-client-protocol.h"
27#include "fullscreen-shell-unstable-v1-client-protocol.h"
28#include "linux-dmabuf-unstable-v1-client-protocol.h"
29#include "linux-explicit-synchronization-unstable-v1-client-protocol.h"
30#include "viewporter-client-protocol.h"
31#include "wayland-cursor.h"
32#include "Thread.h"
fei.dengb9a1a572023-09-13 01:33:57 +000033#include "Poll.h"
fei.dengf7a0cd32023-08-29 09:36:37 +000034#include "render_plugin.h"
35
36using namespace std;
37
38#define DEFAULT_DISPLAY_OUTPUT_NUM 2
39
40class WaylandPlugin;
41class WaylandShmBuffer;
42class WaylandBuffer;
43
44class WaylandDisplay : public Tls::Thread{
45 public:
fei.dengb9a1a572023-09-13 01:33:57 +000046 WaylandDisplay(WaylandPlugin *plugin, int logCategory);
fei.dengf7a0cd32023-08-29 09:36:37 +000047 virtual ~WaylandDisplay();
48 /**
49 * @brief connet client to compositor server
50 * and acquire a display from compositor
51 *
52 * @return int 0 success,other fail
53 */
54 int openDisplay();
55 /**
56 * @brief release display that acquired from compositor
57 *
58 */
59 void closeDisplay();
60 /**
61 * @brief change RenderVideoFormat to wayland protocol dma buffer format
62 * and get the matched dmabuffer modifiers
63 *
64 */
65 int toDmaBufferFormat(RenderVideoFormat format, uint32_t *outDmaformat /*out param*/, uint64_t *outDmaformatModifiers /*out param*/);
66 /**
67 * @brief change RenderVideoFormat to wayland protocol shm buffer format
68 *
69 * @param format RenderVideoFormat
70 * @param outformat wayland protocol shm buffer format
71 * @return int 0 success,other fail
72 */
73 int toShmBufferFormat(RenderVideoFormat format, uint32_t *outformat);
74 /**
75 * @brief Set the Video Buffer Format object
76 *
77 * @param format RenderVideoFormat it is defined in render_lib.h
78 */
79 void setVideoBufferFormat(RenderVideoFormat format);
80 RenderVideoFormat getVideoBufferFormat() {
81 return mBufferFormat;
82 };
83 struct wl_display *getWlDisplay() {
84 return mWlDisplay;
85 };
86 struct zwp_linux_dmabuf_v1 * getDmaBuf()
87 {
88 return mDmabuf;
89 };
90 struct wl_shm *getShm()
91 {
92 return mShm;
93 };
94 /**
95 * @brief Set the Select Display Output index
96 *
97 * @param output selected display output index
98 */
99 void setDisplayOutput(int output);
100 /**
101 * @brief Get the Select Display Output index
102 *
103 * @return int the index of selected output
104 */
105 int getDisplayOutput();
106
107 /**
108 * @brief set pip video
109 * @param pip if set to 1, the video data will display in pip video plane
110 * otherwise video data will display in main video plane
111 */
112 void setPip(int pip);
113
114 bool isSentPtsToWeston() {
115 return mIsSendPtsToWeston;
116 }
117
118 void setRedrawingPending(bool val) {
119 mRedrawingPending = val;
120 };
121
122 bool isRedrawingPending() {
123 return mRedrawingPending;
124 };
125
126 void setRenderRectangle(int x, int y, int w, int h);
127 void setFrameSize(int w, int h);
128 void setWindowSize(int x, int y, int w, int h);
129 int prepareFrameBuffer(RenderBuffer * buf);
130 void displayFrameBuffer(RenderBuffer * buf, int64_t realDisplayTime);
131 void setOpaque();
132 void flushBuffers();
133 void ensureFullscreen(bool fullscreen);
134 void handleBufferReleaseCallback(WaylandBuffer *buf);
135 void handleFrameDisplayedCallback(WaylandBuffer *buf);
136 void handleFrameDropedCallback(WaylandBuffer *buf);
137
138 //thread func
139 void readyToRun();
140 virtual bool threadLoop();
141
142 /**wayland callback functions**/
143 static void dmabuf_modifiers(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
144 uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo);
145 static void dmaBufferFormat (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format);
146 static void registryHandleGlobal (void *data, struct wl_registry *registry,
147 uint32_t id, const char *interface, uint32_t version);
148 static void registryHandleGlobalRemove (void *data, struct wl_registry *registry, uint32_t name);
149 static void shmFormat (void *data, struct wl_shm *wl_shm, uint32_t format);
150 static void outputHandleGeometry( void *data,
151 struct wl_output *output,
152 int x,
153 int y,
154 int mmWidth,
155 int mmHeight,
156 int subPixel,
157 const char *make,
158 const char *model,
159 int transform );
160 static void outputHandleMode( void *data,
161 struct wl_output *output,
162 uint32_t flags,
163 int width,
164 int height,
165 int refreshRate );
166 static void outputHandleDone( void *data,
167 struct wl_output *output );
168 static void outputHandleScale( void *data,
169 struct wl_output *output,
170 int32_t scale );
171 static void pointerHandleEnter(void *data, struct wl_pointer *pointer,
172 uint32_t serial, struct wl_surface *surface,
173 wl_fixed_t sx, wl_fixed_t sy);
174 static void pointerHandleLeave(void *data, struct wl_pointer *pointer,
175 uint32_t serial, struct wl_surface *surface);
176 static void pointerHandleMotion(void *data, struct wl_pointer *pointer,
177 uint32_t time, wl_fixed_t sx, wl_fixed_t sy);
178 static void pointerHandleButton(void *data, struct wl_pointer *wl_pointer,
179 uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
180 static void pointerHandleAxis(void *data, struct wl_pointer *wl_pointer,
181 uint32_t time, uint32_t axis, wl_fixed_t value);
182 static void touchHandleDown(void *data, struct wl_touch *wl_touch,
183 uint32_t serial, uint32_t time, struct wl_surface *surface,
184 int32_t id, wl_fixed_t x_w, wl_fixed_t y_w);
185 static void touchHandleUp(void *data, struct wl_touch *wl_touch,
186 uint32_t serial, uint32_t time, int32_t id);
187 static void touchHandleMotion(void *data, struct wl_touch *wl_touch,
188 uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w);
189 static void touchHandleFrame(void *data, struct wl_touch *wl_touch);
190 static void touchHandleCancel(void *data, struct wl_touch *wl_touch);
191 static void keyboardHandleKeymap(void *data, struct wl_keyboard *keyboard,
192 uint32_t format, int fd, uint32_t size);
193 static void keyboardHandleEnter(void *data, struct wl_keyboard *keyboard,
194 uint32_t serial, struct wl_surface *surface, struct wl_array *keys);
195 static void keyboardHandleLeave(void *data, struct wl_keyboard *keyboard,
196 uint32_t serial, struct wl_surface *surface);
197 static void keyboardHandleKey(void *data, struct wl_keyboard *keyboard,
198 uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
199 static void keyboardHandleModifiers(void *data, struct wl_keyboard *keyboard,
200 uint32_t serial, uint32_t mods_depressed,
201 uint32_t mods_latched, uint32_t mods_locked,
202 uint32_t group);
203 static void seatHandleCapabilities(void *data, struct wl_seat *seat,
204 uint32_t caps);
205 static void handleXdgToplevelClose (void *data, struct xdg_toplevel *xdg_toplevel);
206 static void handleXdgToplevelConfigure (void *data, struct xdg_toplevel *xdg_toplevel,
207 int32_t width, int32_t height, struct wl_array *states);
208 static void handleXdgSurfaceConfigure (void *data, struct xdg_surface *xdg_surface, uint32_t serial);
209 private:
210 typedef struct DisplayOutput {
211 struct wl_output *wlOutput;
212 int offsetX;
213 int offsetY;
214 int width;
215 int height;
216 int refreshRate;
217 bool isPrimary;
fei.dengaf9b07d2023-10-10 07:38:40 +0000218 uint32_t name;
fei.dengf7a0cd32023-08-29 09:36:37 +0000219 } DisplayOutput;
220 struct Rectangle {
221 int x;
222 int y;
223 int w;
224 int h;
225 };
226 char *require_xdg_runtime_dir();
227 void createCommonWindowSurface();
228 void createXdgShellWindowSurface();
229 void destroyWindowSurfaces();
230 void resizeVideoSurface(bool commit);
231 void videoCenterRect(Rectangle src, Rectangle dst, Rectangle *result, bool scaling);
232 void updateBorders();
233 std::size_t calculateDmaBufferHash(RenderDmaBuffer &dmabuf);
234 void cleanSurface();
235 void addWaylandBuffer(RenderBuffer * buf, WaylandBuffer *waylandbuf);
236 WaylandBuffer* findWaylandBuffer(RenderBuffer * buf);
237 void cleanAllWaylandBuffer();
238
239 WaylandPlugin *mWaylandPlugin;
240 struct wl_display *mWlDisplay;
241 struct wl_display *mWlDisplayWrapper;
242 struct wl_event_queue *mWlQueue;
243
244 struct wl_registry *mRegistry;
245 struct wl_compositor *mCompositor;
246 struct wl_subcompositor *mSubCompositor;
247 struct xdg_wm_base *mXdgWmBase;
248 struct wp_viewporter *mViewporter;
249 struct zwp_linux_dmabuf_v1 *mDmabuf;
250 struct wl_shm *mShm;
251 struct wl_seat *mSeat;
252 struct wl_pointer *mPointer;
253 struct wl_touch *mTouch;
254 struct wl_keyboard *mKeyboard;
255
256 /*primary output will signal first,so 0 index is primary wl_output, 1 index is extend wl_output*/
257 DisplayOutput mOutput[DEFAULT_DISPLAY_OUTPUT_NUM]; //info about wl_output
fei.dengf7a0cd32023-08-29 09:36:37 +0000258 int mActiveOutput; //default is primary output
259
fei.dengb9a1a572023-09-13 01:33:57 +0000260 int mLogCategory;
261
fei.dengf7a0cd32023-08-29 09:36:37 +0000262 std::list<uint32_t> mShmFormats;
263 std::unordered_map<uint32_t, uint64_t> mDmaBufferFormats;
264 RenderVideoFormat mBufferFormat;
265
fei.dengb9a1a572023-09-13 01:33:57 +0000266 mutable Tls::Mutex mBufferMutex;
267 mutable Tls::Mutex mMutex;
fei.dengf7a0cd32023-08-29 09:36:37 +0000268 int mFd;
fei.dengb9a1a572023-09-13 01:33:57 +0000269 Tls::Poll *mPoll;
fei.dengf7a0cd32023-08-29 09:36:37 +0000270
271 /*the followed is windows variable*/
fei.dengb9a1a572023-09-13 01:33:57 +0000272 mutable Tls::Mutex mRenderMutex;
fei.dengf7a0cd32023-08-29 09:36:37 +0000273 struct wl_surface *mAreaSurface;
274 struct wl_surface *mAreaSurfaceWrapper;
275 struct wl_surface *mVideoSurface;
276 struct wl_surface *mVideoSurfaceWrapper;
277 struct wl_subsurface *mVideoSubSurface;
278 struct xdg_surface *mXdgSurface;
279 struct xdg_toplevel *mXdgToplevel;
280 struct wp_viewport *mAreaViewport;
281 struct wp_viewport *mVideoViewport;
282 WaylandShmBuffer *mAreaShmBuffer;
283 bool mXdgSurfaceConfigured;
fei.dengb9a1a572023-09-13 01:33:57 +0000284 Tls::Condition mConfigureCond;
285 Tls::Mutex mConfigureMutex;
fei.dengf7a0cd32023-08-29 09:36:37 +0000286 bool mFullScreen; //default full screen
287
288 bool mIsSendPtsToWeston;
289
290 bool mReCommitAreaSurface;
291
292 /* the size and position of the area_(sub)surface
293 it is full screen size now*/
294 struct Rectangle mRenderRect;
295
296 /*the size and position of window */
297 struct Rectangle mWindowRect;
298
299 /* the size and position of the video_subsurface */
300 struct Rectangle mVideoRect;
301 /* the size of the video in the buffers */
302 int mVideoWidth;
303 int mVideoHeight;
304
305 //the count display buffer of committed to weston
306 int mCommitCnt;
307
308 /*store waylandbuffers when set reusing waylandbuffer flag*/
309 std::unordered_map<std::size_t, WaylandBuffer *> mWaylandBuffersMap;
310 bool mNoBorderUpdate;
311
312 /*store committed to weston waylandbuffer,key is pts*/
313 std::unordered_map<int64_t, WaylandBuffer *> mCommittedBufferMap;
314
315 int mPip; //pip video, 1->pip, 0: main video(default)
316 bool mIsSendVideoPlaneId; //default true,otherwise false if set
317 bool mRedrawingPending;//it will be true when weston obtains a buffer rendering,otherwise false when rendered
318};
319
320#endif /*__WAYLAND_DISPLAY_H__*/