egl: Update to Wayland 1.2 server API
[mesa.git] / src / gallium / state_trackers / egl / common / native_wayland_drm_bufmgr.c
1 #include <stdint.h>
2 #include <string.h>
3
4 #include "native.h"
5 #include "util/u_inlines.h"
6 #include "state_tracker/drm_driver.h"
7
8 #ifdef HAVE_WAYLAND_BACKEND
9
10 #include <wayland-server.h>
11 #include <wayland-drm-server-protocol.h>
12
13 #include "native_wayland_drm_bufmgr.h"
14
15 #include "wayland-drm.h"
16
17 struct wayland_drm_bufmgr {
18 struct native_display_wayland_bufmgr base;
19
20 struct wl_drm *wl_server_drm;
21 char *device_name;
22
23 void *user_data;
24
25 wayland_drm_bufmgr_authenticate_func authenticate;
26 };
27
28 static INLINE struct wayland_drm_bufmgr *
29 wayland_drm_bufmgr(const struct native_display_wayland_bufmgr *base)
30 {
31 return (struct wayland_drm_bufmgr *) base;
32 }
33
34 static int
35 wayland_drm_bufmgr_authenticate(void *user_data, uint32_t magic)
36 {
37 struct native_display *ndpy = user_data;
38 struct wayland_drm_bufmgr *bufmgr;
39
40 bufmgr = wayland_drm_bufmgr(ndpy->wayland_bufmgr);
41
42 return bufmgr->authenticate(user_data, magic);
43 }
44
45 static void
46 wayland_drm_bufmgr_reference_buffer(void *user_data, uint32_t name, int fd,
47 struct wl_drm_buffer *buffer)
48 {
49 struct native_display *ndpy = user_data;
50 struct pipe_resource templ;
51 struct winsys_handle wsh;
52 enum pipe_format pf;
53
54 switch (buffer->format) {
55 case WL_DRM_FORMAT_ARGB8888:
56 pf = PIPE_FORMAT_B8G8R8A8_UNORM;
57 break;
58 case WL_DRM_FORMAT_XRGB8888:
59 pf = PIPE_FORMAT_B8G8R8X8_UNORM;
60 break;
61 default:
62 pf = PIPE_FORMAT_NONE;
63 break;
64 }
65
66 if (pf == PIPE_FORMAT_NONE)
67 return;
68
69 memset(&templ, 0, sizeof(templ));
70 templ.target = PIPE_TEXTURE_2D;
71 templ.format = pf;
72 templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
73 templ.width0 = buffer->width;
74 templ.height0 = buffer->height;
75 templ.depth0 = 1;
76 templ.array_size = 1;
77
78 memset(&wsh, 0, sizeof(wsh));
79 wsh.handle = name;
80 wsh.stride = buffer->stride[0];
81
82 buffer->driver_buffer =
83 ndpy->screen->resource_from_handle(ndpy->screen, &templ, &wsh);
84 }
85
86 static void
87 wayland_drm_bufmgr_unreference_buffer(void *user_data,
88 struct wl_drm_buffer *buffer)
89 {
90 struct pipe_resource *resource = buffer->driver_buffer;
91
92 pipe_resource_reference(&resource, NULL);
93 }
94
95 static struct wayland_drm_callbacks wl_drm_callbacks = {
96 wayland_drm_bufmgr_authenticate,
97 wayland_drm_bufmgr_reference_buffer,
98 wayland_drm_bufmgr_unreference_buffer
99 };
100
101 static boolean
102 wayland_drm_bufmgr_bind_display(struct native_display *ndpy,
103 struct wl_display *wl_dpy)
104 {
105 struct wayland_drm_bufmgr *bufmgr;
106
107 bufmgr = wayland_drm_bufmgr(ndpy->wayland_bufmgr);
108
109 if (bufmgr->wl_server_drm)
110 return FALSE;
111
112 bufmgr->wl_server_drm = wayland_drm_init(wl_dpy, bufmgr->device_name,
113 &wl_drm_callbacks, ndpy, 0);
114
115 if (!bufmgr->wl_server_drm)
116 return FALSE;
117
118 return TRUE;
119 }
120
121 static boolean
122 wayland_drm_bufmgr_unbind_display(struct native_display *ndpy,
123 struct wl_display *wl_dpy)
124 {
125 struct wayland_drm_bufmgr *bufmgr;
126
127 bufmgr = wayland_drm_bufmgr(ndpy->wayland_bufmgr);
128
129 if (!bufmgr->wl_server_drm)
130 return FALSE;
131
132 wayland_drm_uninit(bufmgr->wl_server_drm);
133 bufmgr->wl_server_drm = NULL;
134
135 return TRUE;
136 }
137
138 static struct pipe_resource *
139 wayland_drm_bufmgr_wl_buffer_get_resource(struct native_display *ndpy,
140 struct wl_resource *buffer_resource)
141 {
142 struct wl_drm_buffer *buffer = wayland_drm_buffer_get(buffer_resource);
143
144 if (!buffer)
145 return NULL;
146
147 return wayland_drm_buffer_get_buffer(buffer);
148 }
149
150 static EGLBoolean
151 wayland_drm_bufmgr_query_buffer(struct native_display *ndpy,
152 struct wl_resource *buffer_resource,
153 EGLint attribute, EGLint *value)
154 {
155 struct wl_drm_buffer *buffer = wayland_drm_buffer_get(buffer_resource);
156 struct pipe_resource *resource;
157
158 if (!buffer)
159 return EGL_FALSE;
160
161 resource = buffer->driver_buffer;
162
163 switch (attribute) {
164 case EGL_TEXTURE_FORMAT:
165 switch (resource->format) {
166 case PIPE_FORMAT_B8G8R8A8_UNORM:
167 *value = EGL_TEXTURE_RGBA;
168 return EGL_TRUE;
169 case PIPE_FORMAT_B8G8R8X8_UNORM:
170 *value = EGL_TEXTURE_RGB;
171 return EGL_TRUE;
172 default:
173 return EGL_FALSE;
174 }
175 case EGL_WIDTH:
176 *value = buffer->width;
177 return EGL_TRUE;
178 case EGL_HEIGHT:
179 *value = buffer->height;
180 return EGL_TRUE;
181 default:
182 return EGL_FALSE;
183 }
184 }
185
186
187 struct native_display_wayland_bufmgr *
188 wayland_drm_bufmgr_create(wayland_drm_bufmgr_authenticate_func authenticate,
189 void *user_data, char *device_name)
190 {
191 struct wayland_drm_bufmgr *bufmgr;
192
193 bufmgr = calloc(1, sizeof *bufmgr);
194 if (!bufmgr)
195 return NULL;
196
197 bufmgr->user_data = user_data;
198 bufmgr->authenticate = authenticate;
199 bufmgr->device_name = strdup(device_name);
200
201 bufmgr->base.bind_display = wayland_drm_bufmgr_bind_display;
202 bufmgr->base.unbind_display = wayland_drm_bufmgr_unbind_display;
203 bufmgr->base.buffer_get_resource = wayland_drm_bufmgr_wl_buffer_get_resource;
204 bufmgr->base.query_buffer = wayland_drm_bufmgr_query_buffer;
205
206 return &bufmgr->base;
207 }
208
209 void
210 wayland_drm_bufmgr_destroy(struct native_display_wayland_bufmgr *_bufmgr)
211 {
212 struct wayland_drm_bufmgr *bufmgr = wayland_drm_bufmgr(_bufmgr);
213
214 if (!bufmgr)
215 return;
216
217 free(bufmgr->device_name);
218 free(bufmgr);
219 }
220
221 #endif