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_helper.h"
14 
15 void
egl_g3d_wl_drm_helper_reference_buffer(void * user_data,uint32_t name,struct wl_drm_buffer * buffer)16 egl_g3d_wl_drm_helper_reference_buffer(void *user_data, uint32_t name,
17                                        struct wl_drm_buffer *buffer)
18 {
19    struct native_display *ndpy = user_data;
20    struct pipe_resource templ;
21    struct winsys_handle wsh;
22    enum pipe_format pf;
23 
24    switch (buffer->format) {
25    case WL_DRM_FORMAT_ARGB8888:
26       pf = PIPE_FORMAT_B8G8R8A8_UNORM;
27       break;
28    case WL_DRM_FORMAT_XRGB8888:
29       pf = PIPE_FORMAT_B8G8R8X8_UNORM;
30       break;
31    default:
32       pf = PIPE_FORMAT_NONE;
33       break;
34    }
35 
36    if (pf == PIPE_FORMAT_NONE)
37       return;
38 
39    memset(&templ, 0, sizeof(templ));
40    templ.target = PIPE_TEXTURE_2D;
41    templ.format = pf;
42    templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
43    templ.width0 = buffer->buffer.width;
44    templ.height0 = buffer->buffer.height;
45    templ.depth0 = 1;
46    templ.array_size = 1;
47 
48    memset(&wsh, 0, sizeof(wsh));
49    wsh.handle = name;
50    wsh.stride = buffer->stride[0];
51 
52    buffer->driver_buffer =
53       ndpy->screen->resource_from_handle(ndpy->screen, &templ, &wsh);
54 }
55 
56 void
egl_g3d_wl_drm_helper_unreference_buffer(void * user_data,struct wl_drm_buffer * buffer)57 egl_g3d_wl_drm_helper_unreference_buffer(void *user_data,
58                                          struct wl_drm_buffer *buffer)
59 {
60    struct pipe_resource *resource = buffer->driver_buffer;
61 
62    pipe_resource_reference(&resource, NULL);
63 }
64 
65 struct pipe_resource *
egl_g3d_wl_drm_common_wl_buffer_get_resource(struct native_display * ndpy,struct wl_buffer * buffer)66 egl_g3d_wl_drm_common_wl_buffer_get_resource(struct native_display *ndpy,
67                                              struct wl_buffer *buffer)
68 {
69    return wayland_drm_buffer_get_buffer(buffer);
70 }
71 
72 EGLBoolean
egl_g3d_wl_drm_common_query_buffer(struct native_display * ndpy,struct wl_buffer * _buffer,EGLint attribute,EGLint * value)73 egl_g3d_wl_drm_common_query_buffer(struct native_display *ndpy,
74                                    struct wl_buffer *_buffer,
75                                    EGLint attribute, EGLint *value)
76 {
77    struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer;
78    struct pipe_resource *resource = buffer->driver_buffer;
79 
80    if (!wayland_buffer_is_drm(&buffer->buffer))
81       return EGL_FALSE;
82 
83    switch (attribute) {
84    case EGL_TEXTURE_FORMAT:
85       switch (resource->format) {
86       case PIPE_FORMAT_B8G8R8A8_UNORM:
87          *value = EGL_TEXTURE_RGBA;
88          return EGL_TRUE;
89       case PIPE_FORMAT_B8G8R8X8_UNORM:
90          *value = EGL_TEXTURE_RGB;
91          return EGL_TRUE;
92       default:
93          return EGL_FALSE;
94       }
95    case EGL_WIDTH:
96       *value = buffer->buffer.width;
97       return EGL_TRUE;
98    case EGL_HEIGHT:
99       *value = buffer->buffer.height;
100       return EGL_TRUE;
101    default:
102       return EGL_FALSE;
103    }
104 }
105 
106 #endif
107