1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <errno.h>
19 #include <string.h>
20 #include <signal.h>
21 #include <sys/ioctl.h>
22 #include <poll.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <limits.h>
26 #include <math.h>
27 #include <time.h>
28 
29 #include "config.h"
30 
31 #if HAVE_CONSIO_H
32 #include <sys/consio.h>
33 #else
34 #include <sys/vt.h>
35 #endif
36 
37 #include "drm_common.h"
38 
39 #include "common/common.h"
40 #include "common/msg.h"
41 #include "osdep/io.h"
42 #include "osdep/timer.h"
43 #include "misc/ctype.h"
44 #include "video/out/vo.h"
45 
46 #define EVT_RELEASE 1
47 #define EVT_ACQUIRE 2
48 #define EVT_INTERRUPT 255
49 #define HANDLER_ACQUIRE 0
50 #define HANDLER_RELEASE 1
51 #define RELEASE_SIGNAL SIGUSR1
52 #define ACQUIRE_SIGNAL SIGUSR2
53 #define MAX_CONNECTOR_NAME_LEN 20
54 
55 static int vt_switcher_pipe[2];
56 
57 static int drm_connector_opt_help(
58     struct mp_log *log, const struct m_option *opt, struct bstr name);
59 
60 static int drm_mode_opt_help(
61     struct mp_log *log, const struct m_option *opt, struct bstr name);
62 
63 static int drm_validate_mode_opt(
64     struct mp_log *log, const struct m_option *opt, struct bstr name,
65     const char **value);
66 
67 static void kms_show_available_modes(
68     struct mp_log *log, const drmModeConnector *connector);
69 
70 static void kms_show_available_connectors(struct mp_log *log, int card_no,
71                                           const char *card_path);
72 static double mode_get_Hz(const drmModeModeInfo *mode);
73 
74 #define OPT_BASE_STRUCT struct drm_opts
75 const struct m_sub_options drm_conf = {
76     .opts = (const struct m_option[]) {
77         {"drm-device", OPT_STRING(drm_device_path), .flags = M_OPT_FILE},
78         {"drm-connector", OPT_STRING(drm_connector_spec),
79             .help = drm_connector_opt_help},
80         {"drm-mode", OPT_STRING_VALIDATE(drm_mode_spec, drm_validate_mode_opt),
81             .help = drm_mode_opt_help},
82         {"drm-atomic", OPT_CHOICE(drm_atomic, {"no", 0}, {"auto", 1})},
83         {"drm-draw-plane", OPT_CHOICE(drm_draw_plane,
84             {"primary", DRM_OPTS_PRIMARY_PLANE},
85             {"overlay", DRM_OPTS_OVERLAY_PLANE}),
86             M_RANGE(0, INT_MAX)},
87         {"drm-drmprime-video-plane", OPT_CHOICE(drm_drmprime_video_plane,
88             {"primary", DRM_OPTS_PRIMARY_PLANE},
89             {"overlay", DRM_OPTS_OVERLAY_PLANE}),
90             M_RANGE(0, INT_MAX)},
91         {"drm-format", OPT_CHOICE(drm_format,
92             {"xrgb8888",    DRM_OPTS_FORMAT_XRGB8888},
93             {"xrgb2101010", DRM_OPTS_FORMAT_XRGB2101010})},
94         {"drm-draw-surface-size", OPT_SIZE_BOX(drm_draw_surface_size)},
95 
96         {"drm-osd-plane-id", OPT_REPLACED("drm-draw-plane")},
97         {"drm-video-plane-id", OPT_REPLACED("drm-drmprime-video-plane")},
98         {"drm-osd-size", OPT_REPLACED("drm-draw-surface-size")},
99         {0},
100     },
101     .defaults = &(const struct drm_opts) {
102         .drm_mode_spec = "preferred",
103         .drm_atomic = 1,
104         .drm_draw_plane = DRM_OPTS_PRIMARY_PLANE,
105         .drm_drmprime_video_plane = DRM_OPTS_OVERLAY_PLANE,
106     },
107     .size = sizeof(struct drm_opts),
108 };
109 
110 static const char *connector_names[] = {
111     "Unknown",   // DRM_MODE_CONNECTOR_Unknown
112     "VGA",       // DRM_MODE_CONNECTOR_VGA
113     "DVI-I",     // DRM_MODE_CONNECTOR_DVII
114     "DVI-D",     // DRM_MODE_CONNECTOR_DVID
115     "DVI-A",     // DRM_MODE_CONNECTOR_DVIA
116     "Composite", // DRM_MODE_CONNECTOR_Composite
117     "SVIDEO",    // DRM_MODE_CONNECTOR_SVIDEO
118     "LVDS",      // DRM_MODE_CONNECTOR_LVDS
119     "Component", // DRM_MODE_CONNECTOR_Component
120     "DIN",       // DRM_MODE_CONNECTOR_9PinDIN
121     "DP",        // DRM_MODE_CONNECTOR_DisplayPort
122     "HDMI-A",    // DRM_MODE_CONNECTOR_HDMIA
123     "HDMI-B",    // DRM_MODE_CONNECTOR_HDMIB
124     "TV",        // DRM_MODE_CONNECTOR_TV
125     "eDP",       // DRM_MODE_CONNECTOR_eDP
126     "Virtual",   // DRM_MODE_CONNECTOR_VIRTUAL
127     "DSI",       // DRM_MODE_CONNECTOR_DSI
128     "DPI",       // DRM_MODE_CONNECTOR_DPI
129     "Writeback", // DRM_MODE_CONNECTOR_WRITEBACK
130     "SPI",       // DRM_MODE_CONNECTOR_SPI
131     "USB",       // DRM_MODE_CONNECTOR_USB
132 };
133 
134 struct drm_mode_spec {
135     enum {
136         DRM_MODE_SPEC_BY_IDX,     // Specified by idx
137         DRM_MODE_SPEC_BY_NUMBERS, // Specified by width, height and opt. refresh
138         DRM_MODE_SPEC_PREFERRED,  // Select the preferred mode of the display
139         DRM_MODE_SPEC_HIGHEST,    // Select the mode with the highest resolution
140     } type;
141     unsigned int idx;
142     unsigned int width;
143     unsigned int height;
144     double refresh;
145 };
146 
147 // KMS ------------------------------------------------------------------------
148 
get_connector_name(const drmModeConnector * connector,char ret[MAX_CONNECTOR_NAME_LEN])149 static void get_connector_name(const drmModeConnector *connector,
150                                char ret[MAX_CONNECTOR_NAME_LEN])
151 {
152     const char *type_name;
153 
154     if (connector->connector_type < MP_ARRAY_SIZE(connector_names)) {
155         type_name = connector_names[connector->connector_type];
156     } else {
157         type_name = "UNKNOWN";
158     }
159 
160     snprintf(ret, MAX_CONNECTOR_NAME_LEN, "%s-%d", type_name,
161              connector->connector_type_id);
162 }
163 
164 // Gets the first connector whose name matches the input parameter.
165 // The returned connector may be disconnected.
166 // Result must be freed with drmModeFreeConnector.
get_connector_by_name(const struct kms * kms,const drmModeRes * res,const char * connector_name)167 static drmModeConnector *get_connector_by_name(const struct kms *kms,
168                                                const drmModeRes *res,
169                                                const char *connector_name)
170 {
171     for (int i = 0; i < res->count_connectors; i++) {
172         drmModeConnector *connector
173             = drmModeGetConnector(kms->fd, res->connectors[i]);
174         if (!connector)
175             continue;
176         char other_connector_name[MAX_CONNECTOR_NAME_LEN];
177         get_connector_name(connector, other_connector_name);
178         if (!strcmp(connector_name, other_connector_name))
179             return connector;
180         drmModeFreeConnector(connector);
181     }
182     return NULL;
183 }
184 
185 // Gets the first connected connector.
186 // Result must be freed with drmModeFreeConnector.
get_first_connected_connector(const struct kms * kms,const drmModeRes * res)187 static drmModeConnector *get_first_connected_connector(const struct kms *kms,
188                                                        const drmModeRes *res)
189 {
190     for (int i = 0; i < res->count_connectors; i++) {
191         drmModeConnector *connector
192             = drmModeGetConnector(kms->fd, res->connectors[i]);
193         if (!connector)
194             continue;
195         if (connector->connection == DRM_MODE_CONNECTED
196         && connector->count_modes > 0) {
197             return connector;
198         }
199         drmModeFreeConnector(connector);
200     }
201     return NULL;
202 }
203 
setup_connector(struct kms * kms,const drmModeRes * res,const char * connector_name)204 static bool setup_connector(struct kms *kms, const drmModeRes *res,
205                             const char *connector_name)
206 {
207     drmModeConnector *connector;
208 
209     if (connector_name
210     && strcmp(connector_name, "")
211     && strcmp(connector_name, "auto")) {
212         connector = get_connector_by_name(kms, res, connector_name);
213         if (!connector) {
214             MP_ERR(kms, "No connector with name %s found\n", connector_name);
215             kms_show_available_connectors(kms->log, kms->card_no,
216                                           kms->primary_node_path);
217             return false;
218         }
219     } else {
220         connector = get_first_connected_connector(kms, res);
221         if (!connector) {
222             MP_ERR(kms, "No connected connectors found\n");
223             return false;
224         }
225     }
226 
227     if (connector->connection != DRM_MODE_CONNECTED) {
228         drmModeFreeConnector(connector);
229         MP_ERR(kms, "Chosen connector is disconnected\n");
230         return false;
231     }
232 
233     if (connector->count_modes == 0) {
234         drmModeFreeConnector(connector);
235         MP_ERR(kms, "Chosen connector has no valid modes\n");
236         return false;
237     }
238 
239     kms->connector = connector;
240     return true;
241 }
242 
setup_crtc(struct kms * kms,const drmModeRes * res)243 static bool setup_crtc(struct kms *kms, const drmModeRes *res)
244 {
245     // First try to find currently connected encoder and its current CRTC
246     for (unsigned int i = 0; i < res->count_encoders; i++) {
247         drmModeEncoder *encoder = drmModeGetEncoder(kms->fd, res->encoders[i]);
248         if (!encoder) {
249             MP_WARN(kms, "Cannot retrieve encoder %u:%u: %s\n",
250                     i, res->encoders[i], mp_strerror(errno));
251             continue;
252         }
253 
254         if (encoder->encoder_id == kms->connector->encoder_id && encoder->crtc_id != 0) {
255             MP_VERBOSE(kms, "Connector %u currently connected to encoder %u\n",
256                        kms->connector->connector_id, kms->connector->encoder_id);
257             kms->encoder = encoder;
258             kms->crtc_id = encoder->crtc_id;
259             goto success;
260         }
261 
262         drmModeFreeEncoder(encoder);
263     }
264 
265     // Otherwise pick first legal encoder and CRTC combo for the connector
266     for (unsigned int i = 0; i < kms->connector->count_encoders; ++i) {
267         drmModeEncoder *encoder
268             = drmModeGetEncoder(kms->fd, kms->connector->encoders[i]);
269         if (!encoder) {
270             MP_WARN(kms, "Cannot retrieve encoder %u:%u: %s\n",
271                     i, kms->connector->encoders[i], mp_strerror(errno));
272             continue;
273         }
274 
275         // iterate all global CRTCs
276         for (unsigned int j = 0; j < res->count_crtcs; ++j) {
277             // check whether this CRTC works with the encoder
278             if (!(encoder->possible_crtcs & (1 << j)))
279                 continue;
280 
281             kms->encoder = encoder;
282             kms->crtc_id = res->crtcs[j];
283             goto success;
284         }
285 
286         drmModeFreeEncoder(encoder);
287     }
288 
289     MP_ERR(kms, "Connector %u has no suitable CRTC\n",
290            kms->connector->connector_id);
291     return false;
292 
293   success:
294     MP_VERBOSE(kms, "Selected Encoder %u with CRTC %u\n",
295                kms->encoder->encoder_id, kms->crtc_id);
296     return true;
297 }
298 
all_digits(const char * str)299 static bool all_digits(const char *str)
300 {
301     if (str == NULL || str[0] == '\0') {
302         return false;
303     }
304 
305     for (const char *c = str; *c != '\0'; ++c) {
306         if (!mp_isdigit(*c))
307             return false;
308     }
309     return true;
310 }
311 
parse_mode_spec(const char * spec,struct drm_mode_spec * parse_result)312 static bool parse_mode_spec(const char *spec, struct drm_mode_spec *parse_result)
313 {
314     if (spec == NULL || spec[0] == '\0' || strcmp(spec, "preferred") == 0) {
315         if (parse_result) {
316             *parse_result =
317                 (struct drm_mode_spec) { .type = DRM_MODE_SPEC_PREFERRED };
318         }
319         return true;
320     }
321 
322     if (strcmp(spec, "highest") == 0) {
323         if (parse_result) {
324             *parse_result =
325                 (struct drm_mode_spec) { .type = DRM_MODE_SPEC_HIGHEST };
326         }
327         return true;
328     }
329 
330     // If the string is made up of only digits, it means that it is an index number
331     if (all_digits(spec)) {
332         if (parse_result) {
333             *parse_result = (struct drm_mode_spec) {
334                 .type = DRM_MODE_SPEC_BY_IDX,
335                 .idx = strtoul(spec, NULL, 10),
336             };
337         }
338         return true;
339     }
340 
341     if (!mp_isdigit(spec[0]))
342         return false;
343     char *height_part, *refresh_part;
344     const unsigned int width = strtoul(spec, &height_part, 10);
345     if (spec == height_part || height_part[0] == '\0' || height_part[0] != 'x')
346         return false;
347 
348     height_part += 1;
349     if (!mp_isdigit(height_part[0]))
350         return false;
351     const unsigned int height = strtoul(height_part, &refresh_part, 10);
352     if (height_part == refresh_part)
353         return false;
354 
355     char *rest = NULL;
356     double refresh;
357     switch (refresh_part[0]) {
358     case '\0':
359         refresh = nan("");
360         break;
361     case '@':
362         refresh_part += 1;
363         if (!(mp_isdigit(refresh_part[0]) || refresh_part[0] == '.'))
364             return false;
365         refresh = strtod(refresh_part, &rest);
366         if (refresh_part == rest || rest[0] != '\0' || refresh < 0.0)
367             return false;
368         break;
369     default:
370         return false;
371     }
372 
373     if (parse_result) {
374         *parse_result = (struct drm_mode_spec) {
375             .type = DRM_MODE_SPEC_BY_NUMBERS,
376             .width = width,
377             .height = height,
378             .refresh = refresh,
379         };
380     }
381     return true;
382 }
383 
setup_mode_by_idx(struct kms * kms,unsigned int mode_idx)384 static bool setup_mode_by_idx(struct kms *kms, unsigned int mode_idx)
385 {
386     if (mode_idx >= kms->connector->count_modes) {
387         MP_ERR(kms, "Bad mode index (max = %d).\n",
388                kms->connector->count_modes - 1);
389         return false;
390     }
391 
392     kms->mode.mode = kms->connector->modes[mode_idx];
393     return true;
394 }
395 
mode_match(const drmModeModeInfo * mode,unsigned int width,unsigned int height,double refresh)396 static bool mode_match(const drmModeModeInfo *mode,
397                        unsigned int width,
398                        unsigned int height,
399                        double refresh)
400 {
401     if (isnan(refresh)) {
402         return
403             (mode->hdisplay == width) &&
404             (mode->vdisplay == height);
405     } else {
406         const double mode_refresh = mode_get_Hz(mode);
407         return
408             (mode->hdisplay == width) &&
409             (mode->vdisplay == height) &&
410             ((int)round(refresh*100) == (int)round(mode_refresh*100));
411     }
412 }
413 
setup_mode_by_numbers(struct kms * kms,unsigned int width,unsigned int height,double refresh,const char * mode_spec)414 static bool setup_mode_by_numbers(struct kms *kms,
415                                   unsigned int width,
416                                   unsigned int height,
417                                   double refresh,
418                                   const char *mode_spec)
419 {
420     for (unsigned int i = 0; i < kms->connector->count_modes; ++i) {
421         drmModeModeInfo *current_mode = &kms->connector->modes[i];
422         if (mode_match(current_mode, width, height, refresh)) {
423             kms->mode.mode = *current_mode;
424             return true;
425         }
426     }
427 
428     MP_ERR(kms, "Could not find mode matching %s\n", mode_spec);
429     return false;
430 }
431 
setup_mode_preferred(struct kms * kms)432 static bool setup_mode_preferred(struct kms *kms)
433 {
434     for (unsigned int i = 0; i < kms->connector->count_modes; ++i) {
435         drmModeModeInfo *current_mode = &kms->connector->modes[i];
436         if (current_mode->type & DRM_MODE_TYPE_PREFERRED) {
437             kms->mode.mode = *current_mode;
438             return true;
439         }
440     }
441 
442     // Fall back to first mode
443     MP_WARN(kms, "Could not find any preferred mode. Picking the first mode.\n");
444     kms->mode.mode = kms->connector->modes[0];
445     return true;
446 }
447 
setup_mode_highest(struct kms * kms)448 static bool setup_mode_highest(struct kms *kms)
449 {
450     unsigned int area = 0;
451     drmModeModeInfo *highest_resolution_mode = &kms->connector->modes[0];
452     for (unsigned int i = 0; i < kms->connector->count_modes; ++i) {
453         drmModeModeInfo *current_mode = &kms->connector->modes[i];
454 
455         const unsigned int current_area =
456             current_mode->hdisplay * current_mode->vdisplay;
457         if (current_area > area) {
458             highest_resolution_mode = current_mode;
459             area = current_area;
460         }
461     }
462 
463     kms->mode.mode = *highest_resolution_mode;
464     return true;
465 }
466 
setup_mode(struct kms * kms,const char * mode_spec)467 static bool setup_mode(struct kms *kms, const char *mode_spec)
468 {
469     if (kms->connector->count_modes <= 0) {
470         MP_ERR(kms, "No available modes\n");
471         return false;
472     }
473 
474     struct drm_mode_spec parsed;
475     if (!parse_mode_spec(mode_spec, &parsed)) {
476         MP_ERR(kms, "Parse error\n");
477         goto err;
478     }
479 
480     switch (parsed.type) {
481     case DRM_MODE_SPEC_BY_IDX:
482         if (!setup_mode_by_idx(kms, parsed.idx))
483             goto err;
484         break;
485     case DRM_MODE_SPEC_BY_NUMBERS:
486         if (!setup_mode_by_numbers(kms, parsed.width, parsed.height, parsed.refresh,
487                                    mode_spec))
488             goto err;
489         break;
490     case DRM_MODE_SPEC_PREFERRED:
491         if (!setup_mode_preferred(kms))
492             goto err;
493         break;
494     case DRM_MODE_SPEC_HIGHEST:
495         if (!setup_mode_highest(kms))
496             goto err;
497         break;
498     default:
499         MP_ERR(kms, "setup_mode: Internal error\n");
500         goto err;
501     }
502 
503     drmModeModeInfo *mode = &kms->mode.mode;
504     MP_VERBOSE(kms, "Selected mode: %s (%dx%d@%.2fHz)\n",
505         mode->name, mode->hdisplay, mode->vdisplay, mode_get_Hz(mode));
506 
507     return true;
508 
509 err:
510     MP_INFO(kms, "Available modes:\n");
511     kms_show_available_modes(kms->log, kms->connector);
512     return false;
513 }
514 
open_card_path(const char * path)515 static int open_card_path(const char *path)
516 {
517     return open(path, O_RDWR | O_CLOEXEC);
518 }
519 
get_primary_device_path(struct mp_log * log,int * card_no)520 static char *get_primary_device_path(struct mp_log *log, int *card_no)
521 {
522     drmDevice *devices[DRM_MAX_MINOR] = { 0 };
523     int card_count = drmGetDevices2(0, devices, MP_ARRAY_SIZE(devices));
524     char *device_path = NULL;
525     bool card_no_given = (*card_no >= 0);
526 
527     if (card_count < 0) {
528         mp_err(log, "Listing DRM devices with drmGetDevices failed! (%s)\n",
529                mp_strerror(errno));
530         goto err;
531     }
532 
533     if (card_no_given && *card_no > (card_count - 1)) {
534         mp_err(log, "Card number %d given too high! %d devices located.\n",
535                *card_no, card_count);
536         goto err;
537     }
538 
539     for (int i = card_no_given ? *card_no : 0; i < card_count; i++) {
540         drmDevice *dev = devices[i];
541 
542         if (!(dev->available_nodes & (1 << DRM_NODE_PRIMARY))) {
543             if (card_no_given) {
544                 mp_err(log,
545                        "DRM card number %d given, yet it does not have "
546                        "a primary node!\n", i);
547                 break;
548             }
549 
550             continue;
551         }
552 
553         const char *primary_node_path = dev->nodes[DRM_NODE_PRIMARY];
554 
555         mp_verbose(log, "Picked DRM card %d, primary node %s%s.\n",
556                    i, primary_node_path,
557                    card_no_given ? "" : " as the default");
558 
559         device_path = talloc_strdup(log, primary_node_path);
560         *card_no = i;
561         break;
562     }
563 
564     if (!device_path)
565         mp_err(log, "No primary DRM device could be picked!\n");
566 
567 err:
568     drmFreeDevices(devices, card_count);
569 
570     return device_path;
571 }
572 
parse_connector_spec(struct mp_log * log,const char * connector_spec,int * card_no,char ** connector_name)573 static void parse_connector_spec(struct mp_log *log,
574                                  const char *connector_spec,
575                                  int *card_no, char **connector_name)
576 {
577     if (!connector_spec) {
578         *card_no = -1;
579         *connector_name = NULL;
580         return;
581     }
582     char *dot_ptr = strchr(connector_spec, '.');
583     if (dot_ptr) {
584         mp_warn(log, "Warning: Selecting a connector by index with drm-connector "
585                      "is deprecated. Use the drm-device option instead.\n");
586         *card_no = atoi(connector_spec);
587         *connector_name = talloc_strdup(log, dot_ptr + 1);
588     } else {
589         *card_no = -1;
590         *connector_name = talloc_strdup(log, connector_spec);
591     }
592 }
593 
kms_create(struct mp_log * log,const char * drm_device_path,const char * connector_spec,const char * mode_spec,int draw_plane,int drmprime_video_plane,bool use_atomic)594 struct kms *kms_create(struct mp_log *log,
595                        const char *drm_device_path,
596                        const char *connector_spec,
597                        const char* mode_spec,
598                        int draw_plane, int drmprime_video_plane,
599                        bool use_atomic)
600 {
601     int card_no = -1;
602     char *connector_name = NULL;
603 
604     parse_connector_spec(log, connector_spec, &card_no, &connector_name);
605     if (drm_device_path && card_no != -1)
606         mp_warn(log, "Both DRM device and card number (as part of "
607                      "drm-connector) are set! Will prefer given device path "
608                      "'%s'!\n",
609                 drm_device_path);
610 
611     char *primary_node_path = drm_device_path ?
612                               talloc_strdup(log, drm_device_path) :
613                               get_primary_device_path(log, &card_no);
614 
615     if (!primary_node_path) {
616         mp_err(log,
617                "Failed to find a usable DRM primary node!\n");
618         return NULL;
619     }
620 
621     struct kms *kms = talloc(NULL, struct kms);
622     *kms = (struct kms) {
623         .log = mp_log_new(kms, log, "kms"),
624         .primary_node_path = primary_node_path,
625         .fd = open_card_path(primary_node_path),
626         .connector = NULL,
627         .encoder = NULL,
628         .mode = {{0}},
629         .crtc_id = -1,
630         .card_no = card_no,
631     };
632 
633     drmModeRes *res = NULL;
634 
635     if (kms->fd < 0) {
636         mp_err(log, "Cannot open card \"%d\": %s.\n",
637                card_no, mp_strerror(errno));
638         goto err;
639     }
640 
641     drmVersionPtr ver = drmGetVersion(kms->fd);
642     if (ver) {
643         mp_verbose(log, "Driver: %s %d.%d.%d (%s)\n", ver->name,
644             ver->version_major, ver->version_minor, ver->version_patchlevel,
645             ver->date);
646         drmFreeVersion(ver);
647     }
648 
649     res = drmModeGetResources(kms->fd);
650     if (!res) {
651         mp_err(log, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno));
652         goto err;
653     }
654 
655     if (!setup_connector(kms, res, connector_name))
656         goto err;
657     if (!setup_crtc(kms, res))
658         goto err;
659     if (!setup_mode(kms, mode_spec))
660         goto err;
661 
662     // Universal planes allows accessing all the planes (including primary)
663     if (drmSetClientCap(kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) {
664         mp_err(log, "Failed to set Universal planes capability\n");
665     }
666 
667     if (!use_atomic) {
668         mp_verbose(log, "Using Legacy Modesetting\n");
669     } else if (drmSetClientCap(kms->fd, DRM_CLIENT_CAP_ATOMIC, 1)) {
670         mp_verbose(log, "No DRM Atomic support found. Falling back to legacy modesetting\n");
671     } else {
672         mp_verbose(log, "DRM Atomic support found\n");
673         kms->atomic_context = drm_atomic_create_context(kms->log, kms->fd, kms->crtc_id,
674                                                         kms->connector->connector_id,
675                                                         draw_plane, drmprime_video_plane);
676         if (!kms->atomic_context) {
677             mp_err(log, "Failed to create DRM atomic context\n");
678             goto err;
679         }
680     }
681 
682     drmModeFreeResources(res);
683     return kms;
684 
685 err:
686     if (res)
687         drmModeFreeResources(res);
688     if (connector_name)
689         talloc_free(connector_name);
690 
691     kms_destroy(kms);
692     return NULL;
693 }
694 
kms_destroy(struct kms * kms)695 void kms_destroy(struct kms *kms)
696 {
697     if (!kms)
698         return;
699     drm_mode_destroy_blob(kms->fd, &kms->mode);
700     if (kms->connector) {
701         drmModeFreeConnector(kms->connector);
702         kms->connector = NULL;
703     }
704     if (kms->encoder) {
705         drmModeFreeEncoder(kms->encoder);
706         kms->encoder = NULL;
707     }
708     if (kms->atomic_context) {
709        drm_atomic_destroy_context(kms->atomic_context);
710     }
711 
712     close(kms->fd);
713     talloc_free(kms);
714 }
715 
mode_get_Hz(const drmModeModeInfo * mode)716 static double mode_get_Hz(const drmModeModeInfo *mode)
717 {
718     double rate = mode->clock * 1000.0 / mode->htotal / mode->vtotal;
719     if (mode->flags & DRM_MODE_FLAG_INTERLACE)
720         rate *= 2.0;
721     return rate;
722 }
723 
kms_show_available_modes(struct mp_log * log,const drmModeConnector * connector)724 static void kms_show_available_modes(
725     struct mp_log *log, const drmModeConnector *connector)
726 {
727     for (unsigned int i = 0; i < connector->count_modes; i++) {
728         mp_info(log, "  Mode %d: %s (%dx%d@%.2fHz)\n", i,
729                 connector->modes[i].name,
730                 connector->modes[i].hdisplay,
731                 connector->modes[i].vdisplay,
732                 mode_get_Hz(&connector->modes[i]));
733     }
734 }
735 
kms_show_foreach_connector(struct mp_log * log,int card_no,const char * card_path,void (* show_fn)(struct mp_log *,int,const drmModeConnector *))736 static void kms_show_foreach_connector(struct mp_log *log, int card_no,
737                                        const char *card_path,
738                                        void (*show_fn)(struct mp_log*, int,
739                                                        const drmModeConnector*))
740 {
741     int fd = open_card_path(card_path);
742     if (fd < 0) {
743         mp_err(log, "Failed to open card %d (%s)\n", card_no, card_path);
744         return;
745     }
746 
747     drmModeRes *res = drmModeGetResources(fd);
748     if (!res) {
749         mp_err(log, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno));
750         goto err;
751     }
752 
753     for (int i = 0; i < res->count_connectors; i++) {
754         drmModeConnector *connector
755             = drmModeGetConnector(fd, res->connectors[i]);
756         if (!connector)
757             continue;
758         show_fn(log, card_no, connector);
759         drmModeFreeConnector(connector);
760     }
761 
762 err:
763     if (fd >= 0)
764         close(fd);
765     if (res)
766         drmModeFreeResources(res);
767 }
768 
kms_show_connector_name_and_state_callback(struct mp_log * log,int card_no,const drmModeConnector * connector)769 static void kms_show_connector_name_and_state_callback(
770     struct mp_log *log, int card_no, const drmModeConnector *connector)
771 {
772     char other_connector_name[MAX_CONNECTOR_NAME_LEN];
773     get_connector_name(connector, other_connector_name);
774     const char *connection_str =
775         (connector->connection == DRM_MODE_CONNECTED) ? "connected" : "disconnected";
776     mp_info(log, "  %s (%s)\n", other_connector_name, connection_str);
777 }
778 
kms_show_available_connectors(struct mp_log * log,int card_no,const char * card_path)779 static void kms_show_available_connectors(struct mp_log *log, int card_no,
780                                           const char *card_path)
781 {
782     mp_info(log, "Available connectors for card %d (%s):\n", card_no,
783             card_path);
784     kms_show_foreach_connector(
785         log, card_no, card_path, kms_show_connector_name_and_state_callback);
786     mp_info(log, "\n");
787 }
788 
kms_show_connector_modes_callback(struct mp_log * log,int card_no,const drmModeConnector * connector)789 static void kms_show_connector_modes_callback(struct mp_log *log, int card_no,
790                                               const drmModeConnector *connector)
791 {
792     if (connector->connection != DRM_MODE_CONNECTED)
793         return;
794 
795     char other_connector_name[MAX_CONNECTOR_NAME_LEN];
796     get_connector_name(connector, other_connector_name);
797     mp_info(log, "Available modes for drm-connector=%d.%s\n",
798             card_no, other_connector_name);
799     kms_show_available_modes(log, connector);
800     mp_info(log, "\n");
801 }
802 
kms_show_available_connectors_and_modes(struct mp_log * log,int card_no,const char * card_path)803 static void kms_show_available_connectors_and_modes(struct mp_log *log,
804                                                     int card_no,
805                                                     const char *card_path)
806 {
807     kms_show_foreach_connector(log, card_no, card_path,
808                                kms_show_connector_modes_callback);
809 }
810 
kms_show_foreach_card(struct mp_log * log,void (* show_fn)(struct mp_log *,int,const char *))811 static void kms_show_foreach_card(
812     struct mp_log *log, void (*show_fn)(struct mp_log*,int,const char *))
813 {
814     drmDevice *devices[DRM_MAX_MINOR] = { 0 };
815     int card_count = drmGetDevices2(0, devices, MP_ARRAY_SIZE(devices));
816     if (card_count < 0) {
817         mp_err(log, "Listing DRM devices with drmGetDevices failed! (%s)\n",
818                mp_strerror(errno));
819         return;
820     }
821 
822     for (int i = 0; i < card_count; i++) {
823         drmDevice *dev = devices[i];
824 
825         if (!(dev->available_nodes & (1 << DRM_NODE_PRIMARY)))
826             continue;
827 
828         const char *primary_node_path = dev->nodes[DRM_NODE_PRIMARY];
829 
830         int fd = open_card_path(primary_node_path);
831         if (fd < 0) {
832             mp_err(log, "Failed to open primary DRM node path %s!\n",
833                    primary_node_path);
834             continue;
835         }
836 
837         close(fd);
838         show_fn(log, i, primary_node_path);
839     }
840 
841     drmFreeDevices(devices, card_count);
842 }
843 
kms_show_available_cards_and_connectors(struct mp_log * log)844 static void kms_show_available_cards_and_connectors(struct mp_log *log)
845 {
846     kms_show_foreach_card(log, kms_show_available_connectors);
847 }
848 
kms_show_available_cards_connectors_and_modes(struct mp_log * log)849 static void kms_show_available_cards_connectors_and_modes(struct mp_log *log)
850 {
851     kms_show_foreach_card(log, kms_show_available_connectors_and_modes);
852 }
853 
kms_get_display_fps(const struct kms * kms)854 double kms_get_display_fps(const struct kms *kms)
855 {
856     return mode_get_Hz(&kms->mode.mode);
857 }
858 
drm_connector_opt_help(struct mp_log * log,const struct m_option * opt,struct bstr name)859 static int drm_connector_opt_help(struct mp_log *log, const struct m_option *opt,
860                                   struct bstr name)
861 {
862     kms_show_available_cards_and_connectors(log);
863     return M_OPT_EXIT;
864 }
865 
drm_mode_opt_help(struct mp_log * log,const struct m_option * opt,struct bstr name)866 static int drm_mode_opt_help(struct mp_log *log, const struct m_option *opt,
867                              struct bstr name)
868 {
869     kms_show_available_cards_connectors_and_modes(log);
870     return M_OPT_EXIT;
871 }
872 
drm_validate_mode_opt(struct mp_log * log,const struct m_option * opt,struct bstr name,const char ** value)873 static int drm_validate_mode_opt(struct mp_log *log, const struct m_option *opt,
874                                  struct bstr name, const char **value)
875 {
876     const char *param = *value;
877     if (!parse_mode_spec(param, NULL)) {
878         mp_fatal(log, "Invalid value for option drm-mode. Must be a positive number, a string of the format WxH[@R] or 'help'\n");
879         return M_OPT_INVALID;
880     }
881 
882     return 1;
883 }
884 
885 // VT switcher ----------------------------------------------------------------
886 
vt_switcher_sighandler(int sig)887 static void vt_switcher_sighandler(int sig)
888 {
889     unsigned char event = sig == RELEASE_SIGNAL ? EVT_RELEASE : EVT_ACQUIRE;
890     (void)write(vt_switcher_pipe[1], &event, sizeof(event));
891 }
892 
has_signal_installed(int signo)893 static bool has_signal_installed(int signo)
894 {
895     struct sigaction act = { 0 };
896     sigaction(signo, 0, &act);
897     return act.sa_handler != 0;
898 }
899 
install_signal(int signo,void (* handler)(int))900 static int install_signal(int signo, void (*handler)(int))
901 {
902     struct sigaction act = { 0 };
903     act.sa_handler = handler;
904     sigemptyset(&act.sa_mask);
905     act.sa_flags = SA_RESTART;
906     return sigaction(signo, &act, NULL);
907 }
908 
vt_switcher_init(struct vt_switcher * s,struct mp_log * log)909 bool vt_switcher_init(struct vt_switcher *s, struct mp_log *log)
910 {
911     s->log = log;
912     s->tty_fd = -1;
913     vt_switcher_pipe[0] = -1;
914     vt_switcher_pipe[1] = -1;
915 
916     if (mp_make_cloexec_pipe(vt_switcher_pipe)) {
917         MP_ERR(s, "Creating pipe failed: %s\n", mp_strerror(errno));
918         return false;
919     }
920 
921     s->tty_fd = open("/dev/tty", O_RDWR | O_CLOEXEC);
922     if (s->tty_fd < 0) {
923         MP_ERR(s, "Can't open TTY for VT control: %s\n", mp_strerror(errno));
924         return false;
925     }
926 
927     if (has_signal_installed(RELEASE_SIGNAL)) {
928         MP_ERR(s, "Can't handle VT release - signal already used\n");
929         return false;
930     }
931     if (has_signal_installed(ACQUIRE_SIGNAL)) {
932         MP_ERR(s, "Can't handle VT acquire - signal already used\n");
933         return false;
934     }
935 
936     if (install_signal(RELEASE_SIGNAL, vt_switcher_sighandler)) {
937         MP_ERR(s, "Failed to install release signal: %s\n", mp_strerror(errno));
938         return false;
939     }
940     if (install_signal(ACQUIRE_SIGNAL, vt_switcher_sighandler)) {
941         MP_ERR(s, "Failed to install acquire signal: %s\n", mp_strerror(errno));
942         return false;
943     }
944 
945     struct vt_mode vt_mode = { 0 };
946     if (ioctl(s->tty_fd, VT_GETMODE, &vt_mode) < 0) {
947         MP_ERR(s, "VT_GETMODE failed: %s\n", mp_strerror(errno));
948         return false;
949     }
950 
951     vt_mode.mode = VT_PROCESS;
952     vt_mode.relsig = RELEASE_SIGNAL;
953     vt_mode.acqsig = ACQUIRE_SIGNAL;
954     // frsig is a signal for forced release. Not implemented on Linux,
955     // Solaris, BSDs but must be set to a valid signal on some of those.
956     vt_mode.frsig = SIGIO; // unused
957     if (ioctl(s->tty_fd, VT_SETMODE, &vt_mode) < 0) {
958         MP_ERR(s, "VT_SETMODE failed: %s\n", mp_strerror(errno));
959         return false;
960     }
961 
962     // Block the VT switching signals from interrupting the VO thread (they will
963     // still be picked up by other threads, which will fill vt_switcher_pipe for us)
964     sigset_t set;
965     sigemptyset(&set);
966     sigaddset(&set, RELEASE_SIGNAL);
967     sigaddset(&set, ACQUIRE_SIGNAL);
968     pthread_sigmask(SIG_BLOCK, &set, NULL);
969 
970     return true;
971 }
972 
vt_switcher_acquire(struct vt_switcher * s,void (* handler)(void *),void * user_data)973 void vt_switcher_acquire(struct vt_switcher *s,
974                          void (*handler)(void*), void *user_data)
975 {
976     s->handlers[HANDLER_ACQUIRE] = handler;
977     s->handler_data[HANDLER_ACQUIRE] = user_data;
978 }
979 
vt_switcher_release(struct vt_switcher * s,void (* handler)(void *),void * user_data)980 void vt_switcher_release(struct vt_switcher *s,
981                          void (*handler)(void*), void *user_data)
982 {
983     s->handlers[HANDLER_RELEASE] = handler;
984     s->handler_data[HANDLER_RELEASE] = user_data;
985 }
986 
vt_switcher_interrupt_poll(struct vt_switcher * s)987 void vt_switcher_interrupt_poll(struct vt_switcher *s)
988 {
989     unsigned char event = EVT_INTERRUPT;
990     (void)write(vt_switcher_pipe[1], &event, sizeof(event));
991 }
992 
vt_switcher_destroy(struct vt_switcher * s)993 void vt_switcher_destroy(struct vt_switcher *s)
994 {
995     struct vt_mode vt_mode = {0};
996     vt_mode.mode = VT_AUTO;
997     if (ioctl(s->tty_fd, VT_SETMODE, &vt_mode) < 0) {
998         MP_ERR(s, "VT_SETMODE failed: %s\n", mp_strerror(errno));
999         return;
1000     }
1001 
1002     install_signal(RELEASE_SIGNAL, SIG_DFL);
1003     install_signal(ACQUIRE_SIGNAL, SIG_DFL);
1004     close(s->tty_fd);
1005     close(vt_switcher_pipe[0]);
1006     close(vt_switcher_pipe[1]);
1007 }
1008 
vt_switcher_poll(struct vt_switcher * s,int timeout_ms)1009 void vt_switcher_poll(struct vt_switcher *s, int timeout_ms)
1010 {
1011     struct pollfd fds[1] = {
1012         { .events = POLLIN, .fd = vt_switcher_pipe[0] },
1013     };
1014     poll(fds, 1, timeout_ms);
1015     if (!fds[0].revents)
1016         return;
1017 
1018     unsigned char event;
1019     if (read(fds[0].fd, &event, sizeof(event)) != sizeof(event))
1020         return;
1021 
1022     switch (event) {
1023     case EVT_RELEASE:
1024         s->handlers[HANDLER_RELEASE](s->handler_data[HANDLER_RELEASE]);
1025 
1026         if (ioctl(s->tty_fd, VT_RELDISP, 1) < 0) {
1027             MP_ERR(s, "Failed to release virtual terminal\n");
1028         }
1029         break;
1030 
1031     case EVT_ACQUIRE:
1032         s->handlers[HANDLER_ACQUIRE](s->handler_data[HANDLER_ACQUIRE]);
1033 
1034         if (ioctl(s->tty_fd, VT_RELDISP, VT_ACKACQ) < 0) {
1035             MP_ERR(s, "Failed to acquire virtual terminal\n");
1036         }
1037         break;
1038 
1039     case EVT_INTERRUPT:
1040         break;
1041     }
1042 }
1043 
drm_pflip_cb(int fd,unsigned int msc,unsigned int sec,unsigned int usec,void * data)1044 void drm_pflip_cb(int fd, unsigned int msc, unsigned int sec,
1045                   unsigned int usec, void *data)
1046 {
1047     struct drm_pflip_cb_closure *closure = data;
1048 
1049     struct drm_vsync_tuple *vsync = closure->vsync;
1050     // frame_vsync->ust is the timestamp of the pageflip that happened just before this flip was queued
1051     // frame_vsync->msc is the sequence number of the pageflip that happened just before this flip was queued
1052     // frame_vsync->sbc is the sequence number for the frame that was just flipped to screen
1053     struct drm_vsync_tuple *frame_vsync = closure->frame_vsync;
1054     struct vo_vsync_info *vsync_info = closure->vsync_info;
1055 
1056     const bool ready =
1057         (vsync->msc != 0) &&
1058         (frame_vsync->ust != 0) && (frame_vsync->msc != 0);
1059 
1060     const uint64_t ust = (sec * 1000000LL) + usec;
1061 
1062     const unsigned int msc_since_last_flip = msc - vsync->msc;
1063     if (ready && msc == vsync->msc) {
1064         // Seems like some drivers only increment msc every other page flip when
1065         // running in interlaced mode (I'm looking at you nouveau). Obviously we
1066         // can't work with this, so shame the driver and bail.
1067         mp_err(closure->log,
1068                "Got the same msc value twice: (msc: %u, vsync->msc: %u). This shouldn't happen. Possibly broken driver/interlaced mode?\n",
1069                msc, vsync->msc);
1070         goto fail;
1071     }
1072 
1073     vsync->ust = ust;
1074     vsync->msc = msc;
1075 
1076     if (ready) {
1077         // Convert to mp_time
1078         struct timespec ts;
1079         if (clock_gettime(CLOCK_MONOTONIC, &ts))
1080             goto fail;
1081         const uint64_t now_monotonic = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
1082         const uint64_t ust_mp_time = mp_time_us() - (now_monotonic - vsync->ust);
1083 
1084         const uint64_t     ust_since_enqueue = vsync->ust - frame_vsync->ust;
1085         const unsigned int msc_since_enqueue = vsync->msc - frame_vsync->msc;
1086         const unsigned int sbc_since_enqueue = vsync->sbc - frame_vsync->sbc;
1087 
1088         vsync_info->vsync_duration = ust_since_enqueue / msc_since_enqueue;
1089         vsync_info->skipped_vsyncs = msc_since_last_flip - 1; // Valid iff swap_buffers is called every vsync
1090         vsync_info->last_queue_display_time = ust_mp_time + (sbc_since_enqueue * vsync_info->vsync_duration);
1091     }
1092 
1093 fail:
1094     *closure->waiting_for_flip = false;
1095     talloc_free(closure);
1096 }
1097