More cleanups

This commit is contained in:
Scott Anderson 2017-08-05 19:49:34 +12:00
parent dd7a349295
commit 2f8b5c4448
4 changed files with 63 additions and 113 deletions

View File

@ -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);
}
} }
} }

View File

@ -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;
glViewport(0, 0, output->width, output->height);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
if (!eglSwapBuffers(renderer->egl.display, plane->egl)) {
return;
}
struct gbm_bo *bo = gbm_surface_lock_front_buffer(plane->gbm);
if (!bo) { if (!bo) {
return; // 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);
glClear(GL_COLOR_BUFFER_BIT);
wlr_drm_plane_swap_buffers(renderer, plane);
bo = plane->back;
} }
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,

View File

@ -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

View File

@ -9,7 +9,7 @@
#include <wayland-server-protocol.h> #include <wayland-server-protocol.h>
#include <wlr/backend.h> #include <wlr/backend.h>
#include <wlr/backend/session.h> #include <wlr/backend/session.h>
#include <wlr/backend/multi.h> #include <wlr/backend/multi.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_input_device.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>