More cleanups
This commit is contained in:
parent
dd7a349295
commit
2f8b5c4448
|
@ -32,6 +32,7 @@ static void wlr_drm_backend_destroy(struct wlr_backend_state *drm) {
|
||||||
|
|
||||||
wlr_udev_signal_remove(drm->udev, &drm->drm_invalidated);
|
wlr_udev_signal_remove(drm->udev, &drm->drm_invalidated);
|
||||||
wlr_drm_renderer_free(&drm->renderer);
|
wlr_drm_renderer_free(&drm->renderer);
|
||||||
|
wlr_drm_resources_free(drm);
|
||||||
wlr_session_close_file(drm->session, drm->fd);
|
wlr_session_close_file(drm->session, drm->fd);
|
||||||
wl_event_source_remove(drm->drm_event);
|
wl_event_source_remove(drm->drm_event);
|
||||||
free(drm);
|
free(drm);
|
||||||
|
@ -55,11 +56,6 @@ static void session_signal(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wlr_log(L_INFO, "DRM fd paused");
|
wlr_log(L_INFO, "DRM fd paused");
|
||||||
|
|
||||||
for (size_t i = 0; i < drm->outputs->length; ++i) {
|
|
||||||
struct wlr_output_state *output = drm->outputs->items[i];
|
|
||||||
wlr_drm_output_pause_renderer(output);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,19 +54,15 @@ static bool init_planes(struct wlr_backend_state *drm)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_planes = plane_res->count_planes;
|
drm->num_planes = plane_res->count_planes;
|
||||||
struct wlr_drm_plane *planes = calloc(num_planes, sizeof(*planes));
|
drm->planes = calloc(drm->num_planes, sizeof(*drm->planes));
|
||||||
if (!planes) {
|
if (!drm->planes) {
|
||||||
wlr_log_errno(L_ERROR, "Allocation failed");
|
wlr_log_errno(L_ERROR, "Allocation failed");
|
||||||
goto error_res;
|
goto error_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_overlay = 0;
|
for (size_t i = 0; i < drm->num_planes; ++i) {
|
||||||
size_t num_primary = 0;
|
struct wlr_drm_plane *p = &drm->planes[i];
|
||||||
size_t num_cursor = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_planes; ++i) {
|
|
||||||
struct wlr_drm_plane *p = &planes[i];
|
|
||||||
|
|
||||||
drmModePlane *plane = drmModeGetPlane(drm->fd, plane_res->planes[i]);
|
drmModePlane *plane = drmModeGetPlane(drm->fd, plane_res->planes[i]);
|
||||||
if (!plane) {
|
if (!plane) {
|
||||||
|
@ -85,41 +81,24 @@ static bool init_planes(struct wlr_backend_state *drm)
|
||||||
}
|
}
|
||||||
|
|
||||||
p->type = type;
|
p->type = type;
|
||||||
|
drm->num_type_planes[type]++;
|
||||||
switch (type) {
|
|
||||||
case DRM_PLANE_TYPE_OVERLAY:
|
|
||||||
++num_overlay;
|
|
||||||
break;
|
|
||||||
case DRM_PLANE_TYPE_PRIMARY:
|
|
||||||
++num_primary;
|
|
||||||
break;
|
|
||||||
case DRM_PLANE_TYPE_CURSOR:
|
|
||||||
++num_cursor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
drmModeFreePlane(plane);
|
drmModeFreePlane(plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_log(L_INFO, "(%zu overlay, %zu primary, %zu cursor)",
|
wlr_log(L_INFO, "(%zu overlay, %zu primary, %zu cursor)",
|
||||||
num_overlay, num_primary, num_cursor);
|
drm->num_overlay_planes, drm->num_primary_planes, drm->num_cursor_planes);
|
||||||
|
|
||||||
qsort(planes, num_planes, sizeof(*planes), cmp_plane);
|
qsort(drm->planes, drm->num_planes, sizeof(*drm->planes), cmp_plane);
|
||||||
|
|
||||||
drm->num_planes = num_planes;
|
drm->overlay_planes = drm->planes;
|
||||||
drm->num_overlay_planes = num_overlay;
|
drm->primary_planes = drm->overlay_planes + drm->num_overlay_planes;
|
||||||
drm->num_primary_planes = num_primary;
|
drm->cursor_planes = drm->primary_planes + drm->num_primary_planes;
|
||||||
drm->num_cursor_planes = num_cursor;
|
|
||||||
|
|
||||||
drm->planes = planes;
|
|
||||||
drm->overlay_planes = planes;
|
|
||||||
drm->primary_planes = planes + num_overlay;
|
|
||||||
drm->cursor_planes = planes + num_overlay + num_primary;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_planes:
|
error_planes:
|
||||||
free(planes);
|
free(drm->planes);
|
||||||
error_res:
|
error_res:
|
||||||
drmModeFreePlaneResources(plane_res);
|
drmModeFreePlaneResources(plane_res);
|
||||||
return false;
|
return false;
|
||||||
|
@ -162,6 +141,14 @@ error_res:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_drm_resources_free(struct wlr_backend_state *drm) {
|
||||||
|
if (!drm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(drm->crtcs);
|
||||||
|
free(drm->planes);
|
||||||
|
}
|
||||||
|
|
||||||
bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) {
|
bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) {
|
||||||
renderer->gbm = gbm_create_device(fd);
|
renderer->gbm = gbm_create_device(fd);
|
||||||
if (!renderer->gbm) {
|
if (!renderer->gbm) {
|
||||||
|
@ -179,54 +166,55 @@ bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer) {
|
void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer) {
|
||||||
if (!renderer) {
|
if (!renderer)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
wlr_egl_free(&renderer->egl);
|
wlr_egl_free(&renderer->egl);
|
||||||
gbm_device_destroy(renderer->gbm);
|
gbm_device_destroy(renderer->gbm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_fb(struct gbm_bo *bo, void *data) {
|
static void free_fb(struct gbm_bo *bo, void *data) {
|
||||||
uint32_t *id = data;
|
uint32_t id = (uintptr_t)data;
|
||||||
|
|
||||||
if (id && *id) {
|
if (id) {
|
||||||
struct gbm_device *gbm = gbm_bo_get_device(bo);
|
struct gbm_device *gbm = gbm_bo_get_device(bo);
|
||||||
drmModeRmFB(gbm_device_get_fd(gbm), *id);
|
drmModeRmFB(gbm_device_get_fd(gbm), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_fb_for_bo(struct gbm_bo *bo) {
|
static uint32_t get_fb_for_bo(struct gbm_bo *bo) {
|
||||||
uint32_t *id = gbm_bo_get_user_data(bo);
|
uint32_t id = (uintptr_t)gbm_bo_get_user_data(bo);
|
||||||
|
if (id)
|
||||||
if (id) {
|
return id;
|
||||||
return *id;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = calloc(1, sizeof *id);
|
|
||||||
if (!id) {
|
|
||||||
wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gbm_device *gbm = gbm_bo_get_device(bo);
|
struct gbm_device *gbm = gbm_bo_get_device(bo);
|
||||||
int fd = gbm_device_get_fd(gbm);
|
drmModeAddFB(gbm_device_get_fd(gbm), gbm_bo_get_width(bo), gbm_bo_get_height(bo),
|
||||||
|
24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &id);
|
||||||
|
|
||||||
drmModeAddFB(fd, gbm_bo_get_width(bo), gbm_bo_get_height(bo), 24, 32,
|
gbm_bo_set_user_data(bo, (void *)(uintptr_t)id, free_fb);
|
||||||
gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, id);
|
|
||||||
|
|
||||||
gbm_bo_set_user_data(bo, id, free_fb);
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
return *id;
|
static void wlr_drm_plane_make_current(struct wlr_drm_renderer *renderer,
|
||||||
|
struct wlr_drm_plane *plane) {
|
||||||
|
eglMakeCurrent(renderer->egl.display, plane->egl, plane->egl,
|
||||||
|
renderer->egl.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wlr_drm_plane_swap_buffers(struct wlr_drm_renderer *renderer,
|
||||||
|
struct wlr_drm_plane *plane) {
|
||||||
|
if (plane->front)
|
||||||
|
gbm_surface_release_buffer(plane->gbm, plane->front);
|
||||||
|
|
||||||
|
eglSwapBuffers(renderer->egl.display, plane->egl);
|
||||||
|
|
||||||
|
plane->front = plane->back;
|
||||||
|
plane->back = gbm_surface_lock_front_buffer(plane->gbm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wlr_drm_output_make_current(struct wlr_output_state *output) {
|
static void wlr_drm_output_make_current(struct wlr_output_state *output) {
|
||||||
struct wlr_drm_renderer *renderer = output->renderer;
|
wlr_drm_plane_make_current(output->renderer, output->crtc->primary);
|
||||||
struct wlr_drm_plane *plane = output->crtc->primary;
|
|
||||||
|
|
||||||
eglMakeCurrent(renderer->egl.display, plane->egl,
|
|
||||||
plane->egl, renderer->egl.context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wlr_drm_output_swap_buffers(struct wlr_output_state *output) {
|
static void wlr_drm_output_swap_buffers(struct wlr_output_state *output) {
|
||||||
|
@ -234,39 +222,11 @@ static void wlr_drm_output_swap_buffers(struct wlr_output_state *output) {
|
||||||
struct wlr_drm_crtc *crtc = output->crtc;
|
struct wlr_drm_crtc *crtc = output->crtc;
|
||||||
struct wlr_drm_plane *plane = crtc->primary;
|
struct wlr_drm_plane *plane = crtc->primary;
|
||||||
|
|
||||||
if (!eglSwapBuffers(renderer->egl.display, plane->egl)) {
|
wlr_drm_plane_swap_buffers(renderer, plane);
|
||||||
return;
|
uint32_t fb_id = get_fb_for_bo(plane->back);
|
||||||
}
|
|
||||||
|
|
||||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(plane->gbm);
|
|
||||||
if (!bo) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fb_id = get_fb_for_bo(bo);
|
|
||||||
drmModePageFlip(renderer->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output);
|
drmModePageFlip(renderer->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output);
|
||||||
output->pageflip_pending = true;
|
output->pageflip_pending = true;
|
||||||
|
|
||||||
plane->front = plane->back;
|
|
||||||
plane->back = bo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wlr_drm_output_pause_renderer(struct wlr_output_state *output) {
|
|
||||||
if (output->state != WLR_DRM_OUTPUT_CONNECTED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_drm_plane *plane = output->crtc->primary;
|
|
||||||
|
|
||||||
if (plane->front) {
|
|
||||||
gbm_surface_release_buffer(plane->gbm, plane->front);
|
|
||||||
plane->front = NULL;
|
|
||||||
}
|
|
||||||
if (plane->back) {
|
|
||||||
gbm_surface_release_buffer(plane->gbm, plane->back);
|
|
||||||
plane->back = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_drm_output_start_renderer(struct wlr_output_state *output) {
|
void wlr_drm_output_start_renderer(struct wlr_output_state *output) {
|
||||||
|
@ -279,19 +239,16 @@ void wlr_drm_output_start_renderer(struct wlr_output_state *output) {
|
||||||
struct wlr_drm_crtc *crtc = output->crtc;
|
struct wlr_drm_crtc *crtc = output->crtc;
|
||||||
struct wlr_drm_plane *plane = crtc->primary;
|
struct wlr_drm_plane *plane = crtc->primary;
|
||||||
|
|
||||||
eglMakeCurrent(renderer->egl.display, plane->egl, plane->egl, renderer->egl.context);
|
struct gbm_bo *bo = plane->front;
|
||||||
|
if (!bo) {
|
||||||
glViewport(0, 0, output->width, output->height);
|
// Render a black frame to start the rendering loop
|
||||||
|
wlr_drm_plane_make_current(renderer, plane);
|
||||||
|
glViewport(0, 0, plane->width, plane->height);
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
wlr_drm_plane_swap_buffers(renderer, plane);
|
||||||
|
|
||||||
if (!eglSwapBuffers(renderer->egl.display, plane->egl)) {
|
bo = plane->back;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(plane->gbm);
|
|
||||||
if (!bo) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fb_id = get_fb_for_bo(bo);
|
uint32_t fb_id = get_fb_for_bo(bo);
|
||||||
|
@ -299,9 +256,6 @@ void wlr_drm_output_start_renderer(struct wlr_output_state *output) {
|
||||||
&output->connector, 1, &mode->state->mode);
|
&output->connector, 1, &mode->state->mode);
|
||||||
drmModePageFlip(renderer->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output);
|
drmModePageFlip(renderer->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output);
|
||||||
output->pageflip_pending = true;
|
output->pageflip_pending = true;
|
||||||
|
|
||||||
plane->back = plane->front;
|
|
||||||
plane->front = bo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool plane_init_renderer(struct wlr_drm_renderer *renderer,
|
static bool plane_init_renderer(struct wlr_drm_renderer *renderer,
|
||||||
|
|
|
@ -153,12 +153,12 @@ struct wlr_output_state {
|
||||||
|
|
||||||
bool wlr_drm_check_features(struct wlr_backend_state *drm);
|
bool wlr_drm_check_features(struct wlr_backend_state *drm);
|
||||||
bool wlr_drm_resources_init(struct wlr_backend_state *drm);
|
bool wlr_drm_resources_init(struct wlr_backend_state *drm);
|
||||||
|
void wlr_drm_resources_free(struct wlr_backend_state *drm);
|
||||||
void wlr_drm_output_cleanup(struct wlr_output_state *output, bool restore);
|
void wlr_drm_output_cleanup(struct wlr_output_state *output, bool restore);
|
||||||
|
|
||||||
void wlr_drm_scan_connectors(struct wlr_backend_state *state);
|
void wlr_drm_scan_connectors(struct wlr_backend_state *state);
|
||||||
int wlr_drm_event(int fd, uint32_t mask, void *data);
|
int wlr_drm_event(int fd, uint32_t mask, void *data);
|
||||||
|
|
||||||
void wlr_drm_output_start_renderer(struct wlr_output_state *output);
|
void wlr_drm_output_start_renderer(struct wlr_output_state *output);
|
||||||
void wlr_drm_output_pause_renderer(struct wlr_output_state *output);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue