summarylogtreecommitdiffstats
path: root/0001-Add-force-orientation-option.patch
blob: bae85429fca388a7dcd168cbf418e9d878a57cb7 (plain)
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
From 8ced376eb1efece6df825b474f2f2fb1dfb9e863 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?=
 <samsagax@gmail.com>
Date: Mon, 18 Jul 2022 19:59:41 -0300
Subject: [PATCH 1/2] Add --force-orientation option

---
 src/drm.cpp      | 51 +++++++++++++++++++++++++++++++-----
 src/drm.hpp      | 27 ++++++++++++-------
 src/main.cpp     | 22 +++++++++++++++-
 src/wlserver.cpp | 67 ++++++++++++++++++++++++++++++++++++++----------
 4 files changed, 138 insertions(+), 29 deletions(-)

diff --git a/src/drm.cpp b/src/drm.cpp
index 980e608..c4204be 100644
--- a/src/drm.cpp
+++ b/src/drm.cpp
@@ -48,6 +48,8 @@ const char *g_sOutputName = nullptr;
 bool g_bSupportsAsyncFlips = false;
 
 enum drm_mode_generation g_drmModeGeneration = DRM_MODE_GENERATE_CVT;
+enum g_panel_orientation g_drmModeOrientation = PANEL_ORIENTATION_AUTO;
+
 
 static LogScope drm_log("drm");
 static LogScope drm_verbose_log("drm", LOG_SILENT);
@@ -1256,7 +1258,7 @@ void drm_lock_fbid( struct drm_t *drm, uint32_t fbid )
 void drm_unlock_fbid( struct drm_t *drm, uint32_t fbid )
 {
 	struct fb &fb = get_fb( *drm, fbid );
-	
+
 	assert( fb.held_refs > 0 );
 	if ( --fb.held_refs != 0 )
 		return;
@@ -1297,7 +1299,26 @@ drm_prepare_basic( struct drm_t *drm, const struct FrameInfo_t *frameInfo )
 
 	drm->fbids_in_req.push_back( fb_id );
 
-	add_plane_property(req, drm->primary, "rotation", g_bRotated ? DRM_MODE_ROTATE_270 : DRM_MODE_ROTATE_0);
+	switch ( g_drmModeOrientation )
+	{
+	case PANEL_ORIENTATION_0:
+		add_plane_property(req, drm->primary, "rotation", DRM_MODE_ROTATE_0);
+		break;
+	case PANEL_ORIENTATION_270:
+		add_plane_property(req, drm->primary, "rotation", DRM_MODE_ROTATE_270);
+		break;
+	case PANEL_ORIENTATION_90:
+		add_plane_property(req, drm->primary, "rotation", DRM_MODE_ROTATE_90);
+		break;
+	case PANEL_ORIENTATION_180:
+		add_plane_property(req, drm->primary, "rotation", DRM_MODE_ROTATE_180);
+		break;
+	/* we are keeping the original method used for by default to prevent a sudden break in compatibility for devices using this method.*/
+	case PANEL_ORIENTATION_AUTO:
+	default:
+		add_plane_property(req, drm->primary, "rotation", g_bRotated ? DRM_MODE_ROTATE_270 : DRM_MODE_ROTATE_0);
+		break;
+	}
 
 	add_plane_property(req, drm->primary, "FB_ID", fb_id);
 	add_plane_property(req, drm->primary, "CRTC_ID", drm->crtc->id);
@@ -1547,7 +1568,25 @@ drm_prepare_liftoff( struct drm_t *drm, const struct FrameInfo_t *frameInfo, boo
 			liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_W", entry.layerState[i].srcW );
 			liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_H", entry.layerState[i].srcH );
 
-			liftoff_layer_set_property( drm->lo_layers[ i ], "rotation", g_bRotated ? DRM_MODE_ROTATE_270 : DRM_MODE_ROTATE_0);
+			switch ( g_drmModeOrientation )
+			{
+				case PANEL_ORIENTATION_0:
+					liftoff_layer_set_property( drm->lo_layers[ i ], "rotation", DRM_MODE_ROTATE_0);
+					break;
+				case PANEL_ORIENTATION_270:
+					liftoff_layer_set_property( drm->lo_layers[ i ], "rotation", DRM_MODE_ROTATE_270);
+					break;
+				case PANEL_ORIENTATION_90:
+					liftoff_layer_set_property( drm->lo_layers[ i ], "rotation", DRM_MODE_ROTATE_90);
+					break;
+				case PANEL_ORIENTATION_180:
+					liftoff_layer_set_property( drm->lo_layers[ i ], "rotation", DRM_MODE_ROTATE_180);
+					break;
+				case PANEL_ORIENTATION_AUTO:
+				default: /* We are using auto to ensure compatibility with devicess that used this method*/
+					liftoff_layer_set_property( drm->lo_layers[ i ], "rotation", g_bRotated ? DRM_MODE_ROTATE_270 : DRM_MODE_ROTATE_0);
+					break;
+			}
 
 			liftoff_layer_set_property( drm->lo_layers[ i ], "CRTC_X", entry.layerState[i].crtcX);
 			liftoff_layer_set_property( drm->lo_layers[ i ], "CRTC_Y", entry.layerState[i].crtcY);
@@ -2047,7 +2086,7 @@ bool drm_update_color_mtx(struct drm_t *drm)
 		drm_ctm.matrix[i] = color.s31_32;
 	}
 
-	uint32_t blob_id = 0;	
+	uint32_t blob_id = 0;
 	if (drmModeCreatePropertyBlob(drm->fd, &drm_ctm,
 			sizeof(struct drm_color_ctm), &blob_id) != 0) {
 		drm_log.errorf_errno("Unable to create CTM property blob");
@@ -2125,7 +2164,7 @@ bool drm_update_gamma_lut(struct drm_t *drm)
 		gamma_lut[i].blue  = drm_calc_lut_value( b_exp, drm->pending.color_linear_gain[2], drm->pending.color_gain[2], drm->pending.gain_blend );
 	}
 
-	uint32_t blob_id = 0;	
+	uint32_t blob_id = 0;
 	if (drmModeCreatePropertyBlob(drm->fd, gamma_lut,
 			lut_entries * sizeof(struct drm_color_lut), &blob_id) != 0) {
 		drm_log.errorf_errno("Unable to create gamma LUT property blob");
@@ -2176,7 +2215,7 @@ bool drm_update_degamma_lut(struct drm_t *drm)
 		degamma_lut[i].blue  = drm_quantize_lut_value( safe_pow( input, drm->pending.color_degamma_exponent[screen_type][2] ) );
 	}
 
-	uint32_t blob_id = 0;	
+	uint32_t blob_id = 0;
 	if (drmModeCreatePropertyBlob(drm->fd, degamma_lut,
 			lut_entries * sizeof(struct drm_color_lut), &blob_id) != 0) {
 		drm_log.errorf_errno("Unable to create degamma LUT property blob");
diff --git a/src/drm.hpp b/src/drm.hpp
index fabda88..a1d2d44 100644
--- a/src/drm.hpp
+++ b/src/drm.hpp
@@ -96,7 +96,7 @@ struct fb {
 	uint32_t id;
 	/* Client buffer, if any */
 	struct wlr_buffer *buf;
-	/* A FB is held if it's being used by steamcompmgr 
+	/* A FB is held if it's being used by steamcompmgr
 	 * doesn't need to be atomic as it's only ever
 	 * modified/read from the steamcompmgr thread */
 	int held_refs;
@@ -118,19 +118,19 @@ struct drm_t {
 	std::unordered_map< uint32_t, struct connector > connectors;
 
 	std::map< uint32_t, drmModePropertyRes * > props;
-	
+
 	struct plane *primary;
 	struct crtc *crtc;
 	struct connector *connector;
 	int crtc_index;
 	int kms_in_fence_fd;
 	int kms_out_fence_fd;
-	
+
 	struct wlr_drm_format_set primary_formats;
-	
+
 	drmModeAtomicReq *req;
 	uint32_t flags;
-	
+
 	struct liftoff_device *lo_device;
 	struct liftoff_output *lo_output;
 	struct liftoff_layer *lo_layers[ k_nMaxLayers ];
@@ -168,16 +168,16 @@ struct drm_t {
 	std::vector < uint32_t > fbids_queued;
 	/* FBs currently on screen */
 	std::vector < uint32_t > fbids_on_screen;
-	
+
 	std::unordered_map< uint32_t, struct fb > fb_map;
 	std::mutex fb_map_mutex;
-	
+
 	std::mutex free_queue_lock;
 	std::vector< uint32_t > fbid_unlock_queue;
 	std::vector< uint32_t > fbid_free_queue;
-	
+
 	std::mutex flip_lock;
-	
+
 	std::atomic < uint64_t > flipcount;
 
 	std::atomic < bool > paused;
@@ -204,7 +204,16 @@ enum drm_mode_generation {
 	DRM_MODE_GENERATE_FIXED,
 };
 
+enum g_panel_orientation {
+	PANEL_ORIENTATION_0,	/* NORMAL */
+	PANEL_ORIENTATION_270,	/* RIGHT */
+	PANEL_ORIENTATION_90,	/* LEFT */
+	PANEL_ORIENTATION_180,	/* UPSIDE DOWN */
+	PANEL_ORIENTATION_AUTO,
+};
+
 extern enum drm_mode_generation g_drmModeGeneration;
+extern enum g_panel_orientation g_drmModeOrientation;
 
 bool init_drm(struct drm_t *drm, int width, int height, int refresh);
 void finish_drm(struct drm_t *drm);
diff --git a/src/main.cpp b/src/main.cpp
index 9f88dfc..6ceb80f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -79,6 +79,7 @@ const struct option *gamescope_options = (struct option[]){
 	{ "composite-debug", no_argument, nullptr, 0 },
 	{ "disable-xres", no_argument, nullptr, 'x' },
 	{ "fade-out-duration", required_argument, nullptr, 0 },
+	{ "force-orientation", required_argument, nullptr, 0 },
 
 	{} // keep last
 };
@@ -107,6 +108,7 @@ const char usage[] =
 	"  -e, --steam                    enable Steam integration\n"
 	"  --xwayland-count               create N xwayland servers\n"
 	"  --prefer-vk-device             prefer Vulkan device for compositing (ex: 1002:7300)\n"
+	"  --force-orientation             rotate the display (left, right, normal, upsidedown)\n"
 	"\n"
 	"Nested mode options:\n"
 	"  -o, --nested-unfocused-refresh game refresh rate when unfocused\n"
@@ -217,6 +219,22 @@ static enum drm_mode_generation parse_drm_mode_generation(const char *str)
 	}
 }
 
+static enum g_panel_orientation force_orientation (const char *str)
+{
+	if (strcmp(str, "normal") == 0) {
+		return PANEL_ORIENTATION_0;
+	} else if (strcmp(str, "right") == 0) {
+		return PANEL_ORIENTATION_270;
+	} else if (strcmp(str, "left") == 0) {
+		return PANEL_ORIENTATION_90;
+	} else if (strcmp(str, "upsidedown") == 0) {
+		return PANEL_ORIENTATION_180;
+	} else {
+		fprintf( stderr, "gamescope: invalid value for --force-orientation\n" );
+		exit(1);
+	}
+}
+
 static void handle_signal( int sig )
 {
 	switch ( sig ) {
@@ -371,6 +389,8 @@ int main(int argc, char **argv)
 					g_nTouchClickMode = g_nDefaultTouchClickMode;
 				} else if (strcmp(opt_name, "generate-drm-mode") == 0) {
 					g_drmModeGeneration = parse_drm_mode_generation( optarg );
+				} else if (strcmp(opt_name, "force-orientation") == 0) {
+					g_drmModeOrientation = force_orientation( optarg );
 				} else if (strcmp(opt_name, "sharpness") == 0 ||
 						   strcmp(opt_name, "fsr-sharpness") == 0) {
 					g_upscalerSharpness = atoi( optarg );
@@ -533,7 +553,7 @@ int main(int argc, char **argv)
 		fprintf( stderr, "Failed to initialize wlserver\n" );
 		return 1;
 	}
-	
+
 	gamescope_xwayland_server_t *base_server = wlserver_get_xwayland_server(0);
 
 	setenv("DISPLAY", base_server->get_nested_display_name(), 1);
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
index 27240ff..0bdb8a4 100644
--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -6,7 +6,7 @@
 #include <unistd.h>
 #include <pthread.h>
 #include <string.h>
-#include <poll.h>	
+#include <poll.h>
 
 #include <linux/input-event-codes.h>
 
@@ -65,6 +65,7 @@ struct wlserver_content_override {
 enum wlserver_touch_click_mode g_nDefaultTouchClickMode = WLSERVER_TOUCH_CLICK_LEFT;
 enum wlserver_touch_click_mode g_nTouchClickMode = g_nDefaultTouchClickMode;
 
+
 static struct wl_list pending_surfaces = {0};
 
 static void wlserver_x11_surface_info_set_wlr( struct wlserver_x11_surface_info *surf, struct wlr_surface *wlr_surf );
@@ -1011,18 +1012,38 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time )
 {
 	if ( wlserver.mouse_focus_surface != NULL )
 	{
-		double tx = g_bRotated ? y : x;
-		double ty = g_bRotated ? 1.0 - x : y;
-
+		double tx = 0;
+		double ty = 0;
+		switch ( g_drmModeOrientation )
+		{
+			case PANEL_ORIENTATION_0:
+				tx = x;
+				ty = y;
+				break;
+			case PANEL_ORIENTATION_90:
+				tx = 1.0 - y;
+				ty = x;
+				break;
+			case PANEL_ORIENTATION_180:
+				tx = 1.0 - x;
+				ty = 1.0 - y;
+				break;
+			case PANEL_ORIENTATION_270:
+				tx = y;
+				ty = 1.0 - x;
+				break;
+			case PANEL_ORIENTATION_AUTO:
+			default: /* we are using the "auto" enum case to ensure compatibility for devices that were already using this*/
+				tx = g_bRotated ? y : x;
+				ty = g_bRotated ? 1.0 - x : y;
+				break;
+		}
 		tx *= g_nOutputWidth;
 		ty *= g_nOutputHeight;
-
 		tx += focusedWindowOffsetX;
 		ty += focusedWindowOffsetY;
-
 		tx *= focusedWindowScaleX;
 		ty *= focusedWindowScaleY;
-
 		wlserver.mouse_surface_cursorx = tx;
 		wlserver.mouse_surface_cursory = ty;
 
@@ -1050,18 +1071,38 @@ void wlserver_touchdown( double x, double y, int touch_id, uint32_t time )
 {
 	if ( wlserver.mouse_focus_surface != NULL )
 	{
-		double tx = g_bRotated ? y : x;
-		double ty = g_bRotated ? 1.0 - x : y;
-
+		double tx = 0;
+		double ty = 0;
+		switch ( g_drmModeOrientation )
+		{
+			case PANEL_ORIENTATION_0:
+				tx = x;
+				ty = y;
+				break;
+			case PANEL_ORIENTATION_90:
+				tx = 1.0 - y;
+				ty = x;
+				break;
+			case PANEL_ORIENTATION_180:
+				tx =  1.0 - x;
+				ty =  1.0 - y;
+				break;
+			case PANEL_ORIENTATION_270:
+				tx = y;
+				ty = 1.0 - x;
+				break;
+			case PANEL_ORIENTATION_AUTO:
+			default: /* we are using the "auto" enum case to ensure compatibility for devices that were already using this*/
+				tx = g_bRotated ? y : x;
+				ty = g_bRotated ? 1.0 - x : y;
+				break;
+		}
 		tx *= g_nOutputWidth;
 		ty *= g_nOutputHeight;
-
 		tx += focusedWindowOffsetX;
 		ty += focusedWindowOffsetY;
-
 		tx *= focusedWindowScaleX;
 		ty *= focusedWindowScaleY;
-
 		wlserver.mouse_surface_cursorx = tx;
 		wlserver.mouse_surface_cursory = ty;
 
-- 
2.37.3