mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 12:55:58 +01:00
linux-dmabuf-v1: add wlr_linux_dmabuf_feedback_v1_init_with_options()
This commit is contained in:
parent
b264ec7767
commit
0c966f102c
2 changed files with 100 additions and 0 deletions
|
@ -111,4 +111,19 @@ struct wlr_linux_dmabuf_feedback_v1_tranche *wlr_linux_dmabuf_feedback_add_tranc
|
|||
*/
|
||||
void wlr_linux_dmabuf_feedback_v1_finish(struct wlr_linux_dmabuf_feedback_v1 *feedback);
|
||||
|
||||
struct wlr_linux_dmabuf_feedback_v1_init_options {
|
||||
// Main renderer used by the compositor
|
||||
struct wlr_renderer *main_renderer;
|
||||
// Output on which direct scan-out is possible on the primary plane, or NULL
|
||||
struct wlr_output *scanout_primary_output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a DMA-BUF feedback object with the provided options.
|
||||
*
|
||||
* The caller is responsible for calling wlr_linux_dmabuf_feedback_v1_finish() after use.
|
||||
*/
|
||||
bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feedback_v1 *feedback,
|
||||
const struct wlr_linux_dmabuf_feedback_v1_init_options *options);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/interfaces/wlr_buffer.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
|
@ -1076,3 +1077,87 @@ void wlr_linux_dmabuf_feedback_v1_finish(struct wlr_linux_dmabuf_feedback_v1 *fe
|
|||
}
|
||||
wl_array_release(&feedback->tranches);
|
||||
}
|
||||
|
||||
static bool devid_from_fd(int fd, dev_t *devid) {
|
||||
struct stat stat;
|
||||
if (fstat(fd, &stat) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "fstat failed");
|
||||
return false;
|
||||
}
|
||||
*devid = stat.st_rdev;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feedback_v1 *feedback,
|
||||
const struct wlr_linux_dmabuf_feedback_v1_init_options *options) {
|
||||
assert(options->main_renderer != NULL);
|
||||
|
||||
memset(feedback, 0, sizeof(*feedback));
|
||||
|
||||
int renderer_drm_fd = wlr_renderer_get_drm_fd(options->main_renderer);
|
||||
if (renderer_drm_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to get renderer DRM FD");
|
||||
goto error;
|
||||
}
|
||||
dev_t renderer_dev;
|
||||
if (!devid_from_fd(renderer_drm_fd, &renderer_dev)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
feedback->main_device = renderer_dev;
|
||||
|
||||
const struct wlr_drm_format_set *renderer_formats =
|
||||
wlr_renderer_get_dmabuf_texture_formats(options->main_renderer);
|
||||
if (renderer_formats == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to get renderer DMA-BUF texture formats");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (options->scanout_primary_output != NULL) {
|
||||
int backend_drm_fd = wlr_backend_get_drm_fd(options->scanout_primary_output->backend);
|
||||
if (backend_drm_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to get backend DRM FD");
|
||||
goto error;
|
||||
}
|
||||
dev_t backend_dev;
|
||||
if (!devid_from_fd(backend_drm_fd, &backend_dev)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
const struct wlr_drm_format_set *scanout_formats =
|
||||
wlr_output_get_primary_formats(options->scanout_primary_output, WLR_BUFFER_CAP_DMABUF);
|
||||
if (scanout_formats == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to get output primary DMA-BUF formats");
|
||||
goto error;
|
||||
}
|
||||
|
||||
struct wlr_linux_dmabuf_feedback_v1_tranche *tranche =
|
||||
wlr_linux_dmabuf_feedback_add_tranche(feedback);
|
||||
if (tranche == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
tranche->target_device = backend_dev;
|
||||
if (!wlr_drm_format_set_intersect(&tranche->formats, scanout_formats, renderer_formats)) {
|
||||
wlr_log(WLR_ERROR, "Failed to intersect renderer and scanout formats");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
struct wlr_linux_dmabuf_feedback_v1_tranche *tranche =
|
||||
wlr_linux_dmabuf_feedback_add_tranche(feedback);
|
||||
if (tranche == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
tranche->target_device = renderer_dev;
|
||||
if (!wlr_drm_format_set_copy(&tranche->formats, renderer_formats)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
wlr_linux_dmabuf_feedback_v1_finish(feedback);
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue