mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-06-13 14:32:57 -04:00
linux-dmabuf-v1: upgrade to minor version 6
- Set the SAMPLING flag when appropriate - Stop sending the main_device event - Expose the buffer's sampling device in struct wlr_dmabuf_v1_buffer - Check tranches are well-formed according to the protocol - Add a fallback for main_device, grabbing the first SAMPLING tranche's target_device Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/work_items/4099
This commit is contained in:
parent
bd99e8c2bd
commit
3e8aed0d87
2 changed files with 77 additions and 12 deletions
|
|
@ -24,7 +24,10 @@ struct wlr_dmabuf_v1_buffer {
|
|||
struct wl_resource *resource; // can be NULL if the client destroyed it
|
||||
struct wlr_dmabuf_attributes attributes;
|
||||
|
||||
const dev_t *sampling_device; // can be NULL if unknown
|
||||
|
||||
struct {
|
||||
dev_t sampling_device_value;
|
||||
struct wl_listener release;
|
||||
} WLR_PRIVATE;
|
||||
};
|
||||
|
|
@ -37,7 +40,7 @@ struct wlr_dmabuf_v1_buffer *wlr_dmabuf_v1_buffer_try_from_buffer_resource(
|
|||
struct wl_resource *buffer_resource);
|
||||
|
||||
struct wlr_linux_dmabuf_feedback_v1 {
|
||||
dev_t main_device;
|
||||
dev_t main_device; // unused for >= v6
|
||||
struct wl_array tranches; // struct wlr_linux_dmabuf_feedback_v1_tranche
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,13 +21,15 @@
|
|||
#include <wlr/backend/drm.h>
|
||||
#endif
|
||||
|
||||
#define LINUX_DMABUF_VERSION 5
|
||||
#define LINUX_DMABUF_VERSION 6
|
||||
|
||||
struct wlr_linux_buffer_params_v1 {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_linux_dmabuf_v1 *linux_dmabuf;
|
||||
struct wlr_dmabuf_attributes attributes;
|
||||
bool has_modifier;
|
||||
bool has_sampling_device;
|
||||
dev_t sampling_device;
|
||||
};
|
||||
|
||||
struct wlr_linux_dmabuf_feedback_v1_compiled_tranche {
|
||||
|
|
@ -37,7 +39,7 @@ struct wlr_linux_dmabuf_feedback_v1_compiled_tranche {
|
|||
};
|
||||
|
||||
struct wlr_linux_dmabuf_feedback_v1_compiled {
|
||||
dev_t main_device;
|
||||
dev_t main_device; // for < v6
|
||||
int table_fd;
|
||||
size_t table_size;
|
||||
|
||||
|
|
@ -241,6 +243,8 @@ static void params_create_common(struct wl_resource *params_resource,
|
|||
|
||||
struct wlr_dmabuf_attributes attribs = params->attributes;
|
||||
struct wlr_linux_dmabuf_v1 *linux_dmabuf = params->linux_dmabuf;
|
||||
bool has_sampling_device = params->has_sampling_device;
|
||||
dev_t sampling_device = params->sampling_device;
|
||||
|
||||
// Make the params resource inert
|
||||
wl_resource_set_user_data(params_resource, NULL);
|
||||
|
|
@ -371,6 +375,11 @@ static void params_create_common(struct wl_resource *params_resource,
|
|||
buffer->release.notify = buffer_handle_release;
|
||||
wl_signal_add(&buffer->base.events.release, &buffer->release);
|
||||
|
||||
if (has_sampling_device) {
|
||||
buffer->sampling_device_value = sampling_device;
|
||||
buffer->sampling_device = &buffer->sampling_device_value;
|
||||
}
|
||||
|
||||
/* send 'created' event when the request is not for an immediate
|
||||
* import, that is buffer_id is zero */
|
||||
if (buffer_id == 0) {
|
||||
|
|
@ -412,11 +421,34 @@ static void params_create_immed(struct wl_client *client,
|
|||
format, flags);
|
||||
}
|
||||
|
||||
static void params_set_sampling_device(struct wl_client *client,
|
||||
struct wl_resource *params_resource, struct wl_array *devid_arr) {
|
||||
struct wlr_linux_buffer_params_v1 *params =
|
||||
params_from_resource(params_resource);
|
||||
if (!params) {
|
||||
wl_resource_post_error(params_resource,
|
||||
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED,
|
||||
"params was already used to create a wl_buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (devid_arr->size != sizeof(dev_t)) {
|
||||
wl_resource_post_error(params_resource,
|
||||
ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DEV_T_SIZE,
|
||||
"invalid dev_t size");
|
||||
return;
|
||||
}
|
||||
|
||||
params->has_sampling_device = true;
|
||||
memcpy(¶ms->sampling_device, devid_arr->data, sizeof(params->sampling_device));
|
||||
}
|
||||
|
||||
static const struct zwp_linux_buffer_params_v1_interface buffer_params_impl = {
|
||||
.destroy = params_destroy,
|
||||
.add = params_add,
|
||||
.create = params_create,
|
||||
.create_immed = params_create_immed,
|
||||
.set_sampling_device = params_set_sampling_device,
|
||||
};
|
||||
|
||||
static void params_handle_resource_destroy(struct wl_resource *resource) {
|
||||
|
|
@ -507,7 +539,7 @@ static ssize_t get_drm_format_set_index(const struct wlr_drm_format_set *set,
|
|||
}
|
||||
|
||||
static struct wlr_linux_dmabuf_feedback_v1_compiled *feedback_compile(
|
||||
const struct wlr_linux_dmabuf_feedback_v1 *feedback) {
|
||||
const struct wlr_linux_dmabuf_feedback_v1 *feedback, uint32_t version) {
|
||||
const struct wlr_linux_dmabuf_feedback_v1_tranche *tranches = feedback->tranches.data;
|
||||
size_t tranches_len = feedback->tranches.size / sizeof(struct wlr_linux_dmabuf_feedback_v1_tranche);
|
||||
assert(tranches_len > 0);
|
||||
|
|
@ -578,11 +610,27 @@ static struct wlr_linux_dmabuf_feedback_v1_compiled *feedback_compile(
|
|||
compiled->table_size = table_size;
|
||||
|
||||
// Build the indices lists for all tranches
|
||||
bool has_sampling_tranche = false;
|
||||
for (size_t i = 0; i < tranches_len; i++) {
|
||||
const struct wlr_linux_dmabuf_feedback_v1_tranche *tranche = &tranches[i];
|
||||
struct wlr_linux_dmabuf_feedback_v1_compiled_tranche *compiled_tranche =
|
||||
&compiled->tranches[i];
|
||||
|
||||
if (version >= ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SAMPLING_SINCE_VERSION) {
|
||||
if (tranche->flags == 0) {
|
||||
wlr_log(WLR_ERROR, "Tranche flags must not be zero");
|
||||
goto error_compiled;
|
||||
}
|
||||
|
||||
if (tranche->flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SAMPLING) {
|
||||
if (!has_sampling_tranche) {
|
||||
// For backwards compat with < v6
|
||||
compiled->main_device = tranche->target_device;
|
||||
}
|
||||
has_sampling_tranche = true;
|
||||
}
|
||||
}
|
||||
|
||||
compiled_tranche->target_device = tranche->target_device;
|
||||
compiled_tranche->flags = tranche->flags;
|
||||
|
||||
|
|
@ -613,6 +661,12 @@ static struct wlr_linux_dmabuf_feedback_v1_compiled *feedback_compile(
|
|||
compiled_tranche->indices.size = n * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if (version >= ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SAMPLING_SINCE_VERSION &&
|
||||
!has_sampling_tranche) {
|
||||
wlr_log(WLR_ERROR, "Missing a SAMPLING tranche");
|
||||
goto error_compiled;
|
||||
}
|
||||
|
||||
wlr_drm_format_set_finish(&all_formats);
|
||||
|
||||
return compiled;
|
||||
|
|
@ -645,7 +699,11 @@ static void feedback_tranche_send(
|
|||
.data = (void *)&tranche->target_device,
|
||||
};
|
||||
zwp_linux_dmabuf_feedback_v1_send_tranche_target_device(resource, &dev_array);
|
||||
zwp_linux_dmabuf_feedback_v1_send_tranche_flags(resource, tranche->flags);
|
||||
uint32_t flags = tranche->flags;
|
||||
if (wl_resource_get_version(resource) < ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SAMPLING_SINCE_VERSION) {
|
||||
flags &= ~ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SAMPLING;
|
||||
}
|
||||
zwp_linux_dmabuf_feedback_v1_send_tranche_flags(resource, flags);
|
||||
zwp_linux_dmabuf_feedback_v1_send_tranche_formats(resource,
|
||||
(struct wl_array *)&tranche->indices);
|
||||
zwp_linux_dmabuf_feedback_v1_send_tranche_done(resource);
|
||||
|
|
@ -653,11 +711,13 @@ static void feedback_tranche_send(
|
|||
|
||||
static void feedback_send(const struct wlr_linux_dmabuf_feedback_v1_compiled *feedback,
|
||||
struct wl_resource *resource) {
|
||||
struct wl_array dev_array = {
|
||||
.size = sizeof(feedback->main_device),
|
||||
.data = (void *)&feedback->main_device,
|
||||
};
|
||||
zwp_linux_dmabuf_feedback_v1_send_main_device(resource, &dev_array);
|
||||
if (wl_resource_get_version(resource) < 6) {
|
||||
struct wl_array dev_array = {
|
||||
.size = sizeof(feedback->main_device),
|
||||
.data = (void *)&feedback->main_device,
|
||||
};
|
||||
zwp_linux_dmabuf_feedback_v1_send_main_device(resource, &dev_array);
|
||||
}
|
||||
|
||||
zwp_linux_dmabuf_feedback_v1_send_format_table(resource,
|
||||
feedback->table_fd, feedback->table_size);
|
||||
|
|
@ -886,7 +946,8 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
|||
|
||||
static bool set_default_feedback(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
|
||||
const struct wlr_linux_dmabuf_feedback_v1 *feedback) {
|
||||
struct wlr_linux_dmabuf_feedback_v1_compiled *compiled = feedback_compile(feedback);
|
||||
struct wlr_linux_dmabuf_feedback_v1_compiled *compiled =
|
||||
feedback_compile(feedback, wl_global_get_version(linux_dmabuf->global));
|
||||
if (compiled == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1025,7 +1086,7 @@ bool wlr_linux_dmabuf_v1_set_surface_feedback(
|
|||
|
||||
struct wlr_linux_dmabuf_feedback_v1_compiled *compiled = NULL;
|
||||
if (feedback != NULL) {
|
||||
compiled = feedback_compile(feedback);
|
||||
compiled = feedback_compile(feedback, wl_global_get_version(linux_dmabuf->global));
|
||||
if (compiled == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1163,6 +1224,7 @@ bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feed
|
|||
}
|
||||
|
||||
tranche->target_device = renderer_dev;
|
||||
tranche->flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SAMPLING;
|
||||
if (!wlr_drm_format_set_copy(&tranche->formats, renderer_formats)) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue