Add initial linux_dmabuf protocol support

Tested with

    ./weston-simple-dmabuf-drm
    ./weston-simple-dmabuf-drm --import-immediate=1
    ./weston-simple-dmabuf-drm --y-inverted=1
    (and combinations)

Supports only single plane XRGB dmabufs for now.
This commit is contained in:
Guido Günther 2018-02-23 18:45:16 +01:00
parent 2d0db16942
commit 14cdb6153f
12 changed files with 787 additions and 4 deletions

View file

@ -123,6 +123,8 @@ bool wlr_texture_upload_drm(struct wlr_texture *tex,
bool wlr_texture_upload_eglimage(struct wlr_texture *tex,
EGLImageKHR image, uint32_t width, uint32_t height);
bool wlr_texture_upload_dmabuf(struct wlr_texture *tex,
struct wl_resource *dmabuf_resource);
/**
* Copies a rectangle of pixels from a wl_shm_buffer onto the texture. The
* buffer is not accessed after this function returns. Under some circumstances,

View file

@ -6,6 +6,7 @@
#include <pixman.h>
#include <stdbool.h>
#include <wayland-server.h>
#include <wlr/types/wlr_linux_dmabuf.h>
struct wlr_egl {
EGLDisplay display;
@ -18,6 +19,8 @@ struct wlr_egl {
struct {
bool buffer_age;
bool swap_buffers_with_damage;
bool dmabuf_import;
bool dmabuf_import_modifiers;
} egl_exts;
struct wl_display *wl_display;
@ -61,6 +64,31 @@ EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window);
EGLImageKHR wlr_egl_create_image(struct wlr_egl *egl,
EGLenum target, EGLClientBuffer buffer, const EGLint *attribs);
/**
* Creates an egl image from the given dmabuf attributes. Check usability
* of the dmabuf with wlr_egl_check_import_dmabuf once first.
*/
EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
struct wlr_dmabuf_buffer_attribs *attributes);
/**
* Try to import the given dmabuf. On success return true false otherwise.
* If this succeeds the dmabuf can be used for rendering on a texture
*/
bool wlr_egl_check_import_dmabuf(struct wlr_egl *egl,
struct wlr_dmabuf_buffer *dmabuf);
/**
* Get the available dmabuf formats
*/
int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, int **formats);
/**
* Get the available dmabuf modifiers for a given format
*/
int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, int format,
uint64_t **modifiers);
/**
* Destroys an egl image created with the given wlr_egl.
*/

View file

@ -8,6 +8,7 @@
#include <wlr/render.h>
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_linux_dmabuf.h>
struct wlr_renderer_impl;
@ -58,6 +59,8 @@ struct wlr_texture_impl {
struct wl_resource *drm_buf);
bool (*upload_eglimage)(struct wlr_texture *texture, EGLImageKHR image,
uint32_t width, uint32_t height);
bool (*upload_dmabuf)(struct wlr_texture *texture,
struct wl_resource *dmabuf_resource);
void (*get_matrix)(struct wlr_texture *state,
float (*matrix)[16], const float (*projection)[16], int x, int y);
void (*get_buffer_size)(struct wlr_texture *texture,

View file

@ -0,0 +1,84 @@
#ifndef WLR_TYPES_WLR_LINUX_DMABUF_H
#define WLR_TYPES_WLR_LINUX_DMABUF_H
#define WLR_LINUX_DMABUF_MAX_PLANES 4
#include <stdint.h>
#include <wayland-server-protocol.h>
/* So we don't have to pull in linux specific drm headers */
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
#endif
struct wlr_dmabuf_buffer_attribs {
/* set via params_add */
int n_planes;
uint32_t offset[WLR_LINUX_DMABUF_MAX_PLANES];
uint32_t stride[WLR_LINUX_DMABUF_MAX_PLANES];
uint64_t modifier[WLR_LINUX_DMABUF_MAX_PLANES];
int fd[WLR_LINUX_DMABUF_MAX_PLANES];
/* set via params_create */
int32_t width;
int32_t height;
uint32_t format;
uint32_t flags; /* enum zlinux_buffer_params_flags */
};
struct wlr_dmabuf_buffer {
struct wlr_egl *egl;
struct wl_resource *buffer_resource;
struct wl_resource *params_resource;
struct wlr_dmabuf_buffer_attribs attributes;
};
/**
* Returns true if the given resource was created via the linux-dmabuf
* buffer protocol, false otherwise
*/
bool wlr_dmabuf_resource_is_buffer(struct wl_resource *buffer_resource);
/**
* Returns the wlr_dmabuf_buffer if the given resource was created
* via the linux-dmabuf buffer protocol
*/
struct wlr_dmabuf_buffer *wlr_dmabuf_buffer_from_buffer_resource(
struct wl_resource *buffer_resource);
/**
* Returns the wlr_dmabuf_buffer if the given resource was created
* via the linux-dmabuf params protocol
*/
struct wlr_dmabuf_buffer *wlr_dmabuf_buffer_from_params_resource(
struct wl_resource *params_resource);
/**
* Returns true if the given dmabuf has y-axis inverted, false otherwise
*/
bool wlr_dmabuf_buffer_has_inverted_y(struct wlr_dmabuf_buffer *dmabuf);
/* the protocol interface */
struct wlr_linux_dmabuf {
struct wl_global *wl_global;
struct wl_listener display_destroy;
struct wlr_egl *egl;
};
/**
* Create linux-dmabuf interface
*/
struct wlr_linux_dmabuf *wlr_linux_dmabuf_create(struct wl_display *display,
struct wlr_egl *egl);
/**
* Destroy the linux-dmabuf interface
*/
void wlr_linux_dmabuf_destroy(struct wlr_linux_dmabuf *linux_dmabuf);
/**
* Returns the wlr_linux_dmabuf if the given resource was created
* via the linux_dmabuf protocol
*/
struct wlr_linux_dmabuf *wlr_linux_dmabuf_from_resource(
struct wl_resource *resource);
#endif