mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-29 04:49:49 +01:00
0817c52a21
The BO handle table exists to avoid double-closing a BO handle, which aren't reference-counted by the kernel. But if we can guarantee that there is only ever a single ref for each BO handle, then we don't need the BO handle table anymore. This is possible if we create the handle right before the ADDFB2 IOCTL, and close the handle right after. The handles are very short-lived and we don't need to track their lifetime. Because of multi-planar FBs, we need to be a bit careful: some FB planes might share the same handle. But with a small check, it's easy to avoid double-closing the same handle (which wouldn't be a big deal anyways). There's one gotcha though: drmModeSetCursor2 takes a BO handle as input. Saving the handles until drmModeSetCursor2 time would require us to track BO handle lifetimes, so we wouldn't be able to get rid of the BO handle table. As a workaround, use drmModeGetFB to turn the FB ID back to a BO handle, call drmModeSetCursor2 and then immediately close the BO handle. The overhead should be minimal since these IOCTLs are pretty cheap. Closes: https://github.com/swaywm/wlroots/issues/3164
60 lines
1.5 KiB
C
60 lines
1.5 KiB
C
#ifndef BACKEND_DRM_RENDERER_H
|
|
#define BACKEND_DRM_RENDERER_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <wlr/backend.h>
|
|
#include <wlr/render/wlr_renderer.h>
|
|
|
|
struct wlr_drm_backend;
|
|
struct wlr_drm_plane;
|
|
struct wlr_buffer;
|
|
|
|
struct wlr_drm_renderer {
|
|
struct wlr_drm_backend *backend;
|
|
|
|
struct wlr_renderer *wlr_rend;
|
|
struct wlr_allocator *allocator;
|
|
};
|
|
|
|
struct wlr_drm_surface {
|
|
struct wlr_drm_renderer *renderer;
|
|
|
|
uint32_t width;
|
|
uint32_t height;
|
|
|
|
struct wlr_swapchain *swapchain;
|
|
};
|
|
|
|
struct wlr_drm_fb {
|
|
struct wlr_buffer *wlr_buf;
|
|
struct wlr_addon addon;
|
|
struct wlr_drm_backend *backend;
|
|
struct wl_list link; // wlr_drm_backend.fbs
|
|
|
|
uint32_t id;
|
|
};
|
|
|
|
bool init_drm_renderer(struct wlr_drm_backend *drm,
|
|
struct wlr_drm_renderer *renderer);
|
|
void finish_drm_renderer(struct wlr_drm_renderer *renderer);
|
|
|
|
bool init_drm_surface(struct wlr_drm_surface *surf,
|
|
struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height,
|
|
const struct wlr_drm_format *drm_format);
|
|
|
|
bool drm_fb_import(struct wlr_drm_fb **fb, struct wlr_drm_backend *drm,
|
|
struct wlr_buffer *buf, const struct wlr_drm_format_set *formats);
|
|
void drm_fb_destroy(struct wlr_drm_fb *fb);
|
|
|
|
void drm_fb_clear(struct wlr_drm_fb **fb);
|
|
void drm_fb_move(struct wlr_drm_fb **new, struct wlr_drm_fb **old);
|
|
|
|
struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
|
|
struct wlr_buffer *buffer);
|
|
|
|
struct wlr_drm_format *drm_plane_pick_render_format(
|
|
struct wlr_drm_plane *plane, struct wlr_drm_renderer *renderer);
|
|
void drm_plane_finish_surface(struct wlr_drm_plane *plane);
|
|
|
|
#endif
|