chiark / gitweb /
build-sys: unbundle unifont
[elogind.git] / src / libsystemd-terminal / grdev-drm.c
index f01df1dae269102da0965fac2eef3285b6b3dbb9..bc4d4c9e76d4d769108cd85321c576536ad0cb16 100644 (file)
@@ -468,9 +468,11 @@ static int grdrm_plane_resync(grdrm_plane *plane) {
                         if (r == -ENOENT) {
                                 card->async_hotplug = true;
                                 r = 0;
-                                log_debug("grdrm: %s: plane %u removed during resync", card->base.name, plane->object.id);
+                                log_debug("grdrm: %s: plane %u removed during resync",
+                                          card->base.name, plane->object.id);
                         } else {
-                                log_debug("grdrm: %s: cannot retrieve plane %u: %m", card->base.name, plane->object.id);
+                                log_debug_errno(errno, "grdrm: %s: cannot retrieve plane %u: %m",
+                                                card->base.name, plane->object.id);
                         }
 
                         return r;
@@ -625,9 +627,11 @@ static int grdrm_connector_resync(grdrm_connector *connector) {
                         if (r == -ENOENT) {
                                 card->async_hotplug = true;
                                 r = 0;
-                                log_debug("grdrm: %s: connector %u removed during resync", card->base.name, connector->object.id);
+                                log_debug("grdrm: %s: connector %u removed during resync",
+                                          card->base.name, connector->object.id);
                         } else {
-                                log_debug("grdrm: %s: cannot retrieve connector %u: %m", card->base.name, connector->object.id);
+                                log_debug_errno(errno, "grdrm: %s: cannot retrieve connector %u: %m",
+                                                card->base.name, connector->object.id);
                         }
 
                         return r;
@@ -783,9 +787,11 @@ static int grdrm_encoder_resync(grdrm_encoder *encoder) {
                 if (r == -ENOENT) {
                         card->async_hotplug = true;
                         r = 0;
-                        log_debug("grdrm: %s: encoder %u removed during resync", card->base.name, encoder->object.id);
+                        log_debug("grdrm: %s: encoder %u removed during resync",
+                                  card->base.name, encoder->object.id);
                 } else {
-                        log_debug("grdrm: %s: cannot retrieve encoder %u: %m", card->base.name, encoder->object.id);
+                        log_debug_errno(errno, "grdrm: %s: cannot retrieve encoder %u: %m",
+                                        card->base.name, encoder->object.id);
                 }
 
                 return r;
@@ -916,9 +922,11 @@ static int grdrm_crtc_resync(grdrm_crtc *crtc) {
                 if (r == -ENOENT) {
                         card->async_hotplug = true;
                         r = 0;
-                        log_debug("grdrm: %s: crtc %u removed during resync", card->base.name, crtc->object.id);
+                        log_debug("grdrm: %s: crtc %u removed during resync",
+                                  card->base.name, crtc->object.id);
                 } else {
-                        log_debug("grdrm: %s: cannot retrieve crtc %u: %m", card->base.name, crtc->object.id);
+                        log_debug_errno(errno, "grdrm: %s: cannot retrieve crtc %u: %m",
+                                        card->base.name, crtc->object.id);
                 }
 
                 return r;
@@ -1119,8 +1127,8 @@ static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb *basefb) {
         r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
         if (r < 0) {
                 r = -errno;
-                log_debug("grdrm: %s: cannot set crtc %" PRIu32 ": %m",
-                          card->base.name, crtc->object.id);
+                log_debug_errno(errno, "grdrm: %s: cannot set crtc %" PRIu32 ": %m",
+                                card->base.name, crtc->object.id);
 
                 grdrm_card_async(card, r);
                 return;
@@ -1158,8 +1166,21 @@ static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb *basefb) {
         assert(basefb);
         assert(pipe);
 
-        if (!crtc->applied && !grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
+        if (!crtc->applied) {
+                if (!grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
+                        return 0;
+
+                /* TODO: Theoretically, we should be able to page-flip to our
+                 * framebuffer here. We didn't perform any deep modeset, but the
+                 * DRM driver is really supposed to reject our page-flip in case
+                 * the FB is not compatible. We then properly fall back to a
+                 * deep modeset.
+                 * As it turns out, drivers don't to this. Therefore, we need to
+                 * perform a full modeset on enter now. We might avoid this in
+                 * the future with fixed drivers.. */
+
                 return 0;
+        }
 
         fb = fb_from_base(basefb);
 
@@ -1175,8 +1196,8 @@ static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb *basefb) {
                  * possible to see whether cards support page-flipping, so
                  * avoid logging on each frame. */
                 if (r != -EINVAL)
-                        log_debug("grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
-                                  card->base.name, crtc->object.id);
+                        log_debug_errno(errno, "grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
+                                        card->base.name, crtc->object.id);
 
                 if (grdrm_card_async(card, r))
                         return r;
@@ -1228,8 +1249,8 @@ static void grdrm_crtc_commit(grdrm_crtc *crtc) {
                         r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
                         if (r < 0) {
                                 r = -errno;
-                                log_debug("grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
-                                          card->base.name, crtc->object.id);
+                                log_debug_errno(errno, "grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
+                                                card->base.name, crtc->object.id);
 
                                 grdrm_card_async(card, r);
                                 return;
@@ -1285,8 +1306,8 @@ static void grdrm_crtc_restore(grdrm_crtc *crtc) {
         r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
         if (r < 0) {
                 r = -errno;
-                log_debug("grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
-                          card->base.name, crtc->object.id);
+                log_debug_errno(errno, "grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
+                                card->base.name, crtc->object.id);
 
                 grdrm_card_async(card, r);
                 return;
@@ -1380,9 +1401,9 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_
 
         r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
         if (r < 0) {
-                r = -errno;
-                log_debug("grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
-                          card->base.name, fb->base.width, fb->base.height);
+                r = negative_errno();
+                log_debug_errno(errno, "grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
+                                card->base.name, fb->base.width, fb->base.height);
                 return r;
         }
 
@@ -1394,17 +1415,17 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_
 
         r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
         if (r < 0) {
-                r = -errno;
-                log_debug("grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
-                          card->base.name, fb->base.width, fb->base.height);
+                r = negative_errno();
+                log_debug_errno(errno, "grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
+                                card->base.name, fb->base.width, fb->base.height);
                 return r;
         }
 
         fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
         if (fb->base.maps[0] == MAP_FAILED) {
-                r = -errno;
-                log_debug("grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
-                          card->base.name, fb->base.width, fb->base.height);
+                r = negative_errno();
+                log_debug_errno(errno, "grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
+                                card->base.name, fb->base.width, fb->base.height);
                 return r;
         }
 
@@ -1420,9 +1441,9 @@ static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_
 
         r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
         if (r < 0) {
-                r = -errno;
-                log_debug("grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
-                          card->base.name, fb->base.width, fb->base.height);
+                r = negative_errno();
+                log_debug_errno(errno, "grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
+                                card->base.name, fb->base.width, fb->base.height);
                 return r;
         }
 
@@ -1448,8 +1469,8 @@ grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
         if (fb->id > 0 && fb->card->fd >= 0) {
                 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
                 if (r < 0)
-                        log_debug("grdrm: %s: cannot delete framebuffer %" PRIu32 ": %m",
-                                  fb->card->base.name, fb->id);
+                        log_debug_errno(errno, "grdrm: %s: cannot delete framebuffer %" PRIu32 ": %m",
+                                        fb->card->base.name, fb->id);
         }
 
         for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
@@ -1462,8 +1483,8 @@ grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
                         destroy_dumb.handle = fb->handles[i];
                         r = ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
                         if (r < 0)
-                                log_debug("grdrm: %s: cannot destroy dumb-buffer %" PRIu32 ": %m",
-                                          fb->card->base.name, fb->handles[i]);
+                                log_debug_errno(errno, "grdrm: %s: cannot destroy dumb-buffer %" PRIu32 ": %m",
+                                                fb->card->base.name, fb->handles[i]);
                 }
         }
 
@@ -1549,9 +1570,23 @@ static grdev_fb *grdrm_pipe_target(grdev_pipe *basepipe) {
         return basepipe->back;
 }
 
+static void grdrm_pipe_enable(grdev_pipe *basepipe) {
+        grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
+
+        pipe->crtc->applied = false;
+}
+
+static void grdrm_pipe_disable(grdev_pipe *basepipe) {
+        grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
+
+        pipe->crtc->applied = false;
+}
+
 static const grdev_pipe_vtable grdrm_pipe_vtable = {
         .free                   = grdrm_pipe_free,
         .target                 = grdrm_pipe_target,
+        .enable                 = grdrm_pipe_enable,
+        .disable                = grdrm_pipe_disable,
 };
 
 /*
@@ -1750,7 +1785,8 @@ static int grdrm_card_resync(grdrm_card *card) {
                 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
                 if (r < 0) {
                         r = -errno;
-                        log_debug("grdrm: %s: cannot retrieve drm resources: %m", card->base.name);
+                        log_debug_errno(errno, "grdrm: %s: cannot retrieve drm resources: %m",
+                                        card->base.name);
                         return r;
                 }
 
@@ -1761,7 +1797,8 @@ static int grdrm_card_resync(grdrm_card *card) {
                 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
                 if (r < 0) {
                         r = -errno;
-                        log_debug("grdrm: %s: cannot retrieve drm plane-resources: %m", card->base.name);
+                        log_debug_errno(errno, "grdrm: %s: cannot retrieve drm plane-resources: %m",
+                                        card->base.name);
                         return r;
                 }
 
@@ -1772,7 +1809,8 @@ static int grdrm_card_resync(grdrm_card *card) {
 
                         n = ALIGN_POWER2(max);
                         if (!n || n > UINT16_MAX) {
-                                log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32, card->base.name, max);
+                                log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32,
+                                          card->base.name, max);
                                 return -ERANGE;
                         }
 
@@ -2022,7 +2060,7 @@ static void grdrm_card_configure(grdrm_card *card) {
          *     headache to configure on dynamic demands. Therefore, we only
          *     support it if configured statically beforehand.
          *
-         *   * CRTCs are not created equal. Some might be much more poweful
+         *   * CRTCs are not created equal. Some might be much more powerful
          *     than others, including more advanced plane support. So far, our
          *     CRTC selection is random. You need to supply static
          *     configuration if you want special setups. So far, there is no
@@ -2159,8 +2197,8 @@ static void grdrm_card_hotplug(grdrm_card *card) {
         card->ready = false;
         r = grdrm_card_resync(card);
         if (r < 0) {
-                log_debug("grdrm: %s/%s: cannot re-sync card: %s",
-                          card->base.session->name, card->base.name, strerror(-r));
+                log_debug_errno(r, "grdrm: %s/%s: cannot re-sync card: %m",
+                                card->base.session->name, card->base.name);
                 return;
         }
 
@@ -2201,7 +2239,8 @@ static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *
                         if (errno == EAGAIN || errno == EINTR)
                                 return 0;
 
-                        log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
+                        log_debug_errno(errno, "grdrm: %s/%s: read error: %m",
+                                        card->base.session->name, card->base.name);
                         grdrm_card_close(card);
                         return 0;
                 }
@@ -2210,7 +2249,8 @@ static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *
                         event = (void*)buf;
 
                         if (len < sizeof(*event) || len < event->length) {
-                                log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
+                                log_debug("grdrm: %s/%s: truncated event",
+                                          card->base.session->name, card->base.name);
                                 break;
                         }
 
@@ -2218,7 +2258,8 @@ static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *
                         case DRM_EVENT_FLIP_COMPLETE:
                                 vblank = (void*)event;
                                 if (event->length < sizeof(*vblank)) {
-                                        log_debug("grdrm: %s/%s: truncated vblank event", card->base.session->name, card->base.name);
+                                        log_debug("grdrm: %s/%s: truncated vblank event",
+                                                  card->base.session->name, card->base.name);
                                         break;
                                 }
 
@@ -2388,8 +2429,8 @@ static int grdrm_card_open(grdrm_card *card, int dev_fd) {
         r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
         card->cap_dumb = r >= 0 && cap.value;
         if (r < 0)
-                log_debug("grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %s",
-                          card->base.session->name, card->base.name, strerror(-r));
+                log_debug_errno(r, "grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %m",
+                                card->base.session->name, card->base.name);
         else if (!card->cap_dumb)
                 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
                           card->base.session->name, card->base.name);
@@ -2400,8 +2441,8 @@ static int grdrm_card_open(grdrm_card *card, int dev_fd) {
         r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
         card->cap_monotonic = r >= 0 && cap.value;
         if (r < 0)
-                log_debug("grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %s",
-                          card->base.session->name, card->base.name, strerror(-r));
+                log_debug_errno(r, "grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %m",
+                                card->base.session->name, card->base.name);
         else if (!card->cap_monotonic)
                 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
                           card->base.session->name, card->base.name);
@@ -2471,8 +2512,8 @@ static void unmanaged_card_enable(grdev_card *basecard) {
                 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
                 if (fd < 0) {
                         /* not fatal; simply ignore the device */
-                        log_debug("grdrm: %s/%s: cannot open node %s: %m",
-                                  basecard->session->name, basecard->name, cu->devnode);
+                        log_debug_errno(errno, "grdrm: %s/%s: cannot open node %s: %m",
+                                        basecard->session->name, basecard->name, cu->devnode);
                         return;
                 }
 
@@ -2480,16 +2521,16 @@ static void unmanaged_card_enable(grdev_card *basecard) {
 
                 r = grdrm_card_open(&cu->card, fd);
                 if (r < 0) {
-                        log_debug("grdrm: %s/%s: cannot open: %s",
-                                  basecard->session->name, basecard->name, strerror(-r));
+                        log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
+                                        basecard->session->name, basecard->name);
                         return;
                 }
         }
 
         r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
         if (r < 0) {
-                log_debug("grdrm: %s/%s: cannot acquire DRM-Master: %m",
-                          basecard->session->name, basecard->name);
+                log_debug_errno(errno, "grdrm: %s/%s: cannot acquire DRM-Master: %m",
+                                basecard->session->name, basecard->name);
                 return;
         }
 
@@ -2539,8 +2580,8 @@ static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct u
         fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
         if (fd < 0) {
                 /* not fatal; allow uaccess based control on activation */
-                log_debug("grdrm: %s/%s: cannot open node %s: %m",
-                          basecard->session->name, basecard->name, cu->devnode);
+                log_debug_errno(errno, "grdrm: %s/%s: cannot open node %s: %m",
+                                basecard->session->name, basecard->name, cu->devnode);
         } else {
                 /* We might get DRM-Master implicitly on open(); drop it immediately
                  * so we acquire it only once we're actually enabled. We don't
@@ -2548,13 +2589,13 @@ static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct u
                  * weird errors, anyway. */
                 r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
                 if (r < 0 && errno != EACCES && errno != EINVAL)
-                        log_debug("grdrm: %s/%s: cannot drop DRM-Master: %m",
-                                  basecard->session->name, basecard->name);
+                        log_debug_errno(errno, "grdrm: %s/%s: cannot drop DRM-Master: %m",
+                                        basecard->session->name, basecard->name);
 
                 r = grdrm_card_open(&cu->card, fd);
                 if (r < 0)
-                        log_debug("grdrm: %s/%s: cannot open: %s",
-                                  basecard->session->name, basecard->name, strerror(-r));
+                        log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
+                                        basecard->session->name, basecard->name);
         }
 
         if (out)
@@ -2697,8 +2738,8 @@ static int managed_card_pause_device_fn(sd_bus *bus,
                 }
 
                 if (r < 0)
-                        log_debug("grdrm: %s/%s: cannot send PauseDeviceComplete: %s",
-                                  session->name, cm->card.base.name, strerror(-r));
+                        log_debug_errno(r, "grdrm: %s/%s: cannot send PauseDeviceComplete: %m",
+                                        session->name, cm->card.base.name);
         }
 
         return 0;
@@ -2744,15 +2785,15 @@ static int managed_card_resume_device_fn(sd_bus *bus,
                  * and our code works fine this way. */
                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
                 if (fd < 0) {
-                        log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
-                                  session->name, cm->card.base.name);
+                        log_debug_errno(errno, "grdrm: %s/%s: cannot duplicate fd: %m",
+                                        session->name, cm->card.base.name);
                         return 0;
                 }
 
                 r = grdrm_card_open(&cm->card, fd);
                 if (r < 0) {
-                        log_debug("grdrm: %s/%s: cannot open: %s",
-                                  session->name, cm->card.base.name, strerror(-r));
+                        log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
+                                        session->name, cm->card.base.name);
                         return 0;
                 }
         }
@@ -2836,15 +2877,15 @@ static int managed_card_take_device_fn(sd_bus *bus,
 
         fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
         if (fd < 0) {
-                log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
-                          session->name, cm->card.base.name);
+                log_debug_errno(errno, "grdrm: %s/%s: cannot duplicate fd: %m",
+                                session->name, cm->card.base.name);
                 return 0;
         }
 
         r = grdrm_card_open(&cm->card, fd);
         if (r < 0) {
-                log_debug("grdrm: %s/%s: cannot open: %s",
-                          session->name, cm->card.base.name, strerror(-r));
+                log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
+                                session->name, cm->card.base.name);
                 return 0;
         }
 
@@ -2885,8 +2926,8 @@ static void managed_card_take_device(managed_card *cm) {
         return;
 
 error:
-        log_debug("grdrm: %s/%s: cannot send TakeDevice request: %s",
-                  session->name, cm->card.base.name, strerror(-r));
+        log_debug_errno(r, "grdrm: %s/%s: cannot send TakeDevice request: %m",
+                        session->name, cm->card.base.name);
 }
 
 static void managed_card_release_device(managed_card *cm) {
@@ -2928,8 +2969,8 @@ static void managed_card_release_device(managed_card *cm) {
         }
 
         if (r < 0 && r != -ENOTCONN)
-                log_debug("grdrm: %s/%s: cannot send ReleaseDevice: %s",
-                          session->name, cm->card.base.name, strerror(-r));
+                log_debug_errno(r, "grdrm: %s/%s: cannot send ReleaseDevice: %m",
+                                session->name, cm->card.base.name);
 }
 
 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {