|
|
@ -1,5 +1,6 @@
|
|
|
|
#define _POSIX_C_SOURCE 200112L
|
|
|
|
#define _POSIX_C_SOURCE 200112L
|
|
|
|
#include <assert.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include <drm_fourcc.h>
|
|
|
|
#include <drm_mode.h>
|
|
|
|
#include <drm_mode.h>
|
|
|
|
#include <EGL/egl.h>
|
|
|
|
#include <EGL/egl.h>
|
|
|
|
#include <EGL/eglext.h>
|
|
|
|
#include <EGL/eglext.h>
|
|
|
@ -109,8 +110,8 @@ static bool init_planes(struct wlr_drm_backend *drm) {
|
|
|
|
|
|
|
|
|
|
|
|
p->id = plane->plane_id;
|
|
|
|
p->id = plane->plane_id;
|
|
|
|
p->possible_crtcs = plane->possible_crtcs;
|
|
|
|
p->possible_crtcs = plane->possible_crtcs;
|
|
|
|
uint64_t type;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t type;
|
|
|
|
if (!get_drm_plane_props(drm->fd, p->id, &p->props) ||
|
|
|
|
if (!get_drm_plane_props(drm->fd, p->id, &p->props) ||
|
|
|
|
!get_drm_prop(drm->fd, p->id, p->props.type, &type)) {
|
|
|
|
!get_drm_prop(drm->fd, p->id, p->props.type, &type)) {
|
|
|
|
drmModeFreePlane(plane);
|
|
|
|
drmModeFreePlane(plane);
|
|
|
@ -120,6 +121,25 @@ static bool init_planes(struct wlr_drm_backend *drm) {
|
|
|
|
p->type = type;
|
|
|
|
p->type = type;
|
|
|
|
drm->num_type_planes[type]++;
|
|
|
|
drm->num_type_planes[type]++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Choose an RGB format for the plane
|
|
|
|
|
|
|
|
uint32_t rgb_format = DRM_FORMAT_INVALID;
|
|
|
|
|
|
|
|
for (size_t j = 0; j < plane->count_formats; ++j) {
|
|
|
|
|
|
|
|
uint32_t fmt = plane->formats[j];
|
|
|
|
|
|
|
|
if (fmt == DRM_FORMAT_ARGB8888) {
|
|
|
|
|
|
|
|
// Prefer formats with alpha channel
|
|
|
|
|
|
|
|
rgb_format = fmt;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
} else if (fmt == DRM_FORMAT_XRGB8888) {
|
|
|
|
|
|
|
|
rgb_format = fmt;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rgb_format == DRM_FORMAT_INVALID) {
|
|
|
|
|
|
|
|
wlr_log(WLR_ERROR, "Failed to find an RGB format for plane %zu", i);
|
|
|
|
|
|
|
|
drmModeFreePlane(plane);
|
|
|
|
|
|
|
|
goto error_planes;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
p->drm_format = rgb_format;
|
|
|
|
|
|
|
|
|
|
|
|
drmModeFreePlane(plane);
|
|
|
|
drmModeFreePlane(plane);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -247,7 +267,7 @@ static bool drm_connector_swap_buffers(struct wlr_output *output,
|
|
|
|
if (drm->parent) {
|
|
|
|
if (drm->parent) {
|
|
|
|
bo = copy_drm_surface_mgpu(&plane->mgpu_surf, bo);
|
|
|
|
bo = copy_drm_surface_mgpu(&plane->mgpu_surf, bo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uint32_t fb_id = get_fb_for_bo(bo);
|
|
|
|
uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format);
|
|
|
|
|
|
|
|
|
|
|
|
if (conn->pageflip_pending) {
|
|
|
|
if (conn->pageflip_pending) {
|
|
|
|
wlr_log(WLR_ERROR, "Skipping pageflip on output '%s'", conn->output.name);
|
|
|
|
wlr_log(WLR_ERROR, "Skipping pageflip on output '%s'", conn->output.name);
|
|
|
@ -366,7 +386,7 @@ static void drm_connector_start_renderer(struct wlr_drm_connector *conn) {
|
|
|
|
|
|
|
|
|
|
|
|
struct gbm_bo *bo = get_drm_surface_front(
|
|
|
|
struct gbm_bo *bo = get_drm_surface_front(
|
|
|
|
drm->parent ? &plane->mgpu_surf : &plane->surf);
|
|
|
|
drm->parent ? &plane->mgpu_surf : &plane->surf);
|
|
|
|
uint32_t fb_id = get_fb_for_bo(bo);
|
|
|
|
uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format);
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode;
|
|
|
|
struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode;
|
|
|
|
if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, &mode->drm_mode)) {
|
|
|
|
if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, &mode->drm_mode)) {
|
|
|
@ -528,7 +548,7 @@ static bool drm_connector_set_mode(struct wlr_output *output,
|
|
|
|
conn->output.name, mode->width, mode->height, mode->refresh);
|
|
|
|
conn->output.name, mode->width, mode->height, mode->refresh);
|
|
|
|
|
|
|
|
|
|
|
|
if (!init_drm_plane_surfaces(conn->crtc->primary, drm,
|
|
|
|
if (!init_drm_plane_surfaces(conn->crtc->primary, drm,
|
|
|
|
mode->width, mode->height, GBM_FORMAT_XRGB8888)) {
|
|
|
|
mode->width, mode->height, drm->renderer.gbm_format)) {
|
|
|
|
wlr_log(WLR_ERROR, "Failed to initialize renderer for plane");
|
|
|
|
wlr_log(WLR_ERROR, "Failed to initialize renderer for plane");
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -622,13 +642,13 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
|
|
|
|
drm->parent ? &drm->parent->renderer : &drm->renderer;
|
|
|
|
drm->parent ? &drm->parent->renderer : &drm->renderer;
|
|
|
|
|
|
|
|
|
|
|
|
if (!init_drm_surface(&plane->surf, renderer, w, h,
|
|
|
|
if (!init_drm_surface(&plane->surf, renderer, w, h,
|
|
|
|
GBM_FORMAT_ARGB8888, 0)) {
|
|
|
|
renderer->gbm_format, 0)) {
|
|
|
|
wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
|
|
|
|
wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
plane->cursor_bo = gbm_bo_create(drm->renderer.gbm, w, h,
|
|
|
|
plane->cursor_bo = gbm_bo_create(drm->renderer.gbm, w, h,
|
|
|
|
GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
|
|
|
renderer->gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
|
|
|
if (!plane->cursor_bo) {
|
|
|
|
if (!plane->cursor_bo) {
|
|
|
|
wlr_log_errno(WLR_ERROR, "Failed to create cursor bo");
|
|
|
|
wlr_log_errno(WLR_ERROR, "Failed to create cursor bo");
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
@ -785,7 +805,6 @@ static bool drm_connector_schedule_frame(struct wlr_output *output) {
|
|
|
|
if (drm->parent) {
|
|
|
|
if (drm->parent) {
|
|
|
|
bo = copy_drm_surface_mgpu(&plane->mgpu_surf, bo);
|
|
|
|
bo = copy_drm_surface_mgpu(&plane->mgpu_surf, bo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uint32_t fb_id = get_fb_for_bo(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (conn->pageflip_pending) {
|
|
|
|
if (conn->pageflip_pending) {
|
|
|
|
wlr_log(WLR_ERROR, "Skipping pageflip on output '%s'",
|
|
|
|
wlr_log(WLR_ERROR, "Skipping pageflip on output '%s'",
|
|
|
@ -793,6 +812,7 @@ static bool drm_connector_schedule_frame(struct wlr_output *output) {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format);
|
|
|
|
if (!drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) {
|
|
|
|
if (!drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -998,7 +1018,7 @@ static void realloc_crtcs(struct wlr_drm_backend *drm, bool *changed_outputs) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!init_drm_plane_surfaces(conn->crtc->primary, drm,
|
|
|
|
if (!init_drm_plane_surfaces(conn->crtc->primary, drm,
|
|
|
|
mode->width, mode->height, GBM_FORMAT_XRGB8888)) {
|
|
|
|
mode->width, mode->height, drm->renderer.gbm_format)) {
|
|
|
|
wlr_log(WLR_ERROR, "Failed to initialize renderer for plane");
|
|
|
|
wlr_log(WLR_ERROR, "Failed to initialize renderer for plane");
|
|
|
|
drm_connector_cleanup(conn);
|
|
|
|
drm_connector_cleanup(conn);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|