Merge pull request #1642 from emersion/format-set
Introduce wlr_format_set
This commit is contained in:
commit
9faea17c73
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef WLR_RENDER_DRM_FORMAT_SET_H
|
||||||
|
#define WLR_RENDER_DRM_FORMAT_SET_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct wlr_drm_format {
|
||||||
|
uint32_t format;
|
||||||
|
size_t len, cap;
|
||||||
|
uint64_t modifiers[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_drm_format_set {
|
||||||
|
size_t len, cap;
|
||||||
|
struct wlr_drm_format **formats;
|
||||||
|
};
|
||||||
|
|
||||||
|
void wlr_drm_format_set_finish(struct wlr_drm_format_set *set);
|
||||||
|
|
||||||
|
const struct wlr_drm_format *wlr_drm_format_set_get(
|
||||||
|
const struct wlr_drm_format_set *set, uint32_t format);
|
||||||
|
|
||||||
|
bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format,
|
||||||
|
uint64_t modifier);
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,6 +21,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/render/dmabuf.h>
|
#include <wlr/render/dmabuf.h>
|
||||||
|
#include <wlr/render/drm_format_set.h>
|
||||||
|
|
||||||
struct wlr_egl {
|
struct wlr_egl {
|
||||||
EGLenum platform;
|
EGLenum platform;
|
||||||
|
@ -42,6 +43,8 @@ struct wlr_egl {
|
||||||
} exts;
|
} exts;
|
||||||
|
|
||||||
struct wl_display *wl_display;
|
struct wl_display *wl_display;
|
||||||
|
|
||||||
|
struct wlr_drm_format_set dmabuf_formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Allocate and return a wlr_egl
|
// TODO: Allocate and return a wlr_egl
|
||||||
|
@ -88,13 +91,7 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
||||||
/**
|
/**
|
||||||
* Get the available dmabuf formats
|
* Get the available dmabuf formats
|
||||||
*/
|
*/
|
||||||
int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, int **formats);
|
const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the available dmabuf modifiers for a given format
|
|
||||||
*/
|
|
||||||
int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, int format,
|
|
||||||
uint64_t **modifiers);
|
|
||||||
|
|
||||||
bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
|
bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
|
||||||
int32_t width, int32_t height, uint32_t flags,
|
int32_t width, int32_t height, uint32_t flags,
|
||||||
|
|
|
@ -46,9 +46,8 @@ struct wlr_renderer_impl {
|
||||||
struct wl_resource *resource);
|
struct wl_resource *resource);
|
||||||
void (*wl_drm_buffer_get_size)(struct wlr_renderer *renderer,
|
void (*wl_drm_buffer_get_size)(struct wlr_renderer *renderer,
|
||||||
struct wl_resource *buffer, int *width, int *height);
|
struct wl_resource *buffer, int *width, int *height);
|
||||||
int (*get_dmabuf_formats)(struct wlr_renderer *renderer, int **formats);
|
const struct wlr_drm_format_set *(*get_dmabuf_formats)(
|
||||||
int (*get_dmabuf_modifiers)(struct wlr_renderer *renderer, int format,
|
struct wlr_renderer *renderer);
|
||||||
uint64_t **modifiers);
|
|
||||||
enum wl_shm_format (*preferred_read_format)(struct wlr_renderer *renderer);
|
enum wl_shm_format (*preferred_read_format)(struct wlr_renderer *renderer);
|
||||||
bool (*read_pixels)(struct wlr_renderer *renderer, enum wl_shm_format fmt,
|
bool (*read_pixels)(struct wlr_renderer *renderer, enum wl_shm_format fmt,
|
||||||
uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
|
uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
install_headers(
|
install_headers(
|
||||||
'dmabuf.h',
|
'dmabuf.h',
|
||||||
'egl.h',
|
'egl.h',
|
||||||
|
'drm_format_set.h',
|
||||||
'gles2.h',
|
'gles2.h',
|
||||||
'interface.h',
|
'interface.h',
|
||||||
'wlr_renderer.h',
|
'wlr_renderer.h',
|
||||||
'wlr_texture.h',
|
'wlr_texture.h',
|
||||||
subdir: 'wlr/render'
|
subdir: 'wlr/render',
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,6 +20,7 @@ enum wlr_renderer_read_pixels_flags {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_renderer_impl;
|
struct wlr_renderer_impl;
|
||||||
|
struct wlr_drm_format_set;
|
||||||
|
|
||||||
struct wlr_renderer {
|
struct wlr_renderer {
|
||||||
const struct wlr_renderer_impl *impl;
|
const struct wlr_renderer_impl *impl;
|
||||||
|
@ -87,15 +88,10 @@ bool wlr_renderer_resource_is_wl_drm_buffer(struct wlr_renderer *renderer,
|
||||||
void wlr_renderer_wl_drm_buffer_get_size(struct wlr_renderer *renderer,
|
void wlr_renderer_wl_drm_buffer_get_size(struct wlr_renderer *renderer,
|
||||||
struct wl_resource *buffer, int *width, int *height);
|
struct wl_resource *buffer, int *width, int *height);
|
||||||
/**
|
/**
|
||||||
* Get the available dmabuf formats
|
* Get the available DMA-BUF formats.
|
||||||
*/
|
*/
|
||||||
int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *renderer,
|
const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_formats(
|
||||||
int **formats);
|
struct wlr_renderer *renderer);
|
||||||
/**
|
|
||||||
* Get the available dmabuf modifiers for a given format
|
|
||||||
*/
|
|
||||||
int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format,
|
|
||||||
uint64_t **modifiers);
|
|
||||||
/**
|
/**
|
||||||
* Reads out of pixels of the currently bound surface into data. `stride` is in
|
* Reads out of pixels of the currently bound surface into data. `stride` is in
|
||||||
* bytes.
|
* bytes.
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
#include <drm_fourcc.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wlr/render/drm_format_set.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
void wlr_drm_format_set_finish(struct wlr_drm_format_set *set) {
|
||||||
|
for (size_t i = 0; i < set->len; ++i) {
|
||||||
|
free(set->formats[i]);
|
||||||
|
}
|
||||||
|
free(set->formats);
|
||||||
|
|
||||||
|
set->len = 0;
|
||||||
|
set->cap = 0;
|
||||||
|
set->formats = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wlr_drm_format **format_set_get_ref(struct wlr_drm_format_set *set,
|
||||||
|
uint32_t format) {
|
||||||
|
for (size_t i = 0; i < set->len; ++i) {
|
||||||
|
if (set->formats[i]->format == format) {
|
||||||
|
return &set->formats[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct wlr_drm_format *wlr_drm_format_set_get(
|
||||||
|
const struct wlr_drm_format_set *set, uint32_t format) {
|
||||||
|
struct wlr_drm_format **ptr =
|
||||||
|
format_set_get_ref((struct wlr_drm_format_set *)set, format);
|
||||||
|
return ptr ? *ptr : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format,
|
||||||
|
uint64_t modifier) {
|
||||||
|
struct wlr_drm_format **ptr = format_set_get_ref(set, format);
|
||||||
|
|
||||||
|
if (ptr) {
|
||||||
|
struct wlr_drm_format *fmt = *ptr;
|
||||||
|
|
||||||
|
if (modifier == DRM_FORMAT_MOD_INVALID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < fmt->len; ++i) {
|
||||||
|
if (fmt->modifiers[i] == modifier) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fmt->len == fmt->cap) {
|
||||||
|
size_t cap = fmt->cap ? fmt->cap * 2 : 4;
|
||||||
|
|
||||||
|
fmt = realloc(fmt, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * cap);
|
||||||
|
if (!fmt) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt->cap = cap;
|
||||||
|
*ptr = fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt->modifiers[fmt->len++] = modifier;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cap = modifier != DRM_FORMAT_MOD_INVALID ? 4 : 0;
|
||||||
|
|
||||||
|
struct wlr_drm_format *fmt =
|
||||||
|
calloc(1, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * cap);
|
||||||
|
if (!fmt) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt->format = format;
|
||||||
|
if (cap) {
|
||||||
|
fmt->cap = cap;
|
||||||
|
fmt->len = 1;
|
||||||
|
fmt->modifiers[0] = modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set->len == set->cap) {
|
||||||
|
size_t new = set->cap ? set->cap * 2 : 4;
|
||||||
|
|
||||||
|
struct wlr_drm_format **tmp = realloc(set->formats,
|
||||||
|
sizeof(*fmt) + sizeof(fmt->modifiers[0]) * new);
|
||||||
|
if (!tmp) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
|
free(fmt);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set->cap = new;
|
||||||
|
set->formats = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
set->formats[set->len++] = fmt;
|
||||||
|
return true;
|
||||||
|
}
|
76
render/egl.c
76
render/egl.c
|
@ -1,7 +1,7 @@
|
||||||
#include <assert.h>
|
|
||||||
#include <drm_fourcc.h>
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <drm_fourcc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wlr/render/egl.h>
|
#include <wlr/render/egl.h>
|
||||||
|
@ -77,24 +77,49 @@ static bool check_egl_ext(const char *exts, const char *ext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_dmabuf_formats(struct wlr_egl *egl) {
|
static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats);
|
||||||
/* Avoid log msg if extension is not present */
|
static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
|
||||||
if (!egl->exts.image_dmabuf_import_modifiers_ext) {
|
uint64_t **modifiers);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void init_dmabuf_formats(struct wlr_egl *egl) {
|
||||||
int *formats;
|
int *formats;
|
||||||
int num = wlr_egl_get_dmabuf_formats(egl, &formats);
|
int formats_len = get_egl_dmabuf_formats(egl, &formats);
|
||||||
if (num < 0) {
|
if (formats_len < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char str_formats[num * 5 + 1];
|
for (int i = 0; i < formats_len; i++) {
|
||||||
for (int i = 0; i < num; i++) {
|
uint32_t fmt = formats[i];
|
||||||
snprintf(&str_formats[i*5], (num - i) * 5 + 1, "%.4s ",
|
|
||||||
|
uint64_t *modifiers;
|
||||||
|
int modifiers_len = get_egl_dmabuf_modifiers(egl, fmt, &modifiers);
|
||||||
|
if (modifiers_len < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modifiers_len == 0) {
|
||||||
|
wlr_drm_format_set_add(&egl->dmabuf_formats, fmt, DRM_FORMAT_MOD_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < modifiers_len; j++) {
|
||||||
|
wlr_drm_format_set_add(&egl->dmabuf_formats, fmt, modifiers[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_formats = malloc(formats_len * 5 + 1);
|
||||||
|
if (str_formats == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < formats_len; i++) {
|
||||||
|
snprintf(&str_formats[i*5], (formats_len - i) * 5 + 1, "%.4s ",
|
||||||
(char*)&formats[i]);
|
(char*)&formats[i]);
|
||||||
}
|
}
|
||||||
wlr_log(WLR_DEBUG, "Supported dmabuf buffer formats: %s", str_formats);
|
wlr_log(WLR_DEBUG, "Supported dmabuf buffer formats: %s", str_formats);
|
||||||
|
free(str_formats);
|
||||||
|
|
||||||
|
out:
|
||||||
free(formats);
|
free(formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +198,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
|
||||||
check_egl_ext(egl->exts_str, "EGL_MESA_image_dma_buf_export") &&
|
check_egl_ext(egl->exts_str, "EGL_MESA_image_dma_buf_export") &&
|
||||||
eglExportDMABUFImageQueryMESA && eglExportDMABUFImageMESA;
|
eglExportDMABUFImageQueryMESA && eglExportDMABUFImageMESA;
|
||||||
|
|
||||||
print_dmabuf_formats(egl);
|
init_dmabuf_formats(egl);
|
||||||
|
|
||||||
egl->exts.bind_wayland_display_wl =
|
egl->exts.bind_wayland_display_wl =
|
||||||
check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display")
|
check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display")
|
||||||
|
@ -242,6 +267,8 @@ void wlr_egl_finish(struct wlr_egl *egl) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlr_drm_format_set_finish(&egl->dmabuf_formats);
|
||||||
|
|
||||||
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
if (egl->wl_display) {
|
if (egl->wl_display) {
|
||||||
assert(egl->exts.bind_wayland_display_wl);
|
assert(egl->exts.bind_wayland_display_wl);
|
||||||
|
@ -486,10 +513,9 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
||||||
EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
|
static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
|
||||||
int **formats) {
|
|
||||||
if (!egl->exts.image_dmabuf_import_ext) {
|
if (!egl->exts.image_dmabuf_import_ext) {
|
||||||
wlr_log(WLR_DEBUG, "dmabuf import extension not present");
|
wlr_log(WLR_DEBUG, "DMA-BUF import extension not present");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +544,7 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
|
||||||
|
|
||||||
EGLint num;
|
EGLint num;
|
||||||
if (!eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) {
|
if (!eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) {
|
||||||
wlr_log(WLR_ERROR, "failed to query number of dmabuf formats");
|
wlr_log(WLR_ERROR, "Failed to query number of dmabuf formats");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,17 +555,17 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) {
|
if (!eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) {
|
||||||
wlr_log(WLR_ERROR, "failed to query dmabuf format");
|
wlr_log(WLR_ERROR, "Failed to query dmabuf format");
|
||||||
free(*formats);
|
free(*formats);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl,
|
static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
|
||||||
int format, uint64_t **modifiers) {
|
uint64_t **modifiers) {
|
||||||
if (!egl->exts.image_dmabuf_import_ext) {
|
if (!egl->exts.image_dmabuf_import_ext) {
|
||||||
wlr_log(WLR_DEBUG, "dmabuf extension not present");
|
wlr_log(WLR_DEBUG, "DMA-BUF extension not present");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +577,7 @@ int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl,
|
||||||
EGLint num;
|
EGLint num;
|
||||||
if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0,
|
if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0,
|
||||||
NULL, NULL, &num)) {
|
NULL, NULL, &num)) {
|
||||||
wlr_log(WLR_ERROR, "failed to query dmabuf number of modifiers");
|
wlr_log(WLR_ERROR, "Failed to query dmabuf number of modifiers");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,13 +589,17 @@ int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl,
|
||||||
|
|
||||||
if (!eglQueryDmaBufModifiersEXT(egl->display, format, num,
|
if (!eglQueryDmaBufModifiersEXT(egl->display, format, num,
|
||||||
*modifiers, NULL, &num)) {
|
*modifiers, NULL, &num)) {
|
||||||
wlr_log(WLR_ERROR, "failed to query dmabuf modifiers");
|
wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers");
|
||||||
free(*modifiers);
|
free(*modifiers);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl) {
|
||||||
|
return &egl->dmabuf_formats;
|
||||||
|
}
|
||||||
|
|
||||||
bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
|
bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
|
||||||
int32_t width, int32_t height, uint32_t flags,
|
int32_t width, int32_t height, uint32_t flags,
|
||||||
struct wlr_dmabuf_attributes *attribs) {
|
struct wlr_dmabuf_attributes *attribs) {
|
||||||
|
|
|
@ -247,16 +247,10 @@ static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
|
||||||
eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_HEIGHT, height);
|
eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_HEIGHT, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gles2_get_dmabuf_formats(struct wlr_renderer *wlr_renderer,
|
static const struct wlr_drm_format_set *gles2_get_dmabuf_formats(
|
||||||
int **formats) {
|
struct wlr_renderer *wlr_renderer) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
||||||
return wlr_egl_get_dmabuf_formats(renderer->egl, formats);
|
return wlr_egl_get_dmabuf_formats(renderer->egl);
|
||||||
}
|
|
||||||
|
|
||||||
static int gles2_get_dmabuf_modifiers(struct wlr_renderer *wlr_renderer,
|
|
||||||
int format, uint64_t **modifiers) {
|
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
|
||||||
return wlr_egl_get_dmabuf_modifiers(renderer->egl, format, modifiers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum wl_shm_format gles2_preferred_read_format(
|
static enum wl_shm_format gles2_preferred_read_format(
|
||||||
|
@ -402,7 +396,6 @@ static const struct wlr_renderer_impl renderer_impl = {
|
||||||
.resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer,
|
.resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer,
|
||||||
.wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size,
|
.wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size,
|
||||||
.get_dmabuf_formats = gles2_get_dmabuf_formats,
|
.get_dmabuf_formats = gles2_get_dmabuf_formats,
|
||||||
.get_dmabuf_modifiers = gles2_get_dmabuf_modifiers,
|
|
||||||
.preferred_read_format = gles2_preferred_read_format,
|
.preferred_read_format = gles2_preferred_read_format,
|
||||||
.read_pixels = gles2_read_pixels,
|
.read_pixels = gles2_read_pixels,
|
||||||
.texture_from_pixels = gles2_texture_from_pixels,
|
.texture_from_pixels = gles2_texture_from_pixels,
|
||||||
|
|
|
@ -12,6 +12,7 @@ lib_wlr_render = static_library(
|
||||||
files(
|
files(
|
||||||
'dmabuf.c',
|
'dmabuf.c',
|
||||||
'egl.c',
|
'egl.c',
|
||||||
|
'drm_format_set.c',
|
||||||
'gles2/pixel_format.c',
|
'gles2/pixel_format.c',
|
||||||
'gles2/renderer.c',
|
'gles2/renderer.c',
|
||||||
'gles2/shaders.c',
|
'gles2/shaders.c',
|
||||||
|
@ -27,7 +28,7 @@ lib_wlr_render = static_library(
|
||||||
drm.partial_dependency(compile_args: true), # <drm_fourcc.h>
|
drm.partial_dependency(compile_args: true), # <drm_fourcc.h>
|
||||||
glesv2,
|
glesv2,
|
||||||
pixman,
|
pixman,
|
||||||
wayland_server
|
wayland_server,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -123,20 +123,12 @@ void wlr_renderer_wl_drm_buffer_get_size(struct wlr_renderer *r,
|
||||||
return r->impl->wl_drm_buffer_get_size(r, buffer, width, height);
|
return r->impl->wl_drm_buffer_get_size(r, buffer, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *r,
|
const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_formats(
|
||||||
int **formats) {
|
struct wlr_renderer *r) {
|
||||||
if (!r->impl->get_dmabuf_formats) {
|
if (!r->impl->get_dmabuf_formats) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
return r->impl->get_dmabuf_formats(r, formats);
|
return r->impl->get_dmabuf_formats(r);
|
||||||
}
|
|
||||||
|
|
||||||
int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *r, int format,
|
|
||||||
uint64_t **modifiers) {
|
|
||||||
if (!r->impl->get_dmabuf_modifiers) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return r->impl->get_dmabuf_modifiers(r, format, modifiers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt,
|
bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
|
#include <wlr/render/drm_format_set.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
@ -386,45 +387,39 @@ struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_from_resource(
|
||||||
|
|
||||||
static void linux_dmabuf_send_formats(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
|
static void linux_dmabuf_send_formats(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
|
||||||
struct wl_resource *resource, uint32_t version) {
|
struct wl_resource *resource, uint32_t version) {
|
||||||
struct wlr_renderer *renderer = linux_dmabuf->renderer;
|
|
||||||
uint64_t modifier_invalid = DRM_FORMAT_MOD_INVALID;
|
uint64_t modifier_invalid = DRM_FORMAT_MOD_INVALID;
|
||||||
int *formats = NULL;
|
const struct wlr_drm_format_set *formats =
|
||||||
int num_formats = wlr_renderer_get_dmabuf_formats(renderer, &formats);
|
wlr_renderer_get_dmabuf_formats(linux_dmabuf->renderer);
|
||||||
if (num_formats < 0) {
|
if (formats == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_formats; i++) {
|
for (size_t i = 0; i < formats->len; i++) {
|
||||||
uint64_t *modifiers = NULL;
|
struct wlr_drm_format *fmt = formats->formats[i];
|
||||||
int num_modifiers = wlr_renderer_get_dmabuf_modifiers(renderer,
|
|
||||||
formats[i], &modifiers);
|
size_t modifiers_len = fmt->len;
|
||||||
if (num_modifiers < 0) {
|
uint64_t *modifiers = fmt->modifiers;
|
||||||
return;
|
|
||||||
}
|
// Send DRM_FORMAT_MOD_INVALID token when no modifiers are supported
|
||||||
/* send DRM_FORMAT_MOD_INVALID token when no modifiers are supported
|
// for this format
|
||||||
* for this format */
|
if (modifiers_len == 0) {
|
||||||
if (num_modifiers == 0) {
|
modifiers_len = 1;
|
||||||
num_modifiers = 1;
|
|
||||||
modifiers = &modifier_invalid;
|
modifiers = &modifier_invalid;
|
||||||
}
|
}
|
||||||
for (int j = 0; j < num_modifiers; j++) {
|
for (size_t j = 0; j < modifiers_len; j++) {
|
||||||
if (version >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
|
if (version >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
|
||||||
uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF;
|
uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF;
|
||||||
uint32_t modifier_hi = modifiers[j] >> 32;
|
uint32_t modifier_hi = modifiers[j] >> 32;
|
||||||
zwp_linux_dmabuf_v1_send_modifier(resource,
|
zwp_linux_dmabuf_v1_send_modifier(resource,
|
||||||
formats[i],
|
fmt->format,
|
||||||
modifier_hi,
|
modifier_hi,
|
||||||
modifier_lo);
|
modifier_lo);
|
||||||
} else if (modifiers[j] == DRM_FORMAT_MOD_LINEAR ||
|
} else if (modifiers[j] == DRM_FORMAT_MOD_LINEAR ||
|
||||||
modifiers == &modifier_invalid) {
|
modifiers == &modifier_invalid) {
|
||||||
zwp_linux_dmabuf_v1_send_format(resource, formats[i]);
|
zwp_linux_dmabuf_v1_send_format(resource, fmt->format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modifiers != &modifier_invalid) {
|
|
||||||
free(modifiers);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
free(formats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void linux_dmabuf_resource_destroy(struct wl_resource *resource) {
|
static void linux_dmabuf_resource_destroy(struct wl_resource *resource) {
|
||||||
|
|
Loading…
Reference in New Issue