aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Simon Ser <contact@emersion.fr>2021-06-07 18:58:20 +0200
committerLibravatar Simon Zeni <simon@bl4ckb0ne.ca>2021-12-13 09:59:33 -0600
commit4732325f591455f1e4bdcb35652505a8a636663a (patch)
treec69c8a5b42add24208a1b81b4cfda93459be026c
parentview: Fix null dereference (diff)
downloadsway-4732325f591455f1e4bdcb35652505a8a636663a.tar.gz
sway-4732325f591455f1e4bdcb35652505a8a636663a.tar.zst
sway-4732325f591455f1e4bdcb35652505a8a636663a.zip
Add support for linux-dmabuf surface hints
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/1376
-rw-r--r--include/sway/server.h2
-rw-r--r--protocols/meson.build1
-rw-r--r--sway/server.c10
-rw-r--r--sway/tree/container.c83
4 files changed, 95 insertions, 1 deletions
diff --git a/include/sway/server.h b/include/sway/server.h
index 7ac2af26..0bd860b2 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -41,6 +41,8 @@ struct sway_server {
41 struct wlr_compositor *compositor; 41 struct wlr_compositor *compositor;
42 struct wl_listener compositor_new_surface; 42 struct wl_listener compositor_new_surface;
43 43
44 struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1;
45
44 struct wlr_data_device_manager *data_device_manager; 46 struct wlr_data_device_manager *data_device_manager;
45 47
46 struct sway_input_manager *input; 48 struct sway_input_manager *input;
diff --git a/protocols/meson.build b/protocols/meson.build
index 8e9e65be..df24a4e5 100644
--- a/protocols/meson.build
+++ b/protocols/meson.build
@@ -15,6 +15,7 @@ protocols = [
15 [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], 15 [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
16 [wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'], 16 [wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
17 [wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml'], 17 [wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml'],
18 [wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
18 ['wlr-layer-shell-unstable-v1.xml'], 19 ['wlr-layer-shell-unstable-v1.xml'],
19 ['idle.xml'], 20 ['idle.xml'],
20 ['wlr-input-inhibitor-unstable-v1.xml'], 21 ['wlr-input-inhibitor-unstable-v1.xml'],
diff --git a/sway/server.c b/sway/server.c
index 582a04ab..f50a0987 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -13,10 +13,12 @@
13#include <wlr/types/wlr_compositor.h> 13#include <wlr/types/wlr_compositor.h>
14#include <wlr/types/wlr_data_control_v1.h> 14#include <wlr/types/wlr_data_control_v1.h>
15#include <wlr/types/wlr_drm_lease_v1.h> 15#include <wlr/types/wlr_drm_lease_v1.h>
16#include <wlr/types/wlr_drm.h>
16#include <wlr/types/wlr_export_dmabuf_v1.h> 17#include <wlr/types/wlr_export_dmabuf_v1.h>
17#include <wlr/types/wlr_gamma_control_v1.h> 18#include <wlr/types/wlr_gamma_control_v1.h>
18#include <wlr/types/wlr_idle.h> 19#include <wlr/types/wlr_idle.h>
19#include <wlr/types/wlr_layer_shell_v1.h> 20#include <wlr/types/wlr_layer_shell_v1.h>
21#include <wlr/types/wlr_linux_dmabuf_v1.h>
20#include <wlr/types/wlr_pointer_constraints_v1.h> 22#include <wlr/types/wlr_pointer_constraints_v1.h>
21#include <wlr/types/wlr_primary_selection_v1.h> 23#include <wlr/types/wlr_primary_selection_v1.h>
22#include <wlr/types/wlr_relative_pointer_v1.h> 24#include <wlr/types/wlr_relative_pointer_v1.h>
@@ -78,7 +80,13 @@ bool server_init(struct sway_server *server) {
78 return false; 80 return false;
79 } 81 }
80 82
81 wlr_renderer_init_wl_display(server->renderer, server->wl_display); 83 wlr_renderer_init_wl_shm(server->renderer, server->wl_display);
84
85 if (wlr_renderer_get_dmabuf_texture_formats(server->renderer) != NULL) {
86 wlr_drm_create(server->wl_display, server->renderer);
87 server->linux_dmabuf_v1 =
88 wlr_linux_dmabuf_v1_create(server->wl_display, server->renderer);
89 }
82 90
83 server->allocator = wlr_allocator_autocreate(server->backend, 91 server->allocator = wlr_allocator_autocreate(server->backend,
84 server->renderer); 92 server->renderer);
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 0284c9a5..132b6819 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -5,8 +5,12 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <string.h> 6#include <string.h>
7#include <strings.h> 7#include <strings.h>
8#include <sys/stat.h>
8#include <wayland-server-core.h> 9#include <wayland-server-core.h>
10#include <wlr/types/wlr_linux_dmabuf_v1.h>
9#include <wlr/types/wlr_output_layout.h> 11#include <wlr/types/wlr_output_layout.h>
12#include <wlr/render/drm_format_set.h>
13#include "linux-dmabuf-unstable-v1-protocol.h"
10#include "cairo_util.h" 14#include "cairo_util.h"
11#include "pango.h" 15#include "pango.h"
12#include "sway/config.h" 16#include "sway/config.h"
@@ -1051,6 +1055,16 @@ void container_end_mouse_operation(struct sway_container *container) {
1051 } 1055 }
1052} 1056}
1053 1057
1058static bool devid_from_fd(int fd, dev_t *devid) {
1059 struct stat stat;
1060 if (fstat(fd, &stat) != 0) {
1061 sway_log_errno(SWAY_ERROR, "fstat failed");
1062 return false;
1063 }
1064 *devid = stat.st_rdev;
1065 return true;
1066}
1067
1054static void set_fullscreen(struct sway_container *con, bool enable) { 1068static void set_fullscreen(struct sway_container *con, bool enable) {
1055 if (!con->view) { 1069 if (!con->view) {
1056 return; 1070 return;
@@ -1062,6 +1076,75 @@ static void set_fullscreen(struct sway_container *con, bool enable) {
1062 con->view->foreign_toplevel, enable); 1076 con->view->foreign_toplevel, enable);
1063 } 1077 }
1064 } 1078 }
1079
1080 if (!server.linux_dmabuf_v1 || !con->view->surface) {
1081 return;
1082 }
1083 if (!enable) {
1084 wlr_linux_dmabuf_v1_set_surface_feedback(server.linux_dmabuf_v1,
1085 con->view->surface, NULL);
1086 return;
1087 }
1088
1089 if (!con->pending.workspace || !con->pending.workspace->output) {
1090 return;
1091 }
1092
1093 struct sway_output *output = con->pending.workspace->output;
1094 struct wlr_output *wlr_output = output->wlr_output;
1095
1096 // TODO: add wlroots helpers for all of this stuff
1097
1098 const struct wlr_drm_format_set *renderer_formats =
1099 wlr_renderer_get_dmabuf_texture_formats(server.renderer);
1100 assert(renderer_formats);
1101
1102 int renderer_drm_fd = wlr_renderer_get_drm_fd(server.renderer);
1103 int backend_drm_fd = wlr_backend_get_drm_fd(wlr_output->backend);
1104 if (renderer_drm_fd < 0 || backend_drm_fd < 0) {
1105 return;
1106 }
1107
1108 dev_t render_dev, scanout_dev;
1109 if (!devid_from_fd(renderer_drm_fd, &render_dev) ||
1110 !devid_from_fd(backend_drm_fd, &scanout_dev)) {
1111 return;
1112 }
1113
1114 const struct wlr_drm_format_set *output_formats =
1115 wlr_output_get_primary_formats(output->wlr_output,
1116 WLR_BUFFER_CAP_DMABUF);
1117 if (!output_formats) {
1118 return;
1119 }
1120
1121 struct wlr_drm_format_set scanout_formats = {0};
1122 if (!wlr_drm_format_set_intersect(&scanout_formats,
1123 output_formats, renderer_formats)) {
1124 return;
1125 }
1126
1127 struct wlr_linux_dmabuf_feedback_v1_tranche tranches[] = {
1128 {
1129 .target_device = scanout_dev,
1130 .flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT,
1131 .formats = &scanout_formats,
1132 },
1133 {
1134 .target_device = render_dev,
1135 .formats = renderer_formats,
1136 },
1137 };
1138
1139 const struct wlr_linux_dmabuf_feedback_v1 feedback = {
1140 .main_device = render_dev,
1141 .tranches = tranches,
1142 .tranches_len = sizeof(tranches) / sizeof(tranches[0]),
1143 };
1144 wlr_linux_dmabuf_v1_set_surface_feedback(server.linux_dmabuf_v1,
1145 con->view->surface, &feedback);
1146
1147 wlr_drm_format_set_finish(&scanout_formats);
1065} 1148}
1066 1149
1067static void container_fullscreen_workspace(struct sway_container *con) { 1150static void container_fullscreen_workspace(struct sway_container *con) {