mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-26 06:35: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);
|
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
|
#endif
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <wlr/backend.h>
|
||||||
#include <wlr/interfaces/wlr_buffer.h>
|
#include <wlr/interfaces/wlr_buffer.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_compositor.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);
|
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