From 610b0493ac4a3bbde44378adf855c7202b1e59c4 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 30 Sep 2017 19:03:34 +1300 Subject: Rename files to remove pointless drm prefix --- include/backend/drm/drm.h | 186 +++++++++++++++++++++++++++++++++++++++ include/backend/drm/properties.h | 67 ++++++++++++++ include/backend/drm/util.h | 39 ++++++++ 3 files changed, 292 insertions(+) create mode 100644 include/backend/drm/drm.h create mode 100644 include/backend/drm/properties.h create mode 100644 include/backend/drm/util.h (limited to 'include/backend/drm') diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h new file mode 100644 index 00000000..43838495 --- /dev/null +++ b/include/backend/drm/drm.h @@ -0,0 +1,186 @@ +#ifndef BACKEND_DRM_DRM_H +#define BACKEND_DRM_DRM_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "properties.h" + +struct wlr_drm_plane { + uint32_t type; + uint32_t id; + + uint32_t possible_crtcs; + + uint32_t width, height; + + struct gbm_surface *gbm; + EGLSurface egl; + + struct gbm_bo *front; + struct gbm_bo *back; + + // Only used by cursor + float matrix[16]; + struct wlr_renderer *wlr_rend; + struct wlr_texture *wlr_tex; + struct gbm_bo *cursor_bo; + + union wlr_drm_plane_props props; +}; + +struct wlr_drm_crtc { + uint32_t id; + uint32_t mode_id; // atomic modesetting only + drmModeAtomicReq *atomic; + + union { + struct { + struct wlr_drm_plane *overlay; + struct wlr_drm_plane *primary; + struct wlr_drm_plane *cursor; + }; + struct wlr_drm_plane *planes[3]; + }; + + union wlr_drm_crtc_props props; + + struct wl_list connectors; +}; + +struct wlr_drm_connector { + struct wlr_output *base; + uint32_t id; + struct wlr_drm_crtc *crtc; + + union wlr_drm_connector_props props; + + struct wl_list link; +}; + +struct wlr_drm_renderer { + int fd; + struct gbm_device *gbm; + struct wlr_egl egl; +}; + +bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd); +void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer); + +struct wlr_drm_interface; + +struct wlr_drm_backend { + struct wlr_backend backend; + + const struct wlr_drm_interface *iface; + + int fd; + + size_t num_crtcs; + struct wlr_drm_crtc *crtcs; + size_t num_planes; + struct wlr_drm_plane *planes; + + union { + struct { + size_t num_overlay_planes; + size_t num_primary_planes; + size_t num_cursor_planes; + }; + size_t num_type_planes[3]; + }; + + union { + struct { + struct wlr_drm_plane *overlay_planes; + struct wlr_drm_plane *primary_planes; + struct wlr_drm_plane *cursor_planes; + }; + struct wlr_drm_plane *type_planes[3]; + }; + + struct wl_display *display; + struct wl_event_source *drm_event; + + struct wl_listener session_signal; + struct wl_listener drm_invalidated; + + list_t *outputs; + + struct wlr_drm_renderer renderer; + struct wlr_session *session; +}; + +enum wlr_drm_output_state { + WLR_DRM_OUTPUT_DISCONNECTED, + WLR_DRM_OUTPUT_NEEDS_MODESET, + WLR_DRM_OUTPUT_CLEANUP, + WLR_DRM_OUTPUT_CONNECTED, +}; + +struct wlr_drm_output_mode { + struct wlr_output_mode wlr_mode; + drmModeModeInfo mode; +}; + +struct wlr_drm_output { + struct wlr_output output; + + enum wlr_drm_output_state state; + uint32_t connector; + + struct wlr_drm_crtc *crtc; + uint32_t possible_crtc; + + union wlr_drm_connector_props props; + + uint32_t width; + uint32_t height; + + drmModeCrtc *old_crtc; + + struct wlr_drm_renderer *renderer; + + bool pageflip_pending; + struct wl_event_source *retry_pageflip; +}; + +// Used to provide atomic or legacy DRM functions +struct wlr_drm_interface { + // Enable or disable DPMS for output + void (*conn_enable)(struct wlr_drm_backend *backend, + struct wlr_drm_output *output, bool enable); + // Pageflip on crtc. If mode is non-NULL perform a full modeset using it. + bool (*crtc_pageflip)(struct wlr_drm_backend *backend, + struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, + uint32_t fb_id, drmModeModeInfo *mode); + // Enable the cursor buffer on crtc. Set bo to NULL to disable + bool (*crtc_set_cursor)(struct wlr_drm_backend *backend, + struct wlr_drm_crtc *crtc, struct gbm_bo *bo); + // Move the cursor on crtc + bool (*crtc_move_cursor)(struct wlr_drm_backend *backend, + struct wlr_drm_crtc *crtc, int x, int y); +}; + +bool wlr_drm_check_features(struct wlr_drm_backend *drm); +bool wlr_drm_resources_init(struct wlr_drm_backend *drm); +void wlr_drm_resources_free(struct wlr_drm_backend *drm); +void wlr_drm_restore_outputs(struct wlr_drm_backend *drm); +void wlr_drm_output_cleanup(struct wlr_drm_output *output); +void wlr_drm_scan_connectors(struct wlr_drm_backend *state); +int wlr_drm_event(int fd, uint32_t mask, void *data); + +void wlr_drm_output_start_renderer(struct wlr_drm_output *output); + +#endif diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h new file mode 100644 index 00000000..7de386ea --- /dev/null +++ b/include/backend/drm/properties.h @@ -0,0 +1,67 @@ +#ifndef BACKEND_DRM_PROPERTIES_H +#define BACKEND_DRM_PROPERTIES_H + +#include +#include + +/* + * These types contain the property ids for several DRM objects. + * See https://01.org/linuxgraphics/gfx-docs/drm/gpu/drm-kms.html#kms-properties + * for more details. + */ + +union wlr_drm_connector_props { + struct { + uint32_t edid; + uint32_t dpms; + + // atomic-modesetting only + + uint32_t crtc_id; + }; + uint32_t props[3]; +}; + +union wlr_drm_crtc_props { + struct { + // Neither of these are guranteed to exist + uint32_t rotation; + uint32_t scaling_mode; + + // atomic-modesetting only + + uint32_t active; + uint32_t mode_id; + }; + uint32_t props[4]; +}; + +union wlr_drm_plane_props { + struct { + uint32_t type; + uint32_t rotation; // Not guranteed to exist + + // atomic-modesetting only + + uint32_t src_x; + uint32_t src_y; + uint32_t src_w; + uint32_t src_h; + uint32_t crtc_x; + uint32_t crtc_y; + uint32_t crtc_w; + uint32_t crtc_h; + uint32_t fb_id; + uint32_t crtc_id; + }; + uint32_t props[12]; +}; + +bool wlr_drm_get_connector_props(int fd, uint32_t id, union wlr_drm_connector_props *out); +bool wlr_drm_get_crtc_props(int fd, uint32_t id, union wlr_drm_crtc_props *out); +bool wlr_drm_get_plane_props(int fd, uint32_t id, union wlr_drm_plane_props *out); + +bool wlr_drm_get_prop(int fd, uint32_t obj, uint32_t prop, uint64_t *ret); +void *wlr_drm_get_prop_blob(int fd, uint32_t obj, uint32_t prop, size_t *ret_len); + +#endif diff --git a/include/backend/drm/util.h b/include/backend/drm/util.h new file mode 100644 index 00000000..6818b4db --- /dev/null +++ b/include/backend/drm/util.h @@ -0,0 +1,39 @@ +#ifndef BACKEND_DRM_UTIL_H +#define BACKEND_DRM_UTIL_H + +#include +#include +#include +#include + +// Calculates a more accurate refresh rate (mHz) than what mode itself provides +int32_t calculate_refresh_rate(drmModeModeInfo *mode); +// Populates the make/model/phys_{width,height} of output from the edid data +void parse_edid(struct wlr_output *restrict output, size_t len, const uint8_t *data); +// Returns the string representation of a DRM output type +const char *conn_get_name(uint32_t type_id); +// Returns the DRM framebuffer id for a gbm_bo +uint32_t get_fb_for_bo(struct gbm_bo *bo); + +// Part of match_obj +enum { + UNMATCHED = (uint32_t)-1, + SKIP = (uint32_t)-2, +}; + +/* + * Tries to match some DRM objects with some other DRM resource. + * e.g. Match CRTCs with Encoders, CRTCs with Planes. + * + * objs contains a bit array which resources it can be matched with. + * e.g. Bit 0 set means can be matched with res[0] + * + * res contains an index of which objs it is matched with or UNMATCHED. + * + * This solution is left in out. + * Returns the total number of matched solutions. + */ +size_t match_obj(size_t num_objs, const uint32_t objs[static restrict num_objs], + size_t num_res, const uint32_t res[static restrict num_res], + uint32_t out[static restrict num_res]); +#endif -- cgit v1.2.3 From d0708b1a3a3fb9fd3a073d6c5406b26e8bf617e9 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 30 Sep 2017 19:11:41 +1300 Subject: Split DRM internal interface to its own header --- backend/drm/drm.c | 4 +--- backend/drm/iface_atomic.c | 1 + backend/drm/iface_legacy.c | 1 + include/backend/drm/drm.h | 18 +----------------- include/backend/drm/iface.h | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 include/backend/drm/iface.h (limited to 'include/backend/drm') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index cba41023..40a6f37b 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -21,12 +21,10 @@ #include #include #include "backend/drm/drm.h" +#include "backend/drm/iface.h" #include "backend/drm/util.h" bool wlr_drm_check_features(struct wlr_drm_backend *backend) { - extern const struct wlr_drm_interface iface_legacy; - extern const struct wlr_drm_interface iface_atomic; - if (drmSetClientCap(backend->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { wlr_log(L_ERROR, "DRM universal planes unsupported"); return false; diff --git a/backend/drm/iface_atomic.c b/backend/drm/iface_atomic.c index 5bb2da9b..75a3c33a 100644 --- a/backend/drm/iface_atomic.c +++ b/backend/drm/iface_atomic.c @@ -3,6 +3,7 @@ #include #include #include "backend/drm/drm.h" +#include "backend/drm/iface.h" #include "backend/drm/util.h" struct atomic { diff --git a/backend/drm/iface_legacy.c b/backend/drm/iface_legacy.c index 856e9060..110b38b5 100644 --- a/backend/drm/iface_legacy.c +++ b/backend/drm/iface_legacy.c @@ -3,6 +3,7 @@ #include #include #include "backend/drm/drm.h" +#include "backend/drm/iface.h" #include "backend/drm/util.h" static bool legacy_crtc_pageflip(struct wlr_drm_backend *backend, diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 43838495..c57493f3 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -15,6 +15,7 @@ #include #include +#include "iface.h" #include "properties.h" struct wlr_drm_plane { @@ -156,23 +157,6 @@ struct wlr_drm_output { struct wl_event_source *retry_pageflip; }; -// Used to provide atomic or legacy DRM functions -struct wlr_drm_interface { - // Enable or disable DPMS for output - void (*conn_enable)(struct wlr_drm_backend *backend, - struct wlr_drm_output *output, bool enable); - // Pageflip on crtc. If mode is non-NULL perform a full modeset using it. - bool (*crtc_pageflip)(struct wlr_drm_backend *backend, - struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, - uint32_t fb_id, drmModeModeInfo *mode); - // Enable the cursor buffer on crtc. Set bo to NULL to disable - bool (*crtc_set_cursor)(struct wlr_drm_backend *backend, - struct wlr_drm_crtc *crtc, struct gbm_bo *bo); - // Move the cursor on crtc - bool (*crtc_move_cursor)(struct wlr_drm_backend *backend, - struct wlr_drm_crtc *crtc, int x, int y); -}; - bool wlr_drm_check_features(struct wlr_drm_backend *drm); bool wlr_drm_resources_init(struct wlr_drm_backend *drm); void wlr_drm_resources_free(struct wlr_drm_backend *drm); diff --git a/include/backend/drm/iface.h b/include/backend/drm/iface.h new file mode 100644 index 00000000..cf77f4d4 --- /dev/null +++ b/include/backend/drm/iface.h @@ -0,0 +1,35 @@ +#ifndef BACKEND_DRM_IFACE_H +#define BACKEND_DRM_IFACE_H + +#include +#include + +#include +#include +#include + +struct wlr_drm_backend; +struct wlr_drm_output; +struct wlr_drm_crtc; + +// Used to provide atomic or legacy DRM functions +struct wlr_drm_interface { + // Enable or disable DPMS for output + void (*conn_enable)(struct wlr_drm_backend *backend, + struct wlr_drm_output *output, bool enable); + // Pageflip on crtc. If mode is non-NULL perform a full modeset using it. + bool (*crtc_pageflip)(struct wlr_drm_backend *backend, + struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, + uint32_t fb_id, drmModeModeInfo *mode); + // Enable the cursor buffer on crtc. Set bo to NULL to disable + bool (*crtc_set_cursor)(struct wlr_drm_backend *backend, + struct wlr_drm_crtc *crtc, struct gbm_bo *bo); + // Move the cursor on crtc + bool (*crtc_move_cursor)(struct wlr_drm_backend *backend, + struct wlr_drm_crtc *crtc, int x, int y); +}; + +extern const struct wlr_drm_interface iface_atomic; +extern const struct wlr_drm_interface iface_legacy; + +#endif -- cgit v1.2.3 From 096249a2a1dc604b062a6fef6c4ca56065724d79 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 30 Sep 2017 20:52:58 +1300 Subject: Split DRM rendering to its own file --- backend/drm/backend.c | 2 +- backend/drm/drm.c | 161 +++++------------------------------------ backend/drm/iface_atomic.c | 8 +- backend/drm/iface_legacy.c | 2 +- backend/drm/renderer.c | 126 ++++++++++++++++++++++++++++++++ backend/meson.build | 1 + include/backend/drm/drm.h | 20 +---- include/backend/drm/renderer.h | 47 ++++++++++++ 8 files changed, 202 insertions(+), 165 deletions(-) create mode 100644 backend/drm/renderer.c create mode 100644 include/backend/drm/renderer.h (limited to 'include/backend/drm') diff --git a/backend/drm/backend.c b/backend/drm/backend.c index e046cea6..95c86bb1 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -33,7 +33,7 @@ static void wlr_drm_backend_destroy(struct wlr_backend *_backend) { wlr_output_destroy(&output->output); } - wlr_drm_renderer_free(&backend->renderer); + wlr_drm_renderer_finish(&backend->renderer); wlr_drm_resources_free(backend); wlr_session_close_file(backend->session, backend->fd); wl_event_source_remove(backend->drm_event); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 40a6f37b..05a050e6 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -173,121 +173,9 @@ void wlr_drm_resources_free(struct wlr_drm_backend *backend) { free(backend->planes); } -bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) { - renderer->gbm = gbm_create_device(fd); - if (!renderer->gbm) { - wlr_log(L_ERROR, "Failed to create GBM device: %s", strerror(errno)); - return false; - } - - if (!wlr_egl_init(&renderer->egl, EGL_PLATFORM_GBM_MESA, - GBM_FORMAT_ARGB8888, renderer->gbm)) { - gbm_device_destroy(renderer->gbm); - return false; - } - - renderer->fd = fd; - return true; -} - -void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer) { - if (!renderer) { - return; - } - - wlr_egl_free(&renderer->egl); - gbm_device_destroy(renderer->gbm); -} - -static bool wlr_drm_plane_renderer_init(struct wlr_drm_renderer *renderer, - struct wlr_drm_plane *plane, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { - if (plane->width == width && plane->height == height) { - return true; - } - - plane->width = width; - plane->height = height; - - plane->gbm = gbm_surface_create(renderer->gbm, width, height, - format, GBM_BO_USE_RENDERING | flags); - if (!plane->gbm) { - wlr_log_errno(L_ERROR, "Failed to create GBM surface for plane"); - return false; - } - - plane->egl = wlr_egl_create_surface(&renderer->egl, plane->gbm); - if (plane->egl == EGL_NO_SURFACE) { - wlr_log(L_ERROR, "Failed to create EGL surface for plane"); - return false; - } - - return true; -} - -static void wlr_drm_plane_renderer_free(struct wlr_drm_renderer *renderer, - struct wlr_drm_plane *plane) { - if (!renderer || !plane) { - return; - } - - eglMakeCurrent(renderer->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (plane->front) { - gbm_surface_release_buffer(plane->gbm, plane->front); - } - if (plane->back) { - gbm_surface_release_buffer(plane->gbm, plane->back); - } - - if (plane->egl) { - eglDestroySurface(renderer->egl.display, plane->egl); - } - if (plane->gbm) { - gbm_surface_destroy(plane->gbm); - } - - if (plane->wlr_tex) { - wlr_texture_destroy(plane->wlr_tex); - } - if (plane->wlr_rend) { - wlr_renderer_destroy(plane->wlr_rend); - } - if (plane->cursor_bo) { - gbm_bo_destroy(plane->cursor_bo); - } - - plane->width = 0; - plane->height = 0; - plane->egl = EGL_NO_SURFACE; - plane->gbm = NULL; - plane->front = NULL; - plane->back = NULL; - plane->wlr_rend = NULL; - plane->wlr_tex = NULL; - plane->cursor_bo = NULL; -} - -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 *_output) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - wlr_drm_plane_make_current(output->renderer, output->crtc->primary); + wlr_drm_surface_make_current(output->renderer, &output->crtc->primary->surf); } static void wlr_drm_output_swap_buffers(struct wlr_output *_output) { @@ -298,9 +186,8 @@ static void wlr_drm_output_swap_buffers(struct wlr_output *_output) { struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->primary; - wlr_drm_plane_swap_buffers(renderer, plane); - - uint32_t fb_id = get_fb_for_bo(plane->back); + struct gbm_bo *bo = wlr_drm_surface_swap_buffers(renderer, &plane->surf); + uint32_t fb_id = get_fb_for_bo(bo); if (backend->iface->crtc_pageflip(backend, output, crtc, fb_id, NULL)) { output->pageflip_pending = true; @@ -338,17 +225,7 @@ void wlr_drm_output_start_renderer(struct wlr_drm_output *output) { struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->primary; - struct gbm_bo *bo = plane->front; - if (!bo) { - // 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; - } + struct gbm_bo *bo = wlr_drm_surface_get_front(renderer, &plane->surf); struct wlr_drm_output_mode *_mode = (struct wlr_drm_output_mode *)output->output.current_mode; @@ -415,8 +292,10 @@ static void realloc_planes(struct wlr_drm_backend *backend, const uint32_t *crtc struct wlr_drm_plane *new = &backend->type_planes[type][crtc_res[i]]; if (*old != new) { - wlr_drm_plane_renderer_free(&backend->renderer, *old); - wlr_drm_plane_renderer_free(&backend->renderer, new); + if (*old) { + wlr_drm_surface_finish(&backend->renderer, &(*old)->surf); + } + wlr_drm_surface_finish(&backend->renderer, &new->surf); *old = new; } } @@ -547,7 +426,7 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, continue; } - if (!wlr_drm_plane_renderer_init(&backend->renderer, crtc->primary, + if (!wlr_drm_surface_init(&backend->renderer, &crtc->primary->surf, mode->width, mode->height, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT)) { wlr_log(L_ERROR, "Failed to initalise renderer for plane"); @@ -598,7 +477,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, crtc->cursor = plane; } - if (!plane->gbm) { + if (!plane->surf.gbm) { int ret; uint64_t w, h; ret = drmGetCap(backend->fd, DRM_CAP_CURSOR_WIDTH, &w); @@ -611,7 +490,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, return false; } - if (!wlr_drm_plane_renderer_init(renderer, plane, w, h, GBM_FORMAT_ARGB8888, 0)) { + if (!wlr_drm_surface_init(renderer, &plane->surf, w, h, GBM_FORMAT_ARGB8888, 0)) { wlr_log(L_ERROR, "Cannot allocate cursor resources"); return false; } @@ -625,7 +504,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, // OpenGL will read the pixels out upside down, // so we need to flip the image vertically - wlr_matrix_texture(plane->matrix, plane->width, plane->height, + wlr_matrix_texture(plane->matrix, plane->surf.width, plane->surf.height, output->output.transform ^ WL_OUTPUT_TRANSFORM_FLIPPED_180); // TODO the image needs to be rotated depending on the output rotation @@ -653,12 +532,12 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, return false; } - wlr_drm_plane_make_current(renderer, plane); + wlr_drm_surface_make_current(renderer, &plane->surf); wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, stride, width, height, buf); - glViewport(0, 0, plane->width, plane->height); + glViewport(0, 0, plane->surf.width, plane->surf.height); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -668,10 +547,10 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, glFinish(); glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, bo_stride); - glReadPixels(0, 0, plane->width, plane->height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bo_data); + glReadPixels(0, 0, plane->surf.width, plane->surf.height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bo_data); glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); - wlr_drm_plane_swap_buffers(renderer, plane); + wlr_drm_surface_swap_buffers(renderer, &plane->surf); gbm_bo_unmap(bo, bo_data); @@ -914,9 +793,9 @@ static void page_flip_handler(int fd, unsigned seq, } struct wlr_drm_plane *plane = output->crtc->primary; - if (plane->front) { - gbm_surface_release_buffer(plane->gbm, plane->front); - plane->front = NULL; + if (plane->surf.front) { + gbm_surface_release_buffer(plane->surf.gbm, plane->surf.front); + plane->surf.front = NULL; } if (backend->session->active) { @@ -987,7 +866,7 @@ void wlr_drm_output_cleanup(struct wlr_drm_output *output) { case WLR_DRM_OUTPUT_CLEANUP:; struct wlr_drm_crtc *crtc = output->crtc; for (int i = 0; i < 3; ++i) { - wlr_drm_plane_renderer_free(renderer, crtc->planes[i]); + wlr_drm_surface_finish(renderer, &crtc->planes[i]->surf); if (crtc->planes[i] && crtc->planes[i]->id == 0) { free(crtc->planes[i]); crtc->planes[i] = NULL; diff --git a/backend/drm/iface_atomic.c b/backend/drm/iface_atomic.c index 75a3c33a..ce5de091 100644 --- a/backend/drm/iface_atomic.c +++ b/backend/drm/iface_atomic.c @@ -84,10 +84,10 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_plane *plane, // The src_* properties are in 16.16 fixed point atomic_add(atom, id, props->src_x, 0); atomic_add(atom, id, props->src_y, 0); - atomic_add(atom, id, props->src_w, plane->width << 16); - atomic_add(atom, id, props->src_h, plane->height << 16); - atomic_add(atom, id, props->crtc_w, plane->width); - atomic_add(atom, id, props->crtc_h, plane->height); + atomic_add(atom, id, props->src_w, plane->surf.width << 16); + atomic_add(atom, id, props->src_h, plane->surf.height << 16); + atomic_add(atom, id, props->crtc_w, plane->surf.width); + atomic_add(atom, id, props->crtc_h, plane->surf.height); atomic_add(atom, id, props->fb_id, fb_id); atomic_add(atom, id, props->crtc_id, crtc_id); if (set_crtc_xy) { diff --git a/backend/drm/iface_legacy.c b/backend/drm/iface_legacy.c index 110b38b5..e320af93 100644 --- a/backend/drm/iface_legacy.c +++ b/backend/drm/iface_legacy.c @@ -45,7 +45,7 @@ bool legacy_crtc_set_cursor(struct wlr_drm_backend *backend, struct wlr_drm_plane *plane = crtc->cursor; if (drmModeSetCursor(backend->fd, crtc->id, gbm_bo_get_handle(bo).u32, - plane->width, plane->height)) { + plane->surf.width, plane->surf.height)) { wlr_log_errno(L_ERROR, "Failed to set hardware cursor"); return false; } diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c new file mode 100644 index 00000000..8afc6dca --- /dev/null +++ b/backend/drm/renderer.c @@ -0,0 +1,126 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include "backend/drm/drm.h" + +bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) { + renderer->gbm = gbm_create_device(fd); + if (!renderer->gbm) { + wlr_log(L_ERROR, "Failed to create GBM device"); + return false; + } + + if (!wlr_egl_init(&renderer->egl, EGL_PLATFORM_GBM_MESA, + GBM_FORMAT_ARGB8888, renderer->gbm)) { + gbm_device_destroy(renderer->gbm); + return false; + } + + renderer->fd = fd; + return true; +} + +void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer) { + if (!renderer) { + return; + } + + wlr_egl_free(&renderer->egl); + gbm_device_destroy(renderer->gbm); +} + +bool wlr_drm_surface_init(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf, uint32_t width, uint32_t height, + uint32_t format, uint32_t flags) { + if (surf->width == width && surf->height == height) { + return true; + } + + surf->width = width; + surf->height = height; + + surf->gbm = gbm_surface_create(renderer->gbm, width, height, + format, GBM_BO_USE_RENDERING | flags); + if (!surf->gbm) { + wlr_log_errno(L_ERROR, "Failed to create GBM surface"); + goto error_zero; + } + + surf->egl = wlr_egl_create_surface(&renderer->egl, surf->gbm); + if (surf->egl == EGL_NO_SURFACE) { + wlr_log(L_ERROR, "Failed to create EGL surface"); + goto error_gbm; + } + + return true; + +error_gbm: + gbm_surface_destroy(surf->gbm); +error_zero: + memset(surf, 0, sizeof(*surf)); + return false; +} + +void wlr_drm_surface_finish(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf) { + if (!renderer || !surf || !surf->gbm) { + return; + } + + eglMakeCurrent(renderer->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + if (surf->front) { + gbm_surface_release_buffer(surf->gbm, surf->front); + } + if (surf->back) { + gbm_surface_release_buffer(surf->gbm, surf->back); + } + + if (surf->egl) { + eglDestroySurface(renderer->egl.display, surf->egl); + } + if (surf->gbm) { + gbm_surface_destroy(surf->gbm); + } + + memset(surf, 0, sizeof(*surf)); +} + +void wlr_drm_surface_make_current(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf) { + eglMakeCurrent(renderer->egl.display, surf->egl, surf->egl, + renderer->egl.context); +} + +struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf) { + if (surf->front) { + gbm_surface_release_buffer(surf->gbm, surf->front); + } + + eglSwapBuffers(renderer->egl.display, surf->egl); + + surf->front = surf->back; + surf->back = gbm_surface_lock_front_buffer(surf->gbm); + return surf->back; +} + +struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf) { + if (surf->front) { + return surf->front; + } + + wlr_drm_surface_make_current(renderer, surf); + glViewport(0, 0, surf->width, surf->height); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + return wlr_drm_surface_swap_buffers(renderer, surf); +} diff --git a/backend/meson.build b/backend/meson.build index 630bc284..caf2c8b0 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -8,6 +8,7 @@ backend_files = files( 'drm/iface_atomic.c', 'drm/iface_legacy.c', 'drm/properties.c', + 'drm/renderer.c', 'drm/util.c', 'libinput/backend.c', 'libinput/events.c', diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index c57493f3..b13cb5e7 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -17,6 +17,7 @@ #include "iface.h" #include "properties.h" +#include "renderer.h" struct wlr_drm_plane { uint32_t type; @@ -24,13 +25,7 @@ struct wlr_drm_plane { uint32_t possible_crtcs; - uint32_t width, height; - - struct gbm_surface *gbm; - EGLSurface egl; - - struct gbm_bo *front; - struct gbm_bo *back; + struct wlr_drm_surface surf; // Only used by cursor float matrix[16]; @@ -70,17 +65,6 @@ struct wlr_drm_connector { struct wl_list link; }; -struct wlr_drm_renderer { - int fd; - struct gbm_device *gbm; - struct wlr_egl egl; -}; - -bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd); -void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer); - -struct wlr_drm_interface; - struct wlr_drm_backend { struct wlr_backend backend; diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h new file mode 100644 index 00000000..bbcf4f0c --- /dev/null +++ b/include/backend/drm/renderer.h @@ -0,0 +1,47 @@ +#ifndef BACKEND_DRM_RENDERER_H +#define BACKEND_DRM_RENDERER_H + +#include +#include + +#include +#include + +struct wlr_drm_renderer { + int fd; + struct gbm_device *gbm; + struct wlr_egl egl; +}; + +struct wlr_drm_surface { + uint32_t width; + uint32_t height; + + struct gbm_surface *gbm; + EGLSurface egl; + + struct gbm_bo *front; + struct gbm_bo *back; +}; + +bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd); + +void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer); + +bool wlr_drm_surface_init(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf, uint32_t width, uint32_t height, + uint32_t format, uint32_t flags); + +void wlr_drm_surface_finish(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf); + +void wlr_drm_surface_make_current(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf); + +struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf); + +struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_renderer *renderer, + struct wlr_drm_surface *surf); + +#endif -- cgit v1.2.3 From ec5b95e08f7549fc3628d9790d62f22d8b975300 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 30 Sep 2017 22:01:59 +1300 Subject: Add pointer to backend from DRM outputs --- backend/drm/drm.c | 38 ++++++++++++++------------------------ include/backend/drm/drm.h | 3 +-- 2 files changed, 15 insertions(+), 26 deletions(-) (limited to 'include/backend/drm') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 05a050e6..96feba15 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -175,14 +175,13 @@ void wlr_drm_resources_free(struct wlr_drm_backend *backend) { static void wlr_drm_output_make_current(struct wlr_output *_output) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - wlr_drm_surface_make_current(output->renderer, &output->crtc->primary->surf); + wlr_drm_surface_make_current(&output->drm->renderer, &output->crtc->primary->surf); } static void wlr_drm_output_swap_buffers(struct wlr_output *_output) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = - wl_container_of(output->renderer, backend, renderer); - struct wlr_drm_renderer *renderer = output->renderer; + struct wlr_drm_backend *backend = output->drm; + struct wlr_drm_renderer *renderer = &backend->renderer; struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->primary; @@ -200,8 +199,7 @@ static void wlr_drm_output_swap_buffers(struct wlr_output *_output) { static void wlr_drm_output_set_gamma(struct wlr_output *_output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = - wl_container_of(output->renderer, backend, renderer); + struct wlr_drm_backend *backend = output->drm; drmModeCrtcSetGamma(backend->fd, output->crtc->id, size, r, g, b); } @@ -219,9 +217,8 @@ void wlr_drm_output_start_renderer(struct wlr_drm_output *output) { return; } - struct wlr_drm_backend *backend = - wl_container_of(output->renderer, backend, renderer); - struct wlr_drm_renderer *renderer = output->renderer; + struct wlr_drm_backend *backend = output->drm; + struct wlr_drm_renderer *renderer = &backend->renderer; struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->primary; @@ -240,8 +237,7 @@ void wlr_drm_output_start_renderer(struct wlr_drm_output *output) { static void wlr_drm_output_enable(struct wlr_output *_output, bool enable) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = - wl_container_of(output->renderer, backend, renderer); + struct wlr_drm_backend *backend = output->drm; if (output->state != WLR_DRM_OUTPUT_CONNECTED) { return; } @@ -367,8 +363,7 @@ static void realloc_crtcs(struct wlr_drm_backend *backend, static bool wlr_drm_output_set_mode(struct wlr_output *_output, struct wlr_output_mode *mode) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend - = wl_container_of(output->renderer, backend, renderer); + struct wlr_drm_backend *backend = output->drm; wlr_log(L_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", output->output.name, mode->width, mode->height, mode->refresh); @@ -457,9 +452,8 @@ static void wlr_drm_output_transform(struct wlr_output *output, static bool wlr_drm_output_set_cursor(struct wlr_output *_output, const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend - = wl_container_of(output->renderer, backend, renderer); - struct wlr_drm_renderer *renderer = output->renderer; + struct wlr_drm_backend *backend = output->drm; + struct wlr_drm_renderer *renderer = &backend->renderer; struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->cursor; @@ -560,8 +554,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, static bool wlr_drm_output_move_cursor(struct wlr_output *_output, int x, int y) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = - wl_container_of(output->renderer, backend, renderer); + struct wlr_drm_backend *backend = output->drm; int width, height, tmp; wlr_output_effective_resolution(_output, &width, &height); @@ -678,7 +671,6 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { output); - output->renderer = &backend->renderer; output->state = WLR_DRM_OUTPUT_DISCONNECTED; output->connector = conn->connector_id; @@ -784,8 +776,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { static void page_flip_handler(int fd, unsigned seq, unsigned tv_sec, unsigned tv_usec, void *user) { struct wlr_drm_output *output = user; - struct wlr_drm_backend *backend = - wl_container_of(output->renderer, backend, renderer); + struct wlr_drm_backend *backend = output->drm; output->pageflip_pending = false; if (output->state != WLR_DRM_OUTPUT_CONNECTED) { @@ -857,9 +848,8 @@ void wlr_drm_output_cleanup(struct wlr_drm_output *output) { return; } - struct wlr_drm_renderer *renderer = output->renderer; - struct wlr_drm_backend *backend = - wl_container_of(renderer, backend, renderer); + struct wlr_drm_backend *backend = output->drm; + struct wlr_drm_renderer *renderer = &backend->renderer; switch (output->state) { case WLR_DRM_OUTPUT_CONNECTED: diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index b13cb5e7..6f1abc00 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -121,6 +121,7 @@ struct wlr_drm_output_mode { struct wlr_drm_output { struct wlr_output output; + struct wlr_drm_backend *drm; enum wlr_drm_output_state state; uint32_t connector; @@ -135,8 +136,6 @@ struct wlr_drm_output { drmModeCrtc *old_crtc; - struct wlr_drm_renderer *renderer; - bool pageflip_pending; struct wl_event_source *retry_pageflip; }; -- cgit v1.2.3 From 22e77d919570c0a8d4a84878c377db8fa9a0edfb Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 30 Sep 2017 22:22:26 +1300 Subject: Rename backend to drm --- backend/drm/backend.c | 97 ++++++++-------- backend/drm/drm.c | 262 ++++++++++++++++++++++---------------------- backend/drm/iface_atomic.c | 28 ++--- backend/drm/iface_legacy.c | 20 ++-- include/backend/drm/iface.h | 18 +-- 5 files changed, 210 insertions(+), 215 deletions(-) (limited to 'include/backend/drm') diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 95c86bb1..f634eee6 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -14,36 +14,37 @@ #include #include "backend/drm/drm.h" -static bool wlr_drm_backend_start(struct wlr_backend *_backend) { - struct wlr_drm_backend *backend = (struct wlr_drm_backend *)_backend; - wlr_drm_scan_connectors(backend); +static bool wlr_drm_backend_start(struct wlr_backend *backend) { + struct wlr_drm_backend *drm = (struct wlr_drm_backend *)backend; + wlr_drm_scan_connectors(drm); return true; } -static void wlr_drm_backend_destroy(struct wlr_backend *_backend) { - if (!_backend) { +static void wlr_drm_backend_destroy(struct wlr_backend *backend) { + if (!backend) { return; } - struct wlr_drm_backend *backend = (struct wlr_drm_backend *)_backend; - wlr_drm_restore_outputs(backend); + struct wlr_drm_backend *drm = (struct wlr_drm_backend *)backend; + + wlr_drm_restore_outputs(drm); - for (size_t i = 0; backend->outputs && i < backend->outputs->length; ++i) { - struct wlr_drm_output *output = backend->outputs->items[i]; + for (size_t i = 0; drm->outputs && i < drm->outputs->length; ++i) { + struct wlr_drm_output *output = drm->outputs->items[i]; wlr_output_destroy(&output->output); } - wlr_drm_renderer_finish(&backend->renderer); - wlr_drm_resources_free(backend); - wlr_session_close_file(backend->session, backend->fd); - wl_event_source_remove(backend->drm_event); - list_free(backend->outputs); - free(backend); + wlr_drm_renderer_finish(&drm->renderer); + wlr_drm_resources_free(drm); + wlr_session_close_file(drm->session, drm->fd); + wl_event_source_remove(drm->drm_event); + list_free(drm->outputs); + free(drm); } static struct wlr_egl *wlr_drm_backend_get_egl(struct wlr_backend *_backend) { - struct wlr_drm_backend *backend = (struct wlr_drm_backend *)_backend; - return &backend->renderer.egl; + struct wlr_drm_backend *drm = (struct wlr_drm_backend *)_backend; + return &drm->renderer.egl; } static struct wlr_backend_impl backend_impl = { @@ -57,15 +58,14 @@ bool wlr_backend_is_drm(struct wlr_backend *b) { } static void session_signal(struct wl_listener *listener, void *data) { - struct wlr_drm_backend *backend = - wl_container_of(listener, backend, session_signal); + struct wlr_drm_backend *drm = wl_container_of(listener, drm, session_signal); struct wlr_session *session = data; if (session->active) { wlr_log(L_INFO, "DRM fd resumed"); - for (size_t i = 0; i < backend->outputs->length; ++i) { - struct wlr_drm_output *output = backend->outputs->items[i]; + for (size_t i = 0; i < drm->outputs->length; ++i) { + struct wlr_drm_output *output = drm->outputs->items[i]; wlr_drm_output_start_renderer(output); if (!output->crtc) { @@ -73,7 +73,7 @@ static void session_signal(struct wl_listener *listener, void *data) { } struct wlr_drm_plane *plane = output->crtc->cursor; - backend->iface->crtc_set_cursor(backend, output->crtc, + drm->iface->crtc_set_cursor(drm, output->crtc, plane ? plane->cursor_bo : NULL); } } else { @@ -82,14 +82,13 @@ static void session_signal(struct wl_listener *listener, void *data) { } static void drm_invalidated(struct wl_listener *listener, void *data) { - struct wlr_drm_backend *backend = - wl_container_of(listener, backend, drm_invalidated); + struct wlr_drm_backend *drm = wl_container_of(listener, drm, drm_invalidated); - char *name = drmGetDeviceNameFromFd2(backend->fd); + char *name = drmGetDeviceNameFromFd2(drm->fd); wlr_log(L_DEBUG, "%s invalidated", name); free(name); - wlr_drm_scan_connectors(backend); + wlr_drm_scan_connectors(drm); } struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, @@ -102,63 +101,63 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, free(name); drmFreeVersion(version); - struct wlr_drm_backend *backend = calloc(1, sizeof(struct wlr_drm_backend)); - if (!backend) { + struct wlr_drm_backend *drm = calloc(1, sizeof(struct wlr_drm_backend)); + if (!drm) { wlr_log_errno(L_ERROR, "Allocation failed"); return NULL; } - wlr_backend_init(&backend->backend, &backend_impl); + wlr_backend_init(&drm->backend, &backend_impl); - backend->session = session; - backend->outputs = list_create(); - if (!backend->outputs) { + drm->session = session; + drm->outputs = list_create(); + if (!drm->outputs) { wlr_log(L_ERROR, "Failed to allocate list"); goto error_backend; } - backend->fd = gpu_fd; + drm->fd = gpu_fd; - backend->drm_invalidated.notify = drm_invalidated; - wlr_session_signal_add(session, gpu_fd, &backend->drm_invalidated); + drm->drm_invalidated.notify = drm_invalidated; + wlr_session_signal_add(session, gpu_fd, &drm->drm_invalidated); - backend->display = display; + drm->display = display; struct wl_event_loop *event_loop = wl_display_get_event_loop(display); - backend->drm_event = wl_event_loop_add_fd(event_loop, backend->fd, + drm->drm_event = wl_event_loop_add_fd(event_loop, drm->fd, WL_EVENT_READABLE, wlr_drm_event, NULL); - if (!backend->drm_event) { + if (!drm->drm_event) { wlr_log(L_ERROR, "Failed to create DRM event source"); goto error_fd; } - backend->session_signal.notify = session_signal; - wl_signal_add(&session->session_signal, &backend->session_signal); + drm->session_signal.notify = session_signal; + wl_signal_add(&session->session_signal, &drm->session_signal); - if (!wlr_drm_check_features(backend)) { + if (!wlr_drm_check_features(drm)) { goto error_event; } - if (!wlr_drm_resources_init(backend)) { + if (!wlr_drm_resources_init(drm)) { goto error_event; } - if (!wlr_drm_renderer_init(&backend->renderer, backend->fd)) { + if (!wlr_drm_renderer_init(&drm->renderer, drm->fd)) { wlr_log(L_ERROR, "Failed to initialize renderer"); goto error_event; } - if (!wlr_egl_bind_display(&backend->renderer.egl, display)) { + if (!wlr_egl_bind_display(&drm->renderer.egl, display)) { wlr_log(L_INFO, "Failed to bind egl/wl display: %s", egl_error()); } - return &backend->backend; + return &drm->backend; error_event: - wl_event_source_remove(backend->drm_event); + wl_event_source_remove(drm->drm_event); error_fd: - wlr_session_close_file(backend->session, backend->fd); - list_free(backend->outputs); + wlr_session_close_file(drm->session, drm->fd); + list_free(drm->outputs); error_backend: - free(backend); + free(drm); return NULL; } diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 96feba15..a50216cb 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -24,21 +24,21 @@ #include "backend/drm/iface.h" #include "backend/drm/util.h" -bool wlr_drm_check_features(struct wlr_drm_backend *backend) { - if (drmSetClientCap(backend->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { +bool wlr_drm_check_features(struct wlr_drm_backend *drm) { + if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { wlr_log(L_ERROR, "DRM universal planes unsupported"); return false; } if (getenv("WLR_DRM_NO_ATOMIC")) { wlr_log(L_DEBUG, "WLR_DRM_NO_ATOMIC set, forcing legacy DRM interface"); - backend->iface = &iface_legacy; - } else if (drmSetClientCap(backend->fd, DRM_CLIENT_CAP_ATOMIC, 1)) { + drm->iface = &iface_legacy; + } else if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_ATOMIC, 1)) { wlr_log(L_DEBUG, "Atomic modesetting unsupported, using legacy DRM interface"); - backend->iface = &iface_legacy; + drm->iface = &iface_legacy; } else { wlr_log(L_DEBUG, "Using atomic DRM interface"); - backend->iface = &iface_atomic; + drm->iface = &iface_atomic; } return true; @@ -51,8 +51,8 @@ static int cmp_plane(const void *arg1, const void *arg2) { return (int)a->type - (int)b->type; } -static bool init_planes(struct wlr_drm_backend *backend) { - drmModePlaneRes *plane_res = drmModeGetPlaneResources(backend->fd); +static bool init_planes(struct wlr_drm_backend *drm) { + drmModePlaneRes *plane_res = drmModeGetPlaneResources(drm->fd); if (!plane_res) { wlr_log_errno(L_ERROR, "Failed to get DRM plane resources"); return false; @@ -65,17 +65,17 @@ static bool init_planes(struct wlr_drm_backend *backend) { return true; } - backend->num_planes = plane_res->count_planes; - backend->planes = calloc(backend->num_planes, sizeof(*backend->planes)); - if (!backend->planes) { + drm->num_planes = plane_res->count_planes; + drm->planes = calloc(drm->num_planes, sizeof(*drm->planes)); + if (!drm->planes) { wlr_log_errno(L_ERROR, "Allocation failed"); goto error_res; } - for (size_t i = 0; i < backend->num_planes; ++i) { - struct wlr_drm_plane *p = &backend->planes[i]; + for (size_t i = 0; i < drm->num_planes; ++i) { + struct wlr_drm_plane *p = &drm->planes[i]; - drmModePlane *plane = drmModeGetPlane(backend->fd, plane_res->planes[i]); + drmModePlane *plane = drmModeGetPlane(drm->fd, plane_res->planes[i]); if (!plane) { wlr_log_errno(L_ERROR, "Failed to get DRM plane"); goto error_planes; @@ -85,44 +85,43 @@ static bool init_planes(struct wlr_drm_backend *backend) { p->possible_crtcs = plane->possible_crtcs; uint64_t type; - if (!wlr_drm_get_plane_props(backend->fd, p->id, &p->props) || - !wlr_drm_get_prop(backend->fd, p->id, p->props.type, &type)) { + if (!wlr_drm_get_plane_props(drm->fd, p->id, &p->props) || + !wlr_drm_get_prop(drm->fd, p->id, p->props.type, &type)) { drmModeFreePlane(plane); goto error_planes; } p->type = type; - backend->num_type_planes[type]++; + drm->num_type_planes[type]++; drmModeFreePlane(plane); } wlr_log(L_INFO, "(%zu overlay, %zu primary, %zu cursor)", - backend->num_overlay_planes, - backend->num_primary_planes, - backend->num_cursor_planes); + drm->num_overlay_planes, + drm->num_primary_planes, + drm->num_cursor_planes); - qsort(backend->planes, backend->num_planes, - sizeof(*backend->planes), cmp_plane); + qsort(drm->planes, drm->num_planes, sizeof(*drm->planes), cmp_plane); - backend->overlay_planes = backend->planes; - backend->primary_planes = backend->overlay_planes - + backend->num_overlay_planes; - backend->cursor_planes = backend->primary_planes - + backend->num_primary_planes; + drm->overlay_planes = drm->planes; + drm->primary_planes = drm->overlay_planes + + drm->num_overlay_planes; + drm->cursor_planes = drm->primary_planes + + drm->num_primary_planes; drmModeFreePlaneResources(plane_res); return true; error_planes: - free(backend->planes); + free(drm->planes); error_res: drmModeFreePlaneResources(plane_res); return false; } -bool wlr_drm_resources_init(struct wlr_drm_backend *backend) { - drmModeRes *res = drmModeGetResources(backend->fd); +bool wlr_drm_resources_init(struct wlr_drm_backend *drm) { + drmModeRes *res = drmModeGetResources(drm->fd); if (!res) { wlr_log_errno(L_ERROR, "Failed to get DRM resources"); return false; @@ -130,20 +129,20 @@ bool wlr_drm_resources_init(struct wlr_drm_backend *backend) { wlr_log(L_INFO, "Found %d DRM CRTCs", res->count_crtcs); - backend->num_crtcs = res->count_crtcs; - backend->crtcs = calloc(backend->num_crtcs, sizeof(backend->crtcs[0])); - if (!backend->crtcs) { + drm->num_crtcs = res->count_crtcs; + drm->crtcs = calloc(drm->num_crtcs, sizeof(drm->crtcs[0])); + if (!drm->crtcs) { wlr_log_errno(L_ERROR, "Allocation failed"); goto error_res; } - for (size_t i = 0; i < backend->num_crtcs; ++i) { - struct wlr_drm_crtc *crtc = &backend->crtcs[i]; + for (size_t i = 0; i < drm->num_crtcs; ++i) { + struct wlr_drm_crtc *crtc = &drm->crtcs[i]; crtc->id = res->crtcs[i]; - wlr_drm_get_crtc_props(backend->fd, crtc->id, &crtc->props); + wlr_drm_get_crtc_props(drm->fd, crtc->id, &crtc->props); } - if (!init_planes(backend)) { + if (!init_planes(drm)) { goto error_crtcs; } @@ -152,25 +151,26 @@ bool wlr_drm_resources_init(struct wlr_drm_backend *backend) { return true; error_crtcs: - free(backend->crtcs); + free(drm->crtcs); error_res: drmModeFreeResources(res); return false; } -void wlr_drm_resources_free(struct wlr_drm_backend *backend) { - if (!backend) { +void wlr_drm_resources_free(struct wlr_drm_backend *drm) { + if (!drm) { return; } - for (size_t i = 0; i < backend->num_crtcs; ++i) { - struct wlr_drm_crtc *crtc = &backend->crtcs[i]; + + for (size_t i = 0; i < drm->num_crtcs; ++i) { + struct wlr_drm_crtc *crtc = &drm->crtcs[i]; drmModeAtomicFree(crtc->atomic); if (crtc->mode_id) { - drmModeDestroyPropertyBlob(backend->fd, crtc->mode_id); + drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); } } - free(backend->crtcs); - free(backend->planes); + free(drm->crtcs); + free(drm->planes); } static void wlr_drm_output_make_current(struct wlr_output *_output) { @@ -180,15 +180,15 @@ static void wlr_drm_output_make_current(struct wlr_output *_output) { static void wlr_drm_output_swap_buffers(struct wlr_output *_output) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = output->drm; - struct wlr_drm_renderer *renderer = &backend->renderer; + struct wlr_drm_backend *drm = output->drm; + struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->primary; - struct gbm_bo *bo = wlr_drm_surface_swap_buffers(renderer, &plane->surf); + struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&drm->renderer, &plane->surf); uint32_t fb_id = get_fb_for_bo(bo); - if (backend->iface->crtc_pageflip(backend, output, crtc, fb_id, NULL)) { + if (drm->iface->crtc_pageflip(drm, output, crtc, fb_id, NULL)) { output->pageflip_pending = true; } else { wl_event_source_timer_update(output->retry_pageflip, @@ -199,8 +199,7 @@ static void wlr_drm_output_swap_buffers(struct wlr_output *_output) { static void wlr_drm_output_set_gamma(struct wlr_output *_output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = output->drm; - drmModeCrtcSetGamma(backend->fd, output->crtc->id, size, r, g, b); + drmModeCrtcSetGamma(output->drm->fd, output->crtc->id, size, r, g, b); } static uint16_t wlr_drm_output_get_gamma_size(struct wlr_output *_output) { @@ -217,17 +216,16 @@ void wlr_drm_output_start_renderer(struct wlr_drm_output *output) { return; } - struct wlr_drm_backend *backend = output->drm; - struct wlr_drm_renderer *renderer = &backend->renderer; + struct wlr_drm_backend *drm = output->drm; struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->primary; - struct gbm_bo *bo = wlr_drm_surface_get_front(renderer, &plane->surf); + struct gbm_bo *bo = wlr_drm_surface_get_front(&drm->renderer, &plane->surf); struct wlr_drm_output_mode *_mode = (struct wlr_drm_output_mode *)output->output.current_mode; drmModeModeInfo *mode = &_mode->mode; - if (backend->iface->crtc_pageflip(backend, output, crtc, get_fb_for_bo(bo), mode)) { + if (drm->iface->crtc_pageflip(drm, output, crtc, get_fb_for_bo(bo), mode)) { output->pageflip_pending = true; } else { wl_event_source_timer_update(output->retry_pageflip, @@ -237,82 +235,81 @@ void wlr_drm_output_start_renderer(struct wlr_drm_output *output) { static void wlr_drm_output_enable(struct wlr_output *_output, bool enable) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = output->drm; if (output->state != WLR_DRM_OUTPUT_CONNECTED) { return; } - backend->iface->conn_enable(backend, output, enable); + struct wlr_drm_backend *drm = output->drm; + drm->iface->conn_enable(drm, output, enable); if (enable) { wlr_drm_output_start_renderer(output); } } -static void realloc_planes(struct wlr_drm_backend *backend, const uint32_t *crtc_in) { +static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in) { // overlay, primary, cursor for (int type = 0; type < 3; ++type) { - if (backend->num_type_planes[type] == 0) { + if (drm->num_type_planes[type] == 0) { continue; } - uint32_t possible[backend->num_type_planes[type]]; - uint32_t crtc[backend->num_crtcs]; - uint32_t crtc_res[backend->num_crtcs]; + uint32_t possible[drm->num_type_planes[type]]; + uint32_t crtc[drm->num_crtcs]; + uint32_t crtc_res[drm->num_crtcs]; - for (size_t i = 0; i < backend->num_type_planes[type]; ++i) { - possible[i] = backend->type_planes[type][i].possible_crtcs; + for (size_t i = 0; i < drm->num_type_planes[type]; ++i) { + possible[i] = drm->type_planes[type][i].possible_crtcs; } - for (size_t i = 0; i < backend->num_crtcs; ++i) { + for (size_t i = 0; i < drm->num_crtcs; ++i) { if (crtc_in[i] == UNMATCHED) { crtc[i] = SKIP; - } else if (backend->crtcs[i].planes[type]) { - crtc[i] = backend->crtcs[i].planes[type] - - backend->type_planes[type]; + } else if (drm->crtcs[i].planes[type]) { + crtc[i] = drm->crtcs[i].planes[type] + - drm->type_planes[type]; } else { crtc[i] = UNMATCHED; } } - match_obj(backend->num_type_planes[type], possible, - backend->num_crtcs, crtc, crtc_res); + match_obj(drm->num_type_planes[type], possible, + drm->num_crtcs, crtc, crtc_res); - for (size_t i = 0; i < backend->num_crtcs; ++i) { + for (size_t i = 0; i < drm->num_crtcs; ++i) { if (crtc_res[i] == UNMATCHED || crtc_res[i] == SKIP) { continue; } - struct wlr_drm_crtc *c = &backend->crtcs[i]; + struct wlr_drm_crtc *c = &drm->crtcs[i]; struct wlr_drm_plane **old = &c->planes[type]; - struct wlr_drm_plane *new = &backend->type_planes[type][crtc_res[i]]; + struct wlr_drm_plane *new = &drm->type_planes[type][crtc_res[i]]; if (*old != new) { if (*old) { - wlr_drm_surface_finish(&backend->renderer, &(*old)->surf); + wlr_drm_surface_finish(&drm->renderer, &(*old)->surf); } - wlr_drm_surface_finish(&backend->renderer, &new->surf); + wlr_drm_surface_finish(&drm->renderer, &new->surf); *old = new; } } } } -static void realloc_crtcs(struct wlr_drm_backend *backend, - struct wlr_drm_output *output) { - uint32_t crtc[backend->num_crtcs]; - uint32_t crtc_res[backend->num_crtcs]; - uint32_t possible_crtc[backend->outputs->length]; +static void realloc_crtcs(struct wlr_drm_backend *drm, struct wlr_drm_output *output) { + uint32_t crtc[drm->num_crtcs]; + uint32_t crtc_res[drm->num_crtcs]; + uint32_t possible_crtc[drm->outputs->length]; - for (size_t i = 0; i < backend->num_crtcs; ++i) { + for (size_t i = 0; i < drm->num_crtcs; ++i) { crtc[i] = UNMATCHED; } memset(possible_crtc, 0, sizeof(possible_crtc)); ssize_t index = -1; - for (size_t i = 0; i < backend->outputs->length; ++i) { - struct wlr_drm_output *o = backend->outputs->items[i]; + for (size_t i = 0; i < drm->outputs->length; ++i) { + struct wlr_drm_output *o = drm->outputs->items[i]; if (o == output) { index = i; } @@ -322,16 +319,16 @@ static void realloc_crtcs(struct wlr_drm_backend *backend, } possible_crtc[i] = o->possible_crtc; - crtc[o->crtc - backend->crtcs] = i; + crtc[o->crtc - drm->crtcs] = i; } assert(index != -1); possible_crtc[index] = output->possible_crtc; - match_obj(backend->outputs->length, possible_crtc, - backend->num_crtcs, crtc, crtc_res); + match_obj(drm->outputs->length, possible_crtc, + drm->num_crtcs, crtc, crtc_res); bool matched = false; - for (size_t i = 0; i < backend->num_crtcs; ++i) { + for (size_t i = 0; i < drm->num_crtcs; ++i) { // We don't want any of the current monitors to be deactivated. if (crtc[i] != UNMATCHED && crtc_res[i] == UNMATCHED) { return; @@ -346,29 +343,29 @@ static void realloc_crtcs(struct wlr_drm_backend *backend, return; } - for (size_t i = 0; i < backend->num_crtcs; ++i) { + for (size_t i = 0; i < drm->num_crtcs; ++i) { if (crtc_res[i] == UNMATCHED) { continue; } if (crtc_res[i] != crtc[i]) { - struct wlr_drm_output *o = backend->outputs->items[crtc_res[i]]; - o->crtc = &backend->crtcs[i]; + struct wlr_drm_output *o = drm->outputs->items[crtc_res[i]]; + o->crtc = &drm->crtcs[i]; } } - realloc_planes(backend, crtc_res); + realloc_planes(drm, crtc_res); } static bool wlr_drm_output_set_mode(struct wlr_output *_output, struct wlr_output_mode *mode) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = output->drm; + struct wlr_drm_backend *drm = output->drm; wlr_log(L_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", output->output.name, mode->width, mode->height, mode->refresh); - drmModeConnector *conn = drmModeGetConnector(backend->fd, output->connector); + drmModeConnector *conn = drmModeGetConnector(drm->fd, output->connector); if (!conn) { wlr_log_errno(L_ERROR, "Failed to get DRM connector"); goto error_output; @@ -381,7 +378,7 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, drmModeEncoder *enc = NULL; for (int i = 0; !enc && i < conn->count_encoders; ++i) { - enc = drmModeGetEncoder(backend->fd, conn->encoders[i]); + enc = drmModeGetEncoder(drm->fd, conn->encoders[i]); } if (!enc) { @@ -390,7 +387,7 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, } output->possible_crtc = enc->possible_crtcs; - realloc_crtcs(backend, output); + realloc_crtcs(drm, output); if (!output->crtc) { wlr_log(L_ERROR, "Unable to match %s with a CRTC", output->output.name); @@ -399,10 +396,10 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, struct wlr_drm_crtc *crtc = output->crtc; wlr_log(L_DEBUG, "%s: crtc=%ju ovr=%jd pri=%jd cur=%jd", output->output.name, - crtc - backend->crtcs, - crtc->overlay ? crtc->overlay - backend->overlay_planes : -1, - crtc->primary ? crtc->primary - backend->primary_planes : -1, - crtc->cursor ? crtc->cursor - backend->cursor_planes : -1); + crtc - drm->crtcs, + crtc->overlay ? crtc->overlay - drm->overlay_planes : -1, + crtc->primary ? crtc->primary - drm->primary_planes : -1, + crtc->cursor ? crtc->cursor - drm->cursor_planes : -1); output->state = WLR_DRM_OUTPUT_CONNECTED; output->width = output->output.width = mode->width; @@ -412,8 +409,8 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, // Since realloc_crtcs can deallocate planes on OTHER outputs, // we actually need to reinitalise all of them - for (size_t i = 0; i < backend->outputs->length; ++i) { - struct wlr_drm_output *output = backend->outputs->items[i]; + for (size_t i = 0; i < drm->outputs->length; ++i) { + struct wlr_drm_output *output = drm->outputs->items[i]; struct wlr_output_mode *mode = output->output.current_mode; struct wlr_drm_crtc *crtc = output->crtc; @@ -421,7 +418,7 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, continue; } - if (!wlr_drm_surface_init(&backend->renderer, &crtc->primary->surf, + if (!wlr_drm_surface_init(&drm->renderer, &crtc->primary->surf, mode->width, mode->height, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT)) { wlr_log(L_ERROR, "Failed to initalise renderer for plane"); @@ -452,13 +449,13 @@ static void wlr_drm_output_transform(struct wlr_output *output, static bool wlr_drm_output_set_cursor(struct wlr_output *_output, const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = output->drm; - struct wlr_drm_renderer *renderer = &backend->renderer; + struct wlr_drm_backend *drm = output->drm; + struct wlr_drm_renderer *renderer = &drm->renderer; struct wlr_drm_crtc *crtc = output->crtc; struct wlr_drm_plane *plane = crtc->cursor; if (!buf) { - return backend->iface->crtc_set_cursor(backend, crtc, NULL); + return drm->iface->crtc_set_cursor(drm, crtc, NULL); } // We don't have a real cursor plane, so we make a fake one @@ -474,9 +471,9 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, if (!plane->surf.gbm) { int ret; uint64_t w, h; - ret = drmGetCap(backend->fd, DRM_CAP_CURSOR_WIDTH, &w); + ret = drmGetCap(drm->fd, DRM_CAP_CURSOR_WIDTH, &w); w = ret ? 64 : w; - ret = drmGetCap(backend->fd, DRM_CAP_CURSOR_HEIGHT, &h); + ret = drmGetCap(drm->fd, DRM_CAP_CURSOR_HEIGHT, &h); h = ret ? 64 : h; if (width > w || height > h) { @@ -503,7 +500,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, // TODO the image needs to be rotated depending on the output rotation - plane->wlr_rend = wlr_gles2_renderer_create(&backend->backend); + plane->wlr_rend = wlr_gles2_renderer_create(&drm->backend); if (!plane->wlr_rend) { return false; } @@ -548,13 +545,13 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, gbm_bo_unmap(bo, bo_data); - return backend->iface->crtc_set_cursor(backend, crtc, bo); + return drm->iface->crtc_set_cursor(drm, crtc, bo); } static bool wlr_drm_output_move_cursor(struct wlr_output *_output, int x, int y) { struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *backend = output->drm; + struct wlr_drm_backend *drm = output->drm; int width, height, tmp; wlr_output_effective_resolution(_output, &width, &height); @@ -580,7 +577,7 @@ static bool wlr_drm_output_move_cursor(struct wlr_output *_output, break; } - return backend->iface->crtc_move_cursor(backend, output->crtc, x, y); + return drm->iface->crtc_move_cursor(drm, output->crtc, x, y); } static void wlr_drm_output_destroy(struct wlr_output *_output) { @@ -632,22 +629,22 @@ static const int32_t subpixel_map[] = { [DRM_MODE_SUBPIXEL_NONE] = WL_OUTPUT_SUBPIXEL_NONE, }; -void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { +void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { wlr_log(L_INFO, "Scanning DRM connectors"); - drmModeRes *res = drmModeGetResources(backend->fd); + drmModeRes *res = drmModeGetResources(drm->fd); if (!res) { wlr_log_errno(L_ERROR, "Failed to get DRM resources"); return; } - size_t seen_len = backend->outputs->length; + size_t seen_len = drm->outputs->length; // +1 so it can never be 0 bool seen[seen_len + 1]; memset(seen, 0, sizeof(seen)); for (int i = 0; i < res->count_connectors; ++i) { - drmModeConnector *conn = drmModeGetConnector(backend->fd, + drmModeConnector *conn = drmModeGetConnector(drm->fd, res->connectors[i]); if (!conn) { wlr_log_errno(L_ERROR, "Failed to get DRM connector"); @@ -655,7 +652,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { } struct wlr_drm_output *output; - int index = list_seq_find(backend->outputs, find_id, &conn->connector_id); + int index = list_seq_find(drm->outputs, find_id, &conn->connector_id); if (index == -1) { output = calloc(1, sizeof(*output)); @@ -666,7 +663,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { } wlr_output_init(&output->output, &output_impl); - struct wl_event_loop *ev = wl_display_get_event_loop(backend->display); + struct wl_event_loop *ev = wl_display_get_event_loop(drm->display); output->retry_pageflip = wl_event_loop_add_timer(ev, retry_pageflip, output); @@ -674,10 +671,10 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { output->state = WLR_DRM_OUTPUT_DISCONNECTED; output->connector = conn->connector_id; - drmModeEncoder *curr_enc = drmModeGetEncoder(backend->fd, + drmModeEncoder *curr_enc = drmModeGetEncoder(drm->fd, conn->encoder_id); if (curr_enc) { - output->old_crtc = drmModeGetCrtc(backend->fd, curr_enc->crtc_id); + output->old_crtc = drmModeGetCrtc(drm->fd, curr_enc->crtc_id); drmModeFreeEncoder(curr_enc); } @@ -688,26 +685,26 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { conn_get_name(conn->connector_type), conn->connector_type_id); - wlr_drm_get_connector_props(backend->fd, + wlr_drm_get_connector_props(drm->fd, output->connector, &output->props); size_t edid_len = 0; - uint8_t *edid = wlr_drm_get_prop_blob(backend->fd, + uint8_t *edid = wlr_drm_get_prop_blob(drm->fd, output->connector, output->props.edid, &edid_len); parse_edid(&output->output, edid_len, edid); free(edid); - if (list_add(backend->outputs, output) == -1) { + if (list_add(drm->outputs, output) == -1) { wlr_log_errno(L_ERROR, "Allocation failed"); drmModeFreeConnector(conn); wl_event_source_remove(output->retry_pageflip); free(output); continue; } - wlr_output_create_global(&output->output, backend->display); + wlr_output_create_global(&output->output, drm->display); wlr_log(L_INFO, "Found display '%s'", output->output.name); } else { - output = backend->outputs->items[index]; + output = drm->outputs->items[index]; seen[index] = true; } @@ -742,7 +739,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { output->state = WLR_DRM_OUTPUT_NEEDS_MODESET; wlr_log(L_INFO, "Sending modesetting signal for '%s'", output->output.name); - wl_signal_emit(&backend->backend.events.output_add, &output->output); + wl_signal_emit(&drm->backend.events.output_add, &output->output); } else if (output->state == WLR_DRM_OUTPUT_CONNECTED && conn->connection != DRM_MODE_CONNECTED) { @@ -760,7 +757,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { continue; } - struct wlr_drm_output *output = backend->outputs->items[i]; + struct wlr_drm_output *output = drm->outputs->items[i]; wlr_log(L_INFO, "'%s' disappeared", output->output.name); wlr_drm_output_cleanup(output); @@ -769,14 +766,14 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { wl_event_source_remove(output->retry_pageflip); free(output); - list_del(backend->outputs, i); + list_del(drm->outputs, i); } } static void page_flip_handler(int fd, unsigned seq, unsigned tv_sec, unsigned tv_usec, void *user) { struct wlr_drm_output *output = user; - struct wlr_drm_backend *backend = output->drm; + struct wlr_drm_backend *drm = output->drm; output->pageflip_pending = false; if (output->state != WLR_DRM_OUTPUT_CONNECTED) { @@ -789,7 +786,7 @@ static void page_flip_handler(int fd, unsigned seq, plane->surf.front = NULL; } - if (backend->session->active) { + if (drm->session->active) { wl_signal_emit(&output->output.events.frame, &output->output); } } @@ -848,15 +845,14 @@ void wlr_drm_output_cleanup(struct wlr_drm_output *output) { return; } - struct wlr_drm_backend *backend = output->drm; - struct wlr_drm_renderer *renderer = &backend->renderer; + struct wlr_drm_backend *drm = output->drm; switch (output->state) { case WLR_DRM_OUTPUT_CONNECTED: case WLR_DRM_OUTPUT_CLEANUP:; struct wlr_drm_crtc *crtc = output->crtc; for (int i = 0; i < 3; ++i) { - wlr_drm_surface_finish(renderer, &crtc->planes[i]->surf); + wlr_drm_surface_finish(&drm->renderer, &crtc->planes[i]->surf); if (crtc->planes[i] && crtc->planes[i]->id == 0) { free(crtc->planes[i]); crtc->planes[i] = NULL; @@ -869,7 +865,7 @@ void wlr_drm_output_cleanup(struct wlr_drm_output *output) { case WLR_DRM_OUTPUT_NEEDS_MODESET: wlr_log(L_INFO, "Emmiting destruction signal for '%s'", output->output.name); - wl_signal_emit(&backend->backend.events.output_remove, &output->output); + wl_signal_emit(&drm->backend.events.output_remove, &output->output); break; case WLR_DRM_OUTPUT_DISCONNECTED: break; diff --git a/backend/drm/iface_atomic.c b/backend/drm/iface_atomic.c index ce5de091..7e506fe7 100644 --- a/backend/drm/iface_atomic.c +++ b/backend/drm/iface_atomic.c @@ -96,16 +96,16 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_plane *plane, } } -static bool atomic_crtc_pageflip(struct wlr_drm_backend *backend, +static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, uint32_t fb_id, drmModeModeInfo *mode) { if (mode) { if (crtc->mode_id) { - drmModeDestroyPropertyBlob(backend->fd, crtc->mode_id); + drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); } - if (drmModeCreatePropertyBlob(backend->fd, mode, sizeof(*mode), &crtc->mode_id)) { + if (drmModeCreatePropertyBlob(drm->fd, mode, sizeof(*mode), &crtc->mode_id)) { wlr_log_errno(L_ERROR, "Unable to create property blob"); return false; } @@ -118,25 +118,25 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *backend, atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id); atomic_add(&atom, crtc->id, crtc->props.active, 1); set_plane_props(&atom, crtc->primary, crtc->id, fb_id, true); - return atomic_commit(backend->fd, &atom, output, + return atomic_commit(drm->fd, &atom, output, mode ? DRM_MODE_ATOMIC_ALLOW_MODESET : DRM_MODE_ATOMIC_NONBLOCK, mode); } -static void atomic_conn_enable(struct wlr_drm_backend *backend, +static void atomic_conn_enable(struct wlr_drm_backend *drm, struct wlr_drm_output *output, bool enable) { struct wlr_drm_crtc *crtc = output->crtc; struct atomic atom; atomic_begin(crtc, &atom); atomic_add(&atom, crtc->id, crtc->props.active, enable); - atomic_end(backend->fd, &atom); + atomic_end(drm->fd, &atom); } -bool legacy_crtc_set_cursor(struct wlr_drm_backend *backend, +bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, struct wlr_drm_crtc *crtc, struct gbm_bo *bo); -static bool atomic_crtc_set_cursor(struct wlr_drm_backend *backend, +static bool atomic_crtc_set_cursor(struct wlr_drm_backend *drm, struct wlr_drm_crtc *crtc, struct gbm_bo *bo) { if (!crtc || !crtc->cursor) { return true; @@ -145,7 +145,7 @@ static bool atomic_crtc_set_cursor(struct wlr_drm_backend *backend, struct wlr_drm_plane *plane = crtc->cursor; // We can't use atomic operations on fake planes if (plane->id == 0) { - return legacy_crtc_set_cursor(backend, crtc, bo); + return legacy_crtc_set_cursor(drm, crtc, bo); } struct atomic atom; @@ -159,18 +159,18 @@ static bool atomic_crtc_set_cursor(struct wlr_drm_backend *backend, atomic_add(&atom, plane->id, plane->props.crtc_id, 0); } - return atomic_end(backend->fd, &atom); + return atomic_end(drm->fd, &atom); } -bool legacy_crtc_move_cursor(struct wlr_drm_backend *backend, +bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, struct wlr_drm_crtc *crtc, int x, int y); -static bool atomic_crtc_move_cursor(struct wlr_drm_backend *backend, +static bool atomic_crtc_move_cursor(struct wlr_drm_backend *drm, struct wlr_drm_crtc *crtc, int x, int y) { struct wlr_drm_plane *plane = crtc->cursor; // We can't use atomic operations on fake planes if (plane->id == 0) { - return legacy_crtc_move_cursor(backend, crtc, x, y); + return legacy_crtc_move_cursor(drm, crtc, x, y); } struct atomic atom; @@ -178,7 +178,7 @@ static bool atomic_crtc_move_cursor(struct wlr_drm_backend *backend, atomic_begin(crtc, &atom); atomic_add(&atom, plane->id, plane->props.crtc_x, x); atomic_add(&atom, plane->id, plane->props.crtc_y, y); - return atomic_end(backend->fd, &atom); + return atomic_end(drm->fd, &atom); } const struct wlr_drm_interface iface_atomic = { diff --git a/backend/drm/iface_legacy.c b/backend/drm/iface_legacy.c index e320af93..ffa8157b 100644 --- a/backend/drm/iface_legacy.c +++ b/backend/drm/iface_legacy.c @@ -6,18 +6,18 @@ #include "backend/drm/iface.h" #include "backend/drm/util.h" -static bool legacy_crtc_pageflip(struct wlr_drm_backend *backend, +static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm, struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, uint32_t fb_id, drmModeModeInfo *mode) { if (mode) { - if (drmModeSetCrtc(backend->fd, crtc->id, fb_id, 0, 0, + if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0, &output->connector, 1, mode)) { wlr_log_errno(L_ERROR, "%s: Failed to set CRTC", output->output.name); return false; } } - if (drmModePageFlip(backend->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output)) { + if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output)) { wlr_log_errno(L_ERROR, "%s: Failed to page flip", output->output.name); return false; } @@ -25,26 +25,26 @@ static bool legacy_crtc_pageflip(struct wlr_drm_backend *backend, return true; } -static void legacy_conn_enable(struct wlr_drm_backend *backend, +static void legacy_conn_enable(struct wlr_drm_backend *drm, struct wlr_drm_output *output, bool enable) { - drmModeConnectorSetProperty(backend->fd, output->connector, output->props.dpms, + drmModeConnectorSetProperty(drm->fd, output->connector, output->props.dpms, enable ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); } -bool legacy_crtc_set_cursor(struct wlr_drm_backend *backend, +bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, struct wlr_drm_crtc *crtc, struct gbm_bo *bo) { if (!crtc || !crtc->cursor) { return true; } if (!bo) { - drmModeSetCursor(backend->fd, crtc->id, 0, 0, 0); + drmModeSetCursor(drm->fd, crtc->id, 0, 0, 0); return true; } struct wlr_drm_plane *plane = crtc->cursor; - if (drmModeSetCursor(backend->fd, crtc->id, gbm_bo_get_handle(bo).u32, + if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(bo).u32, plane->surf.width, plane->surf.height)) { wlr_log_errno(L_ERROR, "Failed to set hardware cursor"); return false; @@ -53,9 +53,9 @@ bool legacy_crtc_set_cursor(struct wlr_drm_backend *backend, return true; } -bool legacy_crtc_move_cursor(struct wlr_drm_backend *backend, +bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, struct wlr_drm_crtc *crtc, int x, int y) { - return !drmModeMoveCursor(backend->fd, crtc->id, x, y); + return !drmModeMoveCursor(drm->fd, crtc->id, x, y); } const struct wlr_drm_interface iface_legacy = { diff --git a/include/backend/drm/iface.h b/include/backend/drm/iface.h index cf77f4d4..291b9a30 100644 --- a/include/backend/drm/iface.h +++ b/include/backend/drm/iface.h @@ -15,18 +15,18 @@ struct wlr_drm_crtc; // Used to provide atomic or legacy DRM functions struct wlr_drm_interface { // Enable or disable DPMS for output - void (*conn_enable)(struct wlr_drm_backend *backend, - struct wlr_drm_output *output, bool enable); + void (*conn_enable)(struct wlr_drm_backend *drm, + struct wlr_drm_output *output, bool enable); // Pageflip on crtc. If mode is non-NULL perform a full modeset using it. - bool (*crtc_pageflip)(struct wlr_drm_backend *backend, - struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, - uint32_t fb_id, drmModeModeInfo *mode); + bool (*crtc_pageflip)(struct wlr_drm_backend *drm, + struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, + uint32_t fb_id, drmModeModeInfo *mode); // Enable the cursor buffer on crtc. Set bo to NULL to disable - bool (*crtc_set_cursor)(struct wlr_drm_backend *backend, - struct wlr_drm_crtc *crtc, struct gbm_bo *bo); + bool (*crtc_set_cursor)(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, struct gbm_bo *bo); // Move the cursor on crtc - bool (*crtc_move_cursor)(struct wlr_drm_backend *backend, - struct wlr_drm_crtc *crtc, int x, int y); + bool (*crtc_move_cursor)(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, int x, int y); }; extern const struct wlr_drm_interface iface_atomic; -- cgit v1.2.3 From 4101b897000602caf04aba8a10c1b4a4b229f4d6 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 30 Sep 2017 23:31:08 +1300 Subject: Rename wlr_drm_output to wlr_drm_connector --- backend/drm/backend.c | 14 +- backend/drm/drm.c | 422 ++++++++++++++++++++++---------------------- backend/drm/iface_atomic.c | 20 +-- backend/drm/iface_legacy.c | 14 +- include/backend/drm/drm.h | 34 ++-- include/backend/drm/iface.h | 8 +- 6 files changed, 252 insertions(+), 260 deletions(-) (limited to 'include/backend/drm') diff --git a/backend/drm/backend.c b/backend/drm/backend.c index f634eee6..442e5d0e 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -30,8 +30,8 @@ static void wlr_drm_backend_destroy(struct wlr_backend *backend) { wlr_drm_restore_outputs(drm); for (size_t i = 0; drm->outputs && i < drm->outputs->length; ++i) { - struct wlr_drm_output *output = drm->outputs->items[i]; - wlr_output_destroy(&output->output); + struct wlr_drm_connector *conn = drm->outputs->items[i]; + wlr_output_destroy(&conn->output); } wlr_drm_renderer_finish(&drm->renderer); @@ -65,15 +65,15 @@ static void session_signal(struct wl_listener *listener, void *data) { wlr_log(L_INFO, "DRM fd resumed"); for (size_t i = 0; i < drm->outputs->length; ++i) { - struct wlr_drm_output *output = drm->outputs->items[i]; - wlr_drm_output_start_renderer(output); + struct wlr_drm_connector *conn = drm->outputs->items[i]; + wlr_drm_connector_start_renderer(conn); - if (!output->crtc) { + if (!conn->crtc) { continue; } - struct wlr_drm_plane *plane = output->crtc->cursor; - drm->iface->crtc_set_cursor(drm, output->crtc, + struct wlr_drm_plane *plane = conn->crtc->cursor; + drm->iface->crtc_set_cursor(drm, conn->crtc, plane ? plane->cursor_bo : NULL); } } else { diff --git a/backend/drm/drm.c b/backend/drm/drm.c index a50216cb..676f5f7b 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -173,77 +173,73 @@ void wlr_drm_resources_free(struct wlr_drm_backend *drm) { free(drm->planes); } -static void wlr_drm_output_make_current(struct wlr_output *_output) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - wlr_drm_surface_make_current(&output->drm->renderer, &output->crtc->primary->surf); +static void wlr_drm_connector_make_current(struct wlr_output *output) { + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + wlr_drm_surface_make_current(&conn->drm->renderer, &conn->crtc->primary->surf); } -static void wlr_drm_output_swap_buffers(struct wlr_output *_output) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *drm = output->drm; +static void wlr_drm_connector_swap_buffers(struct wlr_output *output) { + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + struct wlr_drm_backend *drm = conn->drm; - struct wlr_drm_crtc *crtc = output->crtc; + struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_plane *plane = crtc->primary; struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&drm->renderer, &plane->surf); uint32_t fb_id = get_fb_for_bo(bo); - if (drm->iface->crtc_pageflip(drm, output, crtc, fb_id, NULL)) { - output->pageflip_pending = true; + if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) { + conn->pageflip_pending = true; } else { - wl_event_source_timer_update(output->retry_pageflip, - 1000.0f / output->output.current_mode->refresh); + wl_event_source_timer_update(conn->retry_pageflip, + 1000.0f / conn->output.current_mode->refresh); } } -static void wlr_drm_output_set_gamma(struct wlr_output *_output, +static void wlr_drm_connector_set_gamma(struct wlr_output *output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - drmModeCrtcSetGamma(output->drm->fd, output->crtc->id, size, r, g, b); + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + drmModeCrtcSetGamma(conn->drm->fd, conn->crtc->id, size, r, g, b); } -static uint16_t wlr_drm_output_get_gamma_size(struct wlr_output *_output) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - drmModeCrtc *crtc = output->old_crtc; - if (!crtc) { - return 0; - } - return crtc->gamma_size; +static uint16_t wlr_drm_connector_get_gamma_size(struct wlr_output *output) { + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + drmModeCrtc *crtc = conn->old_crtc; + return crtc ? crtc->gamma_size : 0; } -void wlr_drm_output_start_renderer(struct wlr_drm_output *output) { - if (output->state != WLR_DRM_OUTPUT_CONNECTED) { +void wlr_drm_connector_start_renderer(struct wlr_drm_connector *conn) { + if (conn->state != WLR_DRM_CONN_CONNECTED) { return; } - struct wlr_drm_backend *drm = output->drm; - struct wlr_drm_crtc *crtc = output->crtc; + struct wlr_drm_backend *drm = conn->drm; + struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_plane *plane = crtc->primary; struct gbm_bo *bo = wlr_drm_surface_get_front(&drm->renderer, &plane->surf); + uint32_t fb_id = get_fb_for_bo(bo); - struct wlr_drm_output_mode *_mode = - (struct wlr_drm_output_mode *)output->output.current_mode; - drmModeModeInfo *mode = &_mode->mode; - if (drm->iface->crtc_pageflip(drm, output, crtc, get_fb_for_bo(bo), mode)) { - output->pageflip_pending = true; + 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)) { + conn->pageflip_pending = true; } else { - wl_event_source_timer_update(output->retry_pageflip, - 1000.0f / output->output.current_mode->refresh); + wl_event_source_timer_update(conn->retry_pageflip, + 1000.0f / conn->output.current_mode->refresh); } } -static void wlr_drm_output_enable(struct wlr_output *_output, bool enable) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - if (output->state != WLR_DRM_OUTPUT_CONNECTED) { +static void wlr_drm_connector_enable(struct wlr_output *output, bool enable) { + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + if (conn->state != WLR_DRM_CONN_CONNECTED) { return; } - struct wlr_drm_backend *drm = output->drm; - drm->iface->conn_enable(drm, output, enable); + struct wlr_drm_backend *drm = conn->drm; + drm->iface->conn_enable(drm, conn, enable); if (enable) { - wlr_drm_output_start_renderer(output); + wlr_drm_connector_start_renderer(conn); } } @@ -296,7 +292,7 @@ static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in) } } -static void realloc_crtcs(struct wlr_drm_backend *drm, struct wlr_drm_output *output) { +static void realloc_crtcs(struct wlr_drm_backend *drm, struct wlr_drm_connector *conn) { uint32_t crtc[drm->num_crtcs]; uint32_t crtc_res[drm->num_crtcs]; uint32_t possible_crtc[drm->outputs->length]; @@ -309,23 +305,23 @@ static void realloc_crtcs(struct wlr_drm_backend *drm, struct wlr_drm_output *ou ssize_t index = -1; for (size_t i = 0; i < drm->outputs->length; ++i) { - struct wlr_drm_output *o = drm->outputs->items[i]; - if (o == output) { + struct wlr_drm_connector *c = drm->outputs->items[i]; + if (c == conn) { index = i; } - if (o->state != WLR_DRM_OUTPUT_CONNECTED) { + if (c->state != WLR_DRM_CONN_CONNECTED) { continue; } - possible_crtc[i] = o->possible_crtc; - crtc[o->crtc - drm->crtcs] = i; + possible_crtc[i] = c->possible_crtc; + crtc[c->crtc - drm->crtcs] = i; } assert(index != -1); - possible_crtc[index] = output->possible_crtc; - match_obj(drm->outputs->length, possible_crtc, - drm->num_crtcs, crtc, crtc_res); + possible_crtc[index] = conn->possible_crtc; + match_obj(drm->outputs->length, possible_crtc, drm->num_crtcs, + crtc, crtc_res); bool matched = false; for (size_t i = 0; i < drm->num_crtcs; ++i) { @@ -349,36 +345,29 @@ static void realloc_crtcs(struct wlr_drm_backend *drm, struct wlr_drm_output *ou } if (crtc_res[i] != crtc[i]) { - struct wlr_drm_output *o = drm->outputs->items[crtc_res[i]]; - o->crtc = &drm->crtcs[i]; + struct wlr_drm_connector *c = drm->outputs->items[crtc_res[i]]; + c->crtc = &drm->crtcs[i]; } } realloc_planes(drm, crtc_res); } -static bool wlr_drm_output_set_mode(struct wlr_output *_output, - struct wlr_output_mode *mode) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *drm = output->drm; - - wlr_log(L_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", output->output.name, - mode->width, mode->height, mode->refresh); - - drmModeConnector *conn = drmModeGetConnector(drm->fd, output->connector); +static uint32_t get_possible_crtcs(int fd, uint32_t conn_id) { + drmModeConnector *conn = drmModeGetConnector(fd, conn_id); if (!conn) { wlr_log_errno(L_ERROR, "Failed to get DRM connector"); - goto error_output; + return 0; } if (conn->connection != DRM_MODE_CONNECTED || conn->count_modes == 0) { - wlr_log(L_ERROR, "%s is not connected", output->output.name); - goto error_output; + wlr_log(L_ERROR, "Output is not connected"); + goto error_conn; } drmModeEncoder *enc = NULL; for (int i = 0; !enc && i < conn->count_encoders; ++i) { - enc = drmModeGetEncoder(drm->fd, conn->encoders[i]); + enc = drmModeGetEncoder(fd, conn->encoders[i]); } if (!enc) { @@ -386,35 +375,58 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, goto error_conn; } - output->possible_crtc = enc->possible_crtcs; - realloc_crtcs(drm, output); + uint32_t ret = enc->possible_crtcs; + drmModeFreeEncoder(enc); + drmModeFreeConnector(conn); + return ret; - if (!output->crtc) { - wlr_log(L_ERROR, "Unable to match %s with a CRTC", output->output.name); - goto error_enc; +error_conn: + drmModeFreeConnector(conn); + return 0; +} + +static bool wlr_drm_connector_set_mode(struct wlr_output *output, + struct wlr_output_mode *mode) { + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + struct wlr_drm_backend *drm = conn->drm; + + wlr_log(L_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", conn->output.name, + mode->width, mode->height, mode->refresh); + + wlr_log(L_DEBUG, "%p %p", conn, drm); + conn->possible_crtc = get_possible_crtcs(drm->fd, conn->id); + if (conn->possible_crtc == 0) { + goto error_conn; } - struct wlr_drm_crtc *crtc = output->crtc; - wlr_log(L_DEBUG, "%s: crtc=%ju ovr=%jd pri=%jd cur=%jd", output->output.name, + realloc_crtcs(drm, conn); + + if (!conn->crtc) { + wlr_log(L_ERROR, "Unable to match %s with a CRTC", conn->output.name); + goto error_conn; + } + + struct wlr_drm_crtc *crtc = conn->crtc; + wlr_log(L_DEBUG, "%s: crtc=%ju ovr=%jd pri=%jd cur=%jd", conn->output.name, crtc - drm->crtcs, crtc->overlay ? crtc->overlay - drm->overlay_planes : -1, crtc->primary ? crtc->primary - drm->primary_planes : -1, crtc->cursor ? crtc->cursor - drm->cursor_planes : -1); - output->state = WLR_DRM_OUTPUT_CONNECTED; - output->width = output->output.width = mode->width; - output->height = output->output.height = mode->height; - output->output.current_mode = mode; - wl_signal_emit(&output->output.events.resolution, &output->output); + conn->state = WLR_DRM_CONN_CONNECTED; + conn->output.width = mode->width; + conn->output.height = mode->height; + conn->output.current_mode = mode; + wl_signal_emit(&conn->output.events.resolution, &conn->output); // Since realloc_crtcs can deallocate planes on OTHER outputs, // we actually need to reinitalise all of them for (size_t i = 0; i < drm->outputs->length; ++i) { - struct wlr_drm_output *output = drm->outputs->items[i]; - struct wlr_output_mode *mode = output->output.current_mode; - struct wlr_drm_crtc *crtc = output->crtc; + struct wlr_drm_connector *conn = drm->outputs->items[i]; + struct wlr_output_mode *mode = conn->output.current_mode; + struct wlr_drm_crtc *crtc = conn->crtc; - if (output->state != WLR_DRM_OUTPUT_CONNECTED) { + if (conn->state != WLR_DRM_CONN_CONNECTED) { continue; } @@ -422,36 +434,31 @@ static bool wlr_drm_output_set_mode(struct wlr_output *_output, mode->width, mode->height, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT)) { wlr_log(L_ERROR, "Failed to initalise renderer for plane"); - goto error_enc; + goto error_conn; } - wlr_drm_output_start_renderer(output); + wlr_drm_connector_start_renderer(conn); } - drmModeFreeEncoder(enc); - drmModeFreeConnector(conn); return true; -error_enc: - drmModeFreeEncoder(enc); error_conn: - drmModeFreeConnector(conn); -error_output: - wlr_drm_output_cleanup(output); + wlr_drm_connector_cleanup(conn); return false; } -static void wlr_drm_output_transform(struct wlr_output *output, +static void wlr_drm_connector_transform(struct wlr_output *output, enum wl_output_transform transform) { output->transform = transform; } -static bool wlr_drm_output_set_cursor(struct wlr_output *_output, +static bool wlr_drm_connector_set_cursor(struct wlr_output *output, const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *drm = output->drm; + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + struct wlr_drm_backend *drm = conn->drm; struct wlr_drm_renderer *renderer = &drm->renderer; - struct wlr_drm_crtc *crtc = output->crtc; + + struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_plane *plane = crtc->cursor; if (!buf) { @@ -496,7 +503,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, // OpenGL will read the pixels out upside down, // so we need to flip the image vertically wlr_matrix_texture(plane->matrix, plane->surf.width, plane->surf.height, - output->output.transform ^ WL_OUTPUT_TRANSFORM_FLIPPED_180); + conn->output.transform ^ WL_OUTPUT_TRANSFORM_FLIPPED_180); // TODO the image needs to be rotated depending on the output rotation @@ -548,15 +555,15 @@ static bool wlr_drm_output_set_cursor(struct wlr_output *_output, return drm->iface->crtc_set_cursor(drm, crtc, bo); } -static bool wlr_drm_output_move_cursor(struct wlr_output *_output, +static bool wlr_drm_connector_move_cursor(struct wlr_output *output, int x, int y) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - struct wlr_drm_backend *drm = output->drm; + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + struct wlr_drm_backend *drm = conn->drm; int width, height, tmp; - wlr_output_effective_resolution(_output, &width, &height); + wlr_output_effective_resolution(output, &width, &height); - switch (_output->transform) { + switch (output->transform) { case WL_OUTPUT_TRANSFORM_NORMAL: // nothing to do break; @@ -573,51 +580,45 @@ static bool wlr_drm_output_move_cursor(struct wlr_output *_output, default: // TODO other transformations wlr_log(L_ERROR, "TODO: handle surface to crtc for transformation = %d", - _output->transform); + output->transform); break; } - return drm->iface->crtc_move_cursor(drm, output->crtc, x, y); + return drm->iface->crtc_move_cursor(drm, conn->crtc, x, y); } -static void wlr_drm_output_destroy(struct wlr_output *_output) { - struct wlr_drm_output *output = (struct wlr_drm_output *)_output; - wlr_drm_output_cleanup(output); - wl_event_source_remove(output->retry_pageflip); - free(output); +static void wlr_drm_connector_destroy(struct wlr_output *output) { + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + wlr_drm_connector_cleanup(conn); + wl_event_source_remove(conn->retry_pageflip); + free(conn); } static struct wlr_output_impl output_impl = { - .enable = wlr_drm_output_enable, - .set_mode = wlr_drm_output_set_mode, - .transform = wlr_drm_output_transform, - .set_cursor = wlr_drm_output_set_cursor, - .move_cursor = wlr_drm_output_move_cursor, - .destroy = wlr_drm_output_destroy, - .make_current = wlr_drm_output_make_current, - .swap_buffers = wlr_drm_output_swap_buffers, - .set_gamma = wlr_drm_output_set_gamma, - .get_gamma_size = wlr_drm_output_get_gamma_size, + .enable = wlr_drm_connector_enable, + .set_mode = wlr_drm_connector_set_mode, + .transform = wlr_drm_connector_transform, + .set_cursor = wlr_drm_connector_set_cursor, + .move_cursor = wlr_drm_connector_move_cursor, + .destroy = wlr_drm_connector_destroy, + .make_current = wlr_drm_connector_make_current, + .swap_buffers = wlr_drm_connector_swap_buffers, + .set_gamma = wlr_drm_connector_set_gamma, + .get_gamma_size = wlr_drm_connector_get_gamma_size, }; static int retry_pageflip(void *data) { - struct wlr_drm_output *output = data; - wlr_log(L_INFO, "%s: Retrying pageflip", output->output.name); - wlr_drm_output_start_renderer(output); + struct wlr_drm_connector *conn = data; + wlr_log(L_INFO, "%s: Retrying pageflip", conn->output.name); + wlr_drm_connector_start_renderer(conn); return 0; } static int find_id(const void *item, const void *cmp_to) { - const struct wlr_drm_output *output = item; + const struct wlr_drm_connector *conn = item; const uint32_t *id = cmp_to; - if (output->connector < *id) { - return -1; - } else if (output->connector > *id) { - return 1; - } else { - return 0; - } + return (int)conn->id - (int)*id; } static const int32_t subpixel_map[] = { @@ -644,110 +645,111 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { memset(seen, 0, sizeof(seen)); for (int i = 0; i < res->count_connectors; ++i) { - drmModeConnector *conn = drmModeGetConnector(drm->fd, + drmModeConnector *drm_conn = drmModeGetConnector(drm->fd, res->connectors[i]); - if (!conn) { + if (!drm_conn) { wlr_log_errno(L_ERROR, "Failed to get DRM connector"); continue; } - struct wlr_drm_output *output; - int index = list_seq_find(drm->outputs, find_id, &conn->connector_id); + struct wlr_drm_connector *wlr_conn; + int index = list_seq_find(drm->outputs, find_id, &drm_conn->connector_id); if (index == -1) { - output = calloc(1, sizeof(*output)); - if (!output) { + wlr_conn = calloc(1, sizeof(*wlr_conn)); + if (!wlr_conn) { wlr_log_errno(L_ERROR, "Allocation failed"); - drmModeFreeConnector(conn); + drmModeFreeConnector(drm_conn); continue; } - wlr_output_init(&output->output, &output_impl); + wlr_output_init(&wlr_conn->output, &output_impl); struct wl_event_loop *ev = wl_display_get_event_loop(drm->display); - output->retry_pageflip = wl_event_loop_add_timer(ev, retry_pageflip, - output); + wlr_conn->retry_pageflip = wl_event_loop_add_timer(ev, retry_pageflip, + wlr_conn); - output->state = WLR_DRM_OUTPUT_DISCONNECTED; - output->connector = conn->connector_id; + wlr_conn->drm = drm; + wlr_conn->state = WLR_DRM_CONN_DISCONNECTED; + wlr_conn->id = drm_conn->connector_id; drmModeEncoder *curr_enc = drmModeGetEncoder(drm->fd, - conn->encoder_id); + drm_conn->encoder_id); if (curr_enc) { - output->old_crtc = drmModeGetCrtc(drm->fd, curr_enc->crtc_id); + wlr_conn->old_crtc = drmModeGetCrtc(drm->fd, curr_enc->crtc_id); drmModeFreeEncoder(curr_enc); } - output->output.phys_width = conn->mmWidth; - output->output.phys_height = conn->mmHeight; - output->output.subpixel = subpixel_map[conn->subpixel]; - snprintf(output->output.name, sizeof(output->output.name), "%s-%"PRIu32, - conn_get_name(conn->connector_type), - conn->connector_type_id); + wlr_conn->output.phys_width = drm_conn->mmWidth; + wlr_conn->output.phys_height = drm_conn->mmHeight; + wlr_conn->output.subpixel = subpixel_map[drm_conn->subpixel]; + snprintf(wlr_conn->output.name, sizeof(wlr_conn->output.name), + "%s-%"PRIu32, + conn_get_name(drm_conn->connector_type), + drm_conn->connector_type_id); - wlr_drm_get_connector_props(drm->fd, - output->connector, &output->props); + wlr_drm_get_connector_props(drm->fd, wlr_conn->id, &wlr_conn->props); size_t edid_len = 0; uint8_t *edid = wlr_drm_get_prop_blob(drm->fd, - output->connector, output->props.edid, &edid_len); - parse_edid(&output->output, edid_len, edid); + wlr_conn->id, wlr_conn->props.edid, &edid_len); + parse_edid(&wlr_conn->output, edid_len, edid); free(edid); - if (list_add(drm->outputs, output) == -1) { + if (list_add(drm->outputs, wlr_conn) == -1) { wlr_log_errno(L_ERROR, "Allocation failed"); - drmModeFreeConnector(conn); - wl_event_source_remove(output->retry_pageflip); - free(output); + drmModeFreeConnector(drm_conn); + wl_event_source_remove(wlr_conn->retry_pageflip); + free(wlr_conn); continue; } - wlr_output_create_global(&output->output, drm->display); - wlr_log(L_INFO, "Found display '%s'", output->output.name); + wlr_output_create_global(&wlr_conn->output, drm->display); + wlr_log(L_INFO, "Found display '%s'", wlr_conn->output.name); } else { - output = drm->outputs->items[index]; + wlr_conn = drm->outputs->items[index]; seen[index] = true; } - if (output->state == WLR_DRM_OUTPUT_DISCONNECTED && - conn->connection == DRM_MODE_CONNECTED) { + if (wlr_conn->state == WLR_DRM_CONN_DISCONNECTED && + drm_conn->connection == DRM_MODE_CONNECTED) { - wlr_log(L_INFO, "'%s' connected", output->output.name); + wlr_log(L_INFO, "'%s' connected", wlr_conn->output.name); wlr_log(L_INFO, "Detected modes:"); - for (int i = 0; i < conn->count_modes; ++i) { - struct wlr_drm_output_mode *mode = calloc(1, - sizeof(struct wlr_drm_output_mode)); + for (int i = 0; i < drm_conn->count_modes; ++i) { + struct wlr_drm_mode *mode = calloc(1, sizeof(*mode)); if (!mode) { wlr_log_errno(L_ERROR, "Allocation failed"); continue; } - mode->mode = conn->modes[i]; - mode->wlr_mode.width = mode->mode.hdisplay; - mode->wlr_mode.height = mode->mode.vdisplay; - mode->wlr_mode.refresh = calculate_refresh_rate(&mode->mode); + mode->drm_mode = drm_conn->modes[i]; + mode->wlr_mode.width = mode->drm_mode.hdisplay; + mode->wlr_mode.height = mode->drm_mode.vdisplay; + mode->wlr_mode.refresh = calculate_refresh_rate(&mode->drm_mode); wlr_log(L_INFO, " %"PRId32"@%"PRId32"@%"PRId32, mode->wlr_mode.width, mode->wlr_mode.height, mode->wlr_mode.refresh); - if (list_add(output->output.modes, mode) == -1) { + if (list_add(wlr_conn->output.modes, mode) == -1) { wlr_log_errno(L_ERROR, "Allocation failed"); free(mode); continue; } } - output->state = WLR_DRM_OUTPUT_NEEDS_MODESET; - wlr_log(L_INFO, "Sending modesetting signal for '%s'", output->output.name); - wl_signal_emit(&drm->backend.events.output_add, &output->output); - } else if (output->state == WLR_DRM_OUTPUT_CONNECTED && - conn->connection != DRM_MODE_CONNECTED) { + wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET; + wlr_log(L_INFO, "Sending modesetting signal for '%s'", + wlr_conn->output.name); + wl_signal_emit(&drm->backend.events.output_add, &wlr_conn->output); + } else if (wlr_conn->state == WLR_DRM_CONN_CONNECTED && + drm_conn->connection != DRM_MODE_CONNECTED) { - wlr_log(L_INFO, "'%s' disconnected", output->output.name); - wlr_drm_output_cleanup(output); + wlr_log(L_INFO, "'%s' disconnected", wlr_conn->output.name); + wlr_drm_connector_cleanup(wlr_conn); } - drmModeFreeConnector(conn); + drmModeFreeConnector(drm_conn); } drmModeFreeResources(res); @@ -757,14 +759,14 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { continue; } - struct wlr_drm_output *output = drm->outputs->items[i]; + struct wlr_drm_connector *conn = drm->outputs->items[i]; - wlr_log(L_INFO, "'%s' disappeared", output->output.name); - wlr_drm_output_cleanup(output); + wlr_log(L_INFO, "'%s' disappeared", conn->output.name); + wlr_drm_connector_cleanup(conn); - drmModeFreeCrtc(output->old_crtc); - wl_event_source_remove(output->retry_pageflip); - free(output); + drmModeFreeCrtc(conn->old_crtc); + wl_event_source_remove(conn->retry_pageflip); + free(conn); list_del(drm->outputs, i); } @@ -772,22 +774,22 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { static void page_flip_handler(int fd, unsigned seq, unsigned tv_sec, unsigned tv_usec, void *user) { - struct wlr_drm_output *output = user; - struct wlr_drm_backend *drm = output->drm; + struct wlr_drm_connector *conn = user; + struct wlr_drm_backend *drm = conn->drm; - output->pageflip_pending = false; - if (output->state != WLR_DRM_OUTPUT_CONNECTED) { + conn->pageflip_pending = false; + if (conn->state != WLR_DRM_CONN_CONNECTED) { return; } - struct wlr_drm_plane *plane = output->crtc->primary; + struct wlr_drm_plane *plane = conn->crtc->primary; if (plane->surf.front) { gbm_surface_release_buffer(plane->surf.gbm, plane->surf.front); plane->surf.front = NULL; } if (drm->session->active) { - wl_signal_emit(&output->output.events.frame, &output->output); + wl_signal_emit(&conn->output.events.frame, &conn->output); } } @@ -805,9 +807,9 @@ void wlr_drm_restore_outputs(struct wlr_drm_backend *drm) { uint64_t to_close = (1 << drm->outputs->length) - 1; for (size_t i = 0; i < drm->outputs->length; ++i) { - struct wlr_drm_output *output = drm->outputs->items[i]; - if (output->state == WLR_DRM_OUTPUT_CONNECTED) { - output->state = WLR_DRM_OUTPUT_CLEANUP; + struct wlr_drm_connector *conn = drm->outputs->items[i]; + if (conn->state == WLR_DRM_CONN_CONNECTED) { + conn->state = WLR_DRM_CONN_CLEANUP; } } @@ -816,8 +818,8 @@ void wlr_drm_restore_outputs(struct wlr_drm_backend *drm) { while (to_close && time(NULL) < timeout) { wlr_drm_event(drm->fd, 0, NULL); for (size_t i = 0; i < drm->outputs->length; ++i) { - struct wlr_drm_output *output = drm->outputs->items[i]; - if (output->state != WLR_DRM_OUTPUT_CLEANUP || !output->pageflip_pending) { + struct wlr_drm_connector *conn = drm->outputs->items[i]; + if (conn->state != WLR_DRM_CONN_CLEANUP || !conn->pageflip_pending) { to_close &= ~(1 << i); } } @@ -828,29 +830,29 @@ void wlr_drm_restore_outputs(struct wlr_drm_backend *drm) { } for (size_t i = 0; i < drm->outputs->length; ++i) { - struct wlr_drm_output *output = drm->outputs->items[i]; - drmModeCrtc *crtc = output->old_crtc; + struct wlr_drm_connector *conn = drm->outputs->items[i]; + drmModeCrtc *crtc = conn->old_crtc; if (!crtc) { continue; } drmModeSetCrtc(drm->fd, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, - &output->connector, 1, &crtc->mode); + &conn->id, 1, &crtc->mode); drmModeFreeCrtc(crtc); } } -void wlr_drm_output_cleanup(struct wlr_drm_output *output) { - if (!output) { +void wlr_drm_connector_cleanup(struct wlr_drm_connector *conn) { + if (!conn) { return; } - struct wlr_drm_backend *drm = output->drm; + struct wlr_drm_backend *drm = conn->drm; - switch (output->state) { - case WLR_DRM_OUTPUT_CONNECTED: - case WLR_DRM_OUTPUT_CLEANUP:; - struct wlr_drm_crtc *crtc = output->crtc; + switch (conn->state) { + case WLR_DRM_CONN_CONNECTED: + case WLR_DRM_CONN_CLEANUP:; + struct wlr_drm_crtc *crtc = conn->crtc; for (int i = 0; i < 3; ++i) { wlr_drm_surface_finish(&drm->renderer, &crtc->planes[i]->surf); if (crtc->planes[i] && crtc->planes[i]->id == 0) { @@ -859,17 +861,17 @@ void wlr_drm_output_cleanup(struct wlr_drm_output *output) { } } - output->crtc = NULL; - output->possible_crtc = 0; + conn->crtc = NULL; + conn->possible_crtc = 0; /* Fallthrough */ - case WLR_DRM_OUTPUT_NEEDS_MODESET: + case WLR_DRM_CONN_NEEDS_MODESET: wlr_log(L_INFO, "Emmiting destruction signal for '%s'", - output->output.name); - wl_signal_emit(&drm->backend.events.output_remove, &output->output); + conn->output.name); + wl_signal_emit(&drm->backend.events.output_remove, &conn->output); break; - case WLR_DRM_OUTPUT_DISCONNECTED: + case WLR_DRM_CONN_DISCONNECTED: break; } - output->state = WLR_DRM_OUTPUT_DISCONNECTED; + conn->state = WLR_DRM_CONN_DISCONNECTED; } diff --git a/backend/drm/iface_atomic.c b/backend/drm/iface_atomic.c index 7e506fe7..1aef05d1 100644 --- a/backend/drm/iface_atomic.c +++ b/backend/drm/iface_atomic.c @@ -44,23 +44,23 @@ static bool atomic_end(int drm_fd, struct atomic *atom) { } static bool atomic_commit(int drm_fd, struct atomic *atom, - struct wlr_drm_output *output, uint32_t flag, bool modeset) { + struct wlr_drm_connector *conn, uint32_t flag, bool modeset) { if (atom->failed) { return false; } uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | flag; - int ret = drmModeAtomicCommit(drm_fd, atom->req, flags, output); + int ret = drmModeAtomicCommit(drm_fd, atom->req, flags, conn); if (ret) { wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", - output->output.name, modeset ? "modeset" : "pageflip"); + conn->output.name, modeset ? "modeset" : "pageflip"); // Try to commit without new changes drmModeAtomicSetCursor(atom->req, atom->cursor); - if (drmModeAtomicCommit(drm_fd, atom->req, flags, output)) { + if (drmModeAtomicCommit(drm_fd, atom->req, flags, conn)) { wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", - output->output.name, modeset ? "modeset" : "pageflip"); + conn->output.name, modeset ? "modeset" : "pageflip"); } } @@ -97,7 +97,7 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_plane *plane, } static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, - struct wlr_drm_output *output, + struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc, uint32_t fb_id, drmModeModeInfo *mode) { if (mode) { @@ -114,18 +114,18 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, struct atomic atom; atomic_begin(crtc, &atom); - atomic_add(&atom, output->connector, output->props.crtc_id, crtc->id); + atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id); atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id); atomic_add(&atom, crtc->id, crtc->props.active, 1); set_plane_props(&atom, crtc->primary, crtc->id, fb_id, true); - return atomic_commit(drm->fd, &atom, output, + return atomic_commit(drm->fd, &atom, conn, mode ? DRM_MODE_ATOMIC_ALLOW_MODESET : DRM_MODE_ATOMIC_NONBLOCK, mode); } static void atomic_conn_enable(struct wlr_drm_backend *drm, - struct wlr_drm_output *output, bool enable) { - struct wlr_drm_crtc *crtc = output->crtc; + struct wlr_drm_connector *conn, bool enable) { + struct wlr_drm_crtc *crtc = conn->crtc; struct atomic atom; atomic_begin(crtc, &atom); diff --git a/backend/drm/iface_legacy.c b/backend/drm/iface_legacy.c index ffa8157b..cf73bb87 100644 --- a/backend/drm/iface_legacy.c +++ b/backend/drm/iface_legacy.c @@ -7,18 +7,18 @@ #include "backend/drm/util.h" static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm, - struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, + struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc, uint32_t fb_id, drmModeModeInfo *mode) { if (mode) { if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0, - &output->connector, 1, mode)) { - wlr_log_errno(L_ERROR, "%s: Failed to set CRTC", output->output.name); + &conn->id, 1, mode)) { + wlr_log_errno(L_ERROR, "%s: Failed to set CRTC", conn->output.name); return false; } } - if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, output)) { - wlr_log_errno(L_ERROR, "%s: Failed to page flip", output->output.name); + if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, conn)) { + wlr_log_errno(L_ERROR, "%s: Failed to page flip", conn->output.name); return false; } @@ -26,8 +26,8 @@ static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm, } static void legacy_conn_enable(struct wlr_drm_backend *drm, - struct wlr_drm_output *output, bool enable) { - drmModeConnectorSetProperty(drm->fd, output->connector, output->props.dpms, + struct wlr_drm_connector *conn, bool enable) { + drmModeConnectorSetProperty(drm->fd, conn->id, conn->props.dpms, enable ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); } diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 6f1abc00..a3a724bc 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -55,16 +55,6 @@ struct wlr_drm_crtc { struct wl_list connectors; }; -struct wlr_drm_connector { - struct wlr_output *base; - uint32_t id; - struct wlr_drm_crtc *crtc; - - union wlr_drm_connector_props props; - - struct wl_list link; -}; - struct wlr_drm_backend { struct wlr_backend backend; @@ -107,24 +97,24 @@ struct wlr_drm_backend { struct wlr_session *session; }; -enum wlr_drm_output_state { - WLR_DRM_OUTPUT_DISCONNECTED, - WLR_DRM_OUTPUT_NEEDS_MODESET, - WLR_DRM_OUTPUT_CLEANUP, - WLR_DRM_OUTPUT_CONNECTED, +enum wlr_drm_connector_state { + WLR_DRM_CONN_DISCONNECTED, + WLR_DRM_CONN_NEEDS_MODESET, + WLR_DRM_CONN_CLEANUP, + WLR_DRM_CONN_CONNECTED, }; -struct wlr_drm_output_mode { +struct wlr_drm_mode { struct wlr_output_mode wlr_mode; - drmModeModeInfo mode; + drmModeModeInfo drm_mode; }; -struct wlr_drm_output { +struct wlr_drm_connector { struct wlr_output output; struct wlr_drm_backend *drm; - enum wlr_drm_output_state state; - uint32_t connector; + enum wlr_drm_connector_state state; + uint32_t id; struct wlr_drm_crtc *crtc; uint32_t possible_crtc; @@ -144,10 +134,10 @@ bool wlr_drm_check_features(struct wlr_drm_backend *drm); bool wlr_drm_resources_init(struct wlr_drm_backend *drm); void wlr_drm_resources_free(struct wlr_drm_backend *drm); void wlr_drm_restore_outputs(struct wlr_drm_backend *drm); -void wlr_drm_output_cleanup(struct wlr_drm_output *output); +void wlr_drm_connector_cleanup(struct wlr_drm_connector *conn); void wlr_drm_scan_connectors(struct wlr_drm_backend *state); int wlr_drm_event(int fd, uint32_t mask, void *data); -void wlr_drm_output_start_renderer(struct wlr_drm_output *output); +void wlr_drm_connector_start_renderer(struct wlr_drm_connector *conn); #endif diff --git a/include/backend/drm/iface.h b/include/backend/drm/iface.h index 291b9a30..db1d7ee1 100644 --- a/include/backend/drm/iface.h +++ b/include/backend/drm/iface.h @@ -9,17 +9,17 @@ #include struct wlr_drm_backend; -struct wlr_drm_output; +struct wlr_drm_connector; struct wlr_drm_crtc; // Used to provide atomic or legacy DRM functions struct wlr_drm_interface { - // Enable or disable DPMS for output + // Enable or disable DPMS for connector void (*conn_enable)(struct wlr_drm_backend *drm, - struct wlr_drm_output *output, bool enable); + struct wlr_drm_connector *conn, bool enable); // Pageflip on crtc. If mode is non-NULL perform a full modeset using it. bool (*crtc_pageflip)(struct wlr_drm_backend *drm, - struct wlr_drm_output *output, struct wlr_drm_crtc *crtc, + struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc, uint32_t fb_id, drmModeModeInfo *mode); // Enable the cursor buffer on crtc. Set bo to NULL to disable bool (*crtc_set_cursor)(struct wlr_drm_backend *drm, -- cgit v1.2.3 From eaef028976d32e382c4ebcfbb8605a6f40cd22b8 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sun, 1 Oct 2017 15:55:25 +1300 Subject: Add renderer pointer inside drm_surface --- backend/drm/drm.c | 20 ++++++++++---------- backend/drm/renderer.c | 33 +++++++++++++++------------------ include/backend/drm/renderer.h | 22 ++++++++-------------- 3 files changed, 33 insertions(+), 42 deletions(-) (limited to 'include/backend/drm') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 676f5f7b..5c5ac8cd 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -175,7 +175,7 @@ void wlr_drm_resources_free(struct wlr_drm_backend *drm) { static void wlr_drm_connector_make_current(struct wlr_output *output) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; - wlr_drm_surface_make_current(&conn->drm->renderer, &conn->crtc->primary->surf); + wlr_drm_surface_make_current(&conn->crtc->primary->surf); } static void wlr_drm_connector_swap_buffers(struct wlr_output *output) { @@ -185,7 +185,7 @@ static void wlr_drm_connector_swap_buffers(struct wlr_output *output) { struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_plane *plane = crtc->primary; - struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&drm->renderer, &plane->surf); + struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&plane->surf); uint32_t fb_id = get_fb_for_bo(bo); if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) { @@ -217,7 +217,7 @@ void wlr_drm_connector_start_renderer(struct wlr_drm_connector *conn) { struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_plane *plane = crtc->primary; - struct gbm_bo *bo = wlr_drm_surface_get_front(&drm->renderer, &plane->surf); + struct gbm_bo *bo = wlr_drm_surface_get_front(&plane->surf); uint32_t fb_id = get_fb_for_bo(bo); struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode; @@ -283,9 +283,9 @@ static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in) if (*old != new) { if (*old) { - wlr_drm_surface_finish(&drm->renderer, &(*old)->surf); + wlr_drm_surface_finish(&(*old)->surf); } - wlr_drm_surface_finish(&drm->renderer, &new->surf); + wlr_drm_surface_finish(&new->surf); *old = new; } } @@ -430,7 +430,7 @@ static bool wlr_drm_connector_set_mode(struct wlr_output *output, continue; } - if (!wlr_drm_surface_init(&drm->renderer, &crtc->primary->surf, + if (!wlr_drm_surface_init(&crtc->primary->surf, &drm->renderer, mode->width, mode->height, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT)) { wlr_log(L_ERROR, "Failed to initalise renderer for plane"); @@ -488,7 +488,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, return false; } - if (!wlr_drm_surface_init(renderer, &plane->surf, w, h, GBM_FORMAT_ARGB8888, 0)) { + if (!wlr_drm_surface_init(&plane->surf, renderer, w, h, GBM_FORMAT_ARGB8888, 0)) { wlr_log(L_ERROR, "Cannot allocate cursor resources"); return false; } @@ -530,7 +530,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, return false; } - wlr_drm_surface_make_current(renderer, &plane->surf); + wlr_drm_surface_make_current(&plane->surf); wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, stride, width, height, buf); @@ -548,7 +548,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, glReadPixels(0, 0, plane->surf.width, plane->surf.height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bo_data); glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); - wlr_drm_surface_swap_buffers(renderer, &plane->surf); + wlr_drm_surface_swap_buffers(&plane->surf); gbm_bo_unmap(bo, bo_data); @@ -854,7 +854,7 @@ void wlr_drm_connector_cleanup(struct wlr_drm_connector *conn) { case WLR_DRM_CONN_CLEANUP:; struct wlr_drm_crtc *crtc = conn->crtc; for (int i = 0; i < 3; ++i) { - wlr_drm_surface_finish(&drm->renderer, &crtc->planes[i]->surf); + wlr_drm_surface_finish(&crtc->planes[i]->surf); if (crtc->planes[i] && crtc->planes[i]->id == 0) { free(crtc->planes[i]); crtc->planes[i] = NULL; diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 8afc6dca..e1c6a4bc 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -35,13 +35,14 @@ void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer) { gbm_device_destroy(renderer->gbm); } -bool wlr_drm_surface_init(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf, uint32_t width, uint32_t height, +bool wlr_drm_surface_init(struct wlr_drm_surface *surf, + struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { if (surf->width == width && surf->height == height) { return true; } + surf->renderer = renderer; surf->width = width; surf->height = height; @@ -67,13 +68,12 @@ error_zero: return false; } -void wlr_drm_surface_finish(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf) { - if (!renderer || !surf || !surf->gbm) { +void wlr_drm_surface_finish(struct wlr_drm_surface *surf) { + if (!surf || !surf->renderer) { return; } - eglMakeCurrent(renderer->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, + eglMakeCurrent(surf->renderer->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (surf->front) { @@ -84,7 +84,7 @@ void wlr_drm_surface_finish(struct wlr_drm_renderer *renderer, } if (surf->egl) { - eglDestroySurface(renderer->egl.display, surf->egl); + eglDestroySurface(surf->renderer->egl.display, surf->egl); } if (surf->gbm) { gbm_surface_destroy(surf->gbm); @@ -93,34 +93,31 @@ void wlr_drm_surface_finish(struct wlr_drm_renderer *renderer, memset(surf, 0, sizeof(*surf)); } -void wlr_drm_surface_make_current(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf) { - eglMakeCurrent(renderer->egl.display, surf->egl, surf->egl, - renderer->egl.context); +void wlr_drm_surface_make_current(struct wlr_drm_surface *surf) { + eglMakeCurrent(surf->renderer->egl.display, surf->egl, surf->egl, + surf->renderer->egl.context); } -struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf) { +struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf) { if (surf->front) { gbm_surface_release_buffer(surf->gbm, surf->front); } - eglSwapBuffers(renderer->egl.display, surf->egl); + eglSwapBuffers(surf->renderer->egl.display, surf->egl); surf->front = surf->back; surf->back = gbm_surface_lock_front_buffer(surf->gbm); return surf->back; } -struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf) { +struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *surf) { if (surf->front) { return surf->front; } - wlr_drm_surface_make_current(renderer, surf); + wlr_drm_surface_make_current(surf); glViewport(0, 0, surf->width, surf->height); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); - return wlr_drm_surface_swap_buffers(renderer, surf); + return wlr_drm_surface_swap_buffers(surf); } diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h index bbcf4f0c..9982c25f 100644 --- a/include/backend/drm/renderer.h +++ b/include/backend/drm/renderer.h @@ -14,6 +14,8 @@ struct wlr_drm_renderer { }; struct wlr_drm_surface { + struct wlr_drm_renderer *renderer; + uint32_t width; uint32_t height; @@ -25,23 +27,15 @@ struct wlr_drm_surface { }; bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd); - void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer); -bool wlr_drm_surface_init(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf, uint32_t width, uint32_t height, +bool wlr_drm_surface_init(struct wlr_drm_surface *surf, + struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); -void wlr_drm_surface_finish(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf); - -void wlr_drm_surface_make_current(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf); - -struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf); - -struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_renderer *renderer, - struct wlr_drm_surface *surf); +void wlr_drm_surface_finish(struct wlr_drm_surface *surf); +void wlr_drm_surface_make_current(struct wlr_drm_surface *surf); +struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf); +struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *surf); #endif -- cgit v1.2.3 From 009c3747a8771bcd441dc9cf95823fe40895f1e0 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sun, 1 Oct 2017 19:22:47 +1300 Subject: Multi-GPU DRM --- backend/backend.c | 3 +- backend/drm/backend.c | 4 +- backend/drm/drm.c | 21 ++++---- backend/drm/renderer.c | 117 +++++++++++++++++++++++++++++++++++++++++ include/backend/drm/drm.h | 2 + include/backend/drm/renderer.h | 11 ++++ include/wlr/backend/drm.h | 2 +- include/wlr/render.h | 9 +++- include/wlr/render/interface.h | 4 ++ render/gles2/texture.c | 20 +++++++ render/wlr_texture.c | 5 ++ 11 files changed, 184 insertions(+), 14 deletions(-) (limited to 'include/backend/drm') diff --git a/backend/backend.c b/backend/backend.c index 359df3d1..d5cd1f70 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -109,7 +109,8 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) { wlr_log(L_INFO, "Found %zu GPUs", num_gpus); for (size_t i = 0; i < num_gpus; ++i) { - struct wlr_backend *drm = wlr_drm_backend_create(display, session, gpus[i]); + struct wlr_backend *drm = wlr_drm_backend_create(display, session, + gpus[i], primary_drm); if (!drm) { wlr_log(L_ERROR, "Failed to open DRM device"); continue; diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 2d06e5e4..e3148821 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -92,8 +92,9 @@ static void drm_invalidated(struct wl_listener *listener, void *data) { } struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, - struct wlr_session *session, int gpu_fd) { + struct wlr_session *session, int gpu_fd, struct wlr_backend *parent) { assert(display && session && gpu_fd >= 0); + assert(!parent || wlr_backend_is_drm(parent)); char *name = drmGetDeviceNameFromFd2(gpu_fd); drmVersion *version = drmGetVersion(gpu_fd); @@ -116,6 +117,7 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, } drm->fd = gpu_fd; + drm->parent = (struct wlr_drm_backend *)parent; drm->drm_invalidated.notify = drm_invalidated; wlr_session_signal_add(session, gpu_fd, &drm->drm_invalidated); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 5c5ac8cd..3effa9ff 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -186,6 +186,10 @@ static void wlr_drm_connector_swap_buffers(struct wlr_output *output) { struct wlr_drm_plane *plane = crtc->primary; struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&plane->surf); + if (drm->parent) { + bo = wlr_drm_surface_mgpu_copy(&plane->mgpu_surf, bo); + } + uint32_t fb_id = get_fb_for_bo(bo); if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) { @@ -217,7 +221,8 @@ void wlr_drm_connector_start_renderer(struct wlr_drm_connector *conn) { struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_plane *plane = crtc->primary; - struct gbm_bo *bo = wlr_drm_surface_get_front(&plane->surf); + struct gbm_bo *bo = wlr_drm_surface_get_front( + drm->parent ? &plane->mgpu_surf : &plane->surf); uint32_t fb_id = get_fb_for_bo(bo); struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode; @@ -393,7 +398,6 @@ static bool wlr_drm_connector_set_mode(struct wlr_output *output, wlr_log(L_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", conn->output.name, mode->width, mode->height, mode->refresh); - wlr_log(L_DEBUG, "%p %p", conn, drm); conn->possible_crtc = get_possible_crtcs(drm->fd, conn->id); if (conn->possible_crtc == 0) { goto error_conn; @@ -430,9 +434,8 @@ static bool wlr_drm_connector_set_mode(struct wlr_output *output, continue; } - if (!wlr_drm_surface_init(&crtc->primary->surf, &drm->renderer, - mode->width, mode->height, GBM_FORMAT_XRGB8888, - GBM_BO_USE_SCANOUT)) { + if (!wlr_drm_plane_surfaces_init(crtc->primary, drm, + mode->width, mode->height, GBM_FORMAT_XRGB8888)) { wlr_log(L_ERROR, "Failed to initalise renderer for plane"); goto error_conn; } @@ -782,10 +785,9 @@ static void page_flip_handler(int fd, unsigned seq, return; } - struct wlr_drm_plane *plane = conn->crtc->primary; - if (plane->surf.front) { - gbm_surface_release_buffer(plane->surf.gbm, plane->surf.front); - plane->surf.front = NULL; + wlr_drm_surface_post(&conn->crtc->primary->surf); + if (drm->parent) { + wlr_drm_surface_post(&conn->crtc->primary->mgpu_surf); } if (drm->session->active) { @@ -855,6 +857,7 @@ void wlr_drm_connector_cleanup(struct wlr_drm_connector *conn) { struct wlr_drm_crtc *crtc = conn->crtc; for (int i = 0; i < 3; ++i) { wlr_drm_surface_finish(&crtc->planes[i]->surf); + wlr_drm_surface_finish(&crtc->planes[i]->mgpu_surf); if (crtc->planes[i] && crtc->planes[i]->id == 0) { free(crtc->planes[i]); crtc->planes[i] = NULL; diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index e1c6a4bc..bcadf17e 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -1,12 +1,18 @@ #include +#include +#include #include #include #include #include +#include #include #include +#include +#include +#include #include "backend/drm/drm.h" bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) { @@ -22,6 +28,9 @@ bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) { return false; } + struct wlr_drm_backend *drm = wl_container_of(renderer, drm, renderer); + renderer->wlr_rend = wlr_gles2_renderer_create(&drm->backend); + renderer->fd = fd; return true; } @@ -121,3 +130,111 @@ struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *surf) { glClear(GL_COLOR_BUFFER_BIT); return wlr_drm_surface_swap_buffers(surf); } + +void wlr_drm_surface_post(struct wlr_drm_surface *surf) { + if (surf->front) { + gbm_surface_release_buffer(surf->gbm, surf->front); + surf->front = NULL; + } +} + +struct tex { + struct wlr_egl *egl; + EGLImageKHR img; + struct wlr_texture *tex; +}; + +static void free_eglimage(struct gbm_bo *bo, void *data) { + struct tex *tex = data; + + wlr_egl_destroy_image(tex->egl, tex->img); + wlr_texture_destroy(tex->tex); + free(tex); +} + +static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, struct gbm_bo *bo) { + struct tex *tex = gbm_bo_get_user_data(bo); + if (tex) { + return tex->tex; + } + + tex = malloc(sizeof(*tex)); + if (!tex) { + wlr_log_errno(L_ERROR, "Allocation failed"); + return NULL; + } + + tex->egl = &renderer->egl; + + int dmabuf_fd = gbm_bo_get_fd(bo); + uint32_t width = gbm_bo_get_width(bo); + uint32_t height = gbm_bo_get_height(bo); + + EGLint attribs[] = { + EGL_WIDTH, width, + EGL_HEIGHT, height, + EGL_LINUX_DRM_FOURCC_EXT, gbm_bo_get_format(bo), + EGL_DMA_BUF_PLANE0_FD_EXT, dmabuf_fd, + EGL_DMA_BUF_PLANE0_OFFSET_EXT, gbm_bo_get_offset(bo, 0), + EGL_DMA_BUF_PLANE0_PITCH_EXT, gbm_bo_get_stride_for_plane(bo, 0), + EGL_IMAGE_PRESERVED_KHR, EGL_FALSE, + EGL_NONE, + }; + + tex->img = renderer->egl.eglCreateImageKHR(renderer->egl.display, EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, NULL, attribs); + if (!tex->img) { + wlr_log(L_ERROR, "Failed to create EGL image: %s", egl_error()); + abort(); + } + + tex->tex = wlr_render_texture_create(renderer->wlr_rend); + wlr_texture_upload_eglimage(tex->tex, tex->img, width, height); + + gbm_bo_set_user_data(bo, tex, free_eglimage); + + return tex->tex; +} + +struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, struct gbm_bo *src) { + wlr_drm_surface_make_current(dest); + + struct wlr_texture *tex = get_tex_for_bo(dest->renderer, src); + + static const float matrix[16] = { + [0] = 2.0f, + [3] = -1.0f, + [5] = 2.0f, + [7] = -1.0f, + [10] = 1.0f, + [15] = 1.0f, + }; + + glViewport(0, 0, dest->width, dest->height); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + wlr_render_with_matrix(dest->renderer->wlr_rend, tex, &matrix); + + return wlr_drm_surface_swap_buffers(dest); +} + +bool wlr_drm_plane_surfaces_init(struct wlr_drm_plane *plane, struct wlr_drm_backend *drm, + int32_t width, uint32_t height, uint32_t format) { + if (!drm->parent) { + return wlr_drm_surface_init(&plane->surf, &drm->renderer, width, height, + format, GBM_BO_USE_SCANOUT); + } + + if (!wlr_drm_surface_init(&plane->surf, &drm->parent->renderer, + width, height, format, GBM_BO_USE_LINEAR)) { + return false; + } + + if (!wlr_drm_surface_init(&plane->mgpu_surf, &drm->renderer, + width, height, format, GBM_BO_USE_SCANOUT)) { + wlr_drm_surface_finish(&plane->surf); + return false; + } + + return true; +} diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index a3a724bc..6106a85a 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -26,6 +26,7 @@ struct wlr_drm_plane { uint32_t possible_crtcs; struct wlr_drm_surface surf; + struct wlr_drm_surface mgpu_surf; // Only used by cursor float matrix[16]; @@ -58,6 +59,7 @@ struct wlr_drm_crtc { struct wlr_drm_backend { struct wlr_backend backend; + struct wlr_drm_backend *parent; const struct wlr_drm_interface *iface; int fd; diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h index 9982c25f..8fcf566d 100644 --- a/include/backend/drm/renderer.h +++ b/include/backend/drm/renderer.h @@ -7,10 +7,16 @@ #include #include +#include + +struct wlr_drm_plane; + struct wlr_drm_renderer { int fd; struct gbm_device *gbm; struct wlr_egl egl; + + struct wlr_renderer *wlr_rend; }; struct wlr_drm_surface { @@ -33,9 +39,14 @@ bool wlr_drm_surface_init(struct wlr_drm_surface *surf, struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); +bool wlr_drm_plane_surfaces_init(struct wlr_drm_plane *plane, struct wlr_drm_backend *drm, + int32_t width, uint32_t height, uint32_t format); + void wlr_drm_surface_finish(struct wlr_drm_surface *surf); void wlr_drm_surface_make_current(struct wlr_drm_surface *surf); struct gbm_bo *wlr_drm_surface_swap_buffers(struct wlr_drm_surface *surf); struct gbm_bo *wlr_drm_surface_get_front(struct wlr_drm_surface *surf); +void wlr_drm_surface_post(struct wlr_drm_surface *surf); +struct gbm_bo *wlr_drm_surface_mgpu_copy(struct wlr_drm_surface *dest, struct gbm_bo *src); #endif diff --git a/include/wlr/backend/drm.h b/include/wlr/backend/drm.h index fa63df0a..b3475703 100644 --- a/include/wlr/backend/drm.h +++ b/include/wlr/backend/drm.h @@ -6,7 +6,7 @@ #include struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, - struct wlr_session *session, int gpu_fd); + struct wlr_session *session, int gpu_fd, struct wlr_backend *parent); bool wlr_backend_is_drm(struct wlr_backend *backend); diff --git a/include/wlr/render.h b/include/wlr/render.h index 325f8c01..2fbfb476 100644 --- a/include/wlr/render.h +++ b/include/wlr/render.h @@ -2,6 +2,8 @@ #define WLR_RENDER_H #include +#include +#include #include #include @@ -93,8 +95,11 @@ bool wlr_texture_upload_shm(struct wlr_texture *tex, uint32_t format, * texture. The wl_resource is not used after this call. * Will fail (return false) if the given resource is no drm buffer. */ - bool wlr_texture_upload_drm(struct wlr_texture *tex, - struct wl_resource *drm_buffer); +bool wlr_texture_upload_drm(struct wlr_texture *tex, + struct wl_resource *drm_buffer); + +bool wlr_texture_upload_eglimage(struct wlr_texture *tex, + EGLImageKHR image, uint32_t width, uint32_t height); /** * Copies a rectangle of pixels from a wl_shm_buffer onto the texture. The diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index e3ba0414..cbe33822 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -2,6 +2,8 @@ #define WLR_RENDER_INTERFACE_H #include +#include +#include #include #include #include @@ -45,6 +47,8 @@ struct wlr_texture_impl { int x, int y, int width, int height, struct wl_shm_buffer *shm); bool (*upload_drm)(struct wlr_texture *texture, struct wl_resource *drm_buf); + bool (*upload_eglimage)(struct wlr_texture *texture, EGLImageKHR image, + uint32_t width, uint32_t height); void (*get_matrix)(struct wlr_texture *state, float (*matrix)[16], const float (*projection)[16], int x, int y); void (*get_buffer_size)(struct wlr_texture *texture, diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 98d1a112..5e934aa4 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -205,6 +205,25 @@ static bool gles2_texture_upload_drm(struct wlr_texture *_tex, return true; } +static bool gles2_texture_upload_eglimage(struct wlr_texture *wlr_tex, + EGLImageKHR image, uint32_t width, uint32_t height) { + struct wlr_gles2_texture *tex = (struct wlr_gles2_texture *)wlr_tex; + + tex->image = image; + tex->pixel_format = &external_pixel_format; + tex->wlr_texture.valid = true; + tex->wlr_texture.width = width; + tex->wlr_texture.height = height; + + gles2_texture_ensure_texture(tex); + + GL_CALL(glActiveTexture(GL_TEXTURE0)); + GL_CALL(glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex->tex_id)); + GL_CALL(glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, tex->image)); + + return true; +} + static void gles2_texture_get_matrix(struct wlr_texture *_texture, float (*matrix)[16], const float (*projection)[16], int x, int y) { struct wlr_gles2_texture *texture = (struct wlr_gles2_texture *)_texture; @@ -270,6 +289,7 @@ static struct wlr_texture_impl wlr_texture_impl = { .upload_shm = gles2_texture_upload_shm, .update_shm = gles2_texture_update_shm, .upload_drm = gles2_texture_upload_drm, + .upload_eglimage = gles2_texture_upload_eglimage, .get_matrix = gles2_texture_get_matrix, .get_buffer_size = gles2_texture_get_buffer_size, .bind = gles2_texture_bind, diff --git a/render/wlr_texture.c b/render/wlr_texture.c index 9faea820..4ce86bdd 100644 --- a/render/wlr_texture.c +++ b/render/wlr_texture.c @@ -48,6 +48,11 @@ bool wlr_texture_upload_drm(struct wlr_texture *texture, return texture->impl->upload_drm(texture, drm_buffer); } +bool wlr_texture_upload_eglimage(struct wlr_texture *texture, + EGLImageKHR image, uint32_t width, uint32_t height) { + return texture->impl->upload_eglimage(texture, image, width, height); +} + void wlr_texture_get_matrix(struct wlr_texture *texture, float (*matrix)[16], const float (*projection)[16], int x, int y) { texture->impl->get_matrix(texture, matrix, projection, x, y); -- cgit v1.2.3 From f6f9c4096544fa64b7814ac55718f1c128c15004 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sun, 1 Oct 2017 22:44:24 +1300 Subject: Minor fixes --- backend/drm/backend.c | 2 +- backend/drm/drm.c | 6 +++++- backend/drm/renderer.c | 22 ++++++++++++++++------ include/backend/drm/renderer.h | 4 +++- 4 files changed, 25 insertions(+), 9 deletions(-) (limited to 'include/backend/drm') diff --git a/backend/drm/backend.c b/backend/drm/backend.c index e3148821..468fca6e 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -143,7 +143,7 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, goto error_event; } - if (!wlr_drm_renderer_init(&drm->renderer, drm->fd)) { + if (!wlr_drm_renderer_init(drm, &drm->renderer)) { wlr_log(L_ERROR, "Failed to initialize renderer"); goto error_event; } diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 3effa9ff..ccdc92d9 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -856,9 +856,13 @@ void wlr_drm_connector_cleanup(struct wlr_drm_connector *conn) { case WLR_DRM_CONN_CLEANUP:; struct wlr_drm_crtc *crtc = conn->crtc; for (int i = 0; i < 3; ++i) { + if (!crtc->planes[i]) { + continue; + } + wlr_drm_surface_finish(&crtc->planes[i]->surf); wlr_drm_surface_finish(&crtc->planes[i]->mgpu_surf); - if (crtc->planes[i] && crtc->planes[i]->id == 0) { + if (crtc->planes[i]->id == 0) { free(crtc->planes[i]); crtc->planes[i] = NULL; } diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index bcadf17e..c5840436 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -15,8 +15,9 @@ #include #include "backend/drm/drm.h" -bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) { - renderer->gbm = gbm_create_device(fd); +bool wlr_drm_renderer_init(struct wlr_drm_backend *drm, + struct wlr_drm_renderer *renderer) { + renderer->gbm = gbm_create_device(drm->fd); if (!renderer->gbm) { wlr_log(L_ERROR, "Failed to create GBM device"); return false; @@ -24,15 +25,23 @@ bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd) { if (!wlr_egl_init(&renderer->egl, EGL_PLATFORM_GBM_MESA, GBM_FORMAT_ARGB8888, renderer->gbm)) { - gbm_device_destroy(renderer->gbm); - return false; + goto error_gbm; } - struct wlr_drm_backend *drm = wl_container_of(renderer, drm, renderer); renderer->wlr_rend = wlr_gles2_renderer_create(&drm->backend); + if (!renderer->wlr_rend) { + wlr_log(L_ERROR, "Failed to create WLR renderer"); + goto error_egl; + } - renderer->fd = fd; + renderer->fd = drm->fd; return true; + +error_egl: + wlr_egl_free(&renderer->egl); +error_gbm: + gbm_device_destroy(renderer->gbm); + return false; } void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer) { @@ -40,6 +49,7 @@ void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer) { return; } + wlr_renderer_destroy(renderer->wlr_rend); wlr_egl_free(&renderer->egl); gbm_device_destroy(renderer->gbm); } diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h index 8fcf566d..45127cd0 100644 --- a/include/backend/drm/renderer.h +++ b/include/backend/drm/renderer.h @@ -9,6 +9,7 @@ #include +struct wlr_drm_backend; struct wlr_drm_plane; struct wlr_drm_renderer { @@ -32,7 +33,8 @@ struct wlr_drm_surface { struct gbm_bo *back; }; -bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, int fd); +bool wlr_drm_renderer_init(struct wlr_drm_backend *drm, + struct wlr_drm_renderer *renderer); void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer); bool wlr_drm_surface_init(struct wlr_drm_surface *surf, -- cgit v1.2.3 From f193623ca11c245e9209a8df40115dbe420bbc22 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Mon, 2 Oct 2017 21:44:33 +1300 Subject: Change iface prefix to suffix --- backend/drm/atomic.c | 189 ++++++++++++++++++++++++++++++++++++++++++++ backend/drm/drm.c | 6 +- backend/drm/iface_atomic.c | 189 -------------------------------------------- backend/drm/iface_legacy.c | 66 ---------------- backend/drm/legacy.c | 66 ++++++++++++++++ backend/meson.build | 4 +- include/backend/drm/iface.h | 4 +- 7 files changed, 262 insertions(+), 262 deletions(-) create mode 100644 backend/drm/atomic.c delete mode 100644 backend/drm/iface_atomic.c delete mode 100644 backend/drm/iface_legacy.c create mode 100644 backend/drm/legacy.c (limited to 'include/backend/drm') diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c new file mode 100644 index 00000000..e7374a00 --- /dev/null +++ b/backend/drm/atomic.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include "backend/drm/drm.h" +#include "backend/drm/iface.h" +#include "backend/drm/util.h" + +struct atomic { + drmModeAtomicReq *req; + int cursor; + bool failed; +}; + +static void atomic_begin(struct wlr_drm_crtc *crtc, struct atomic *atom) { + if (!crtc->atomic) { + crtc->atomic = drmModeAtomicAlloc(); + if (!crtc->atomic) { + wlr_log_errno(L_ERROR, "Allocation failed"); + atom->failed = true; + return; + } + } + + atom->req = crtc->atomic; + atom->cursor = drmModeAtomicGetCursor(atom->req); + atom->failed = false; +} + +static bool atomic_end(int drm_fd, struct atomic *atom) { + if (atom->failed) { + return false; + } + + uint32_t flags = DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK; + + if (drmModeAtomicCommit(drm_fd, atom->req, flags, NULL)) { + wlr_log_errno(L_ERROR, "Atomic test failed"); + drmModeAtomicSetCursor(atom->req, atom->cursor); + return false; + } + + return true; +} + +static bool atomic_commit(int drm_fd, struct atomic *atom, + struct wlr_drm_connector *conn, uint32_t flag, bool modeset) { + if (atom->failed) { + return false; + } + + uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | flag; + + int ret = drmModeAtomicCommit(drm_fd, atom->req, flags, conn); + if (ret) { + wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", + conn->output.name, modeset ? "modeset" : "pageflip"); + + // Try to commit without new changes + drmModeAtomicSetCursor(atom->req, atom->cursor); + if (drmModeAtomicCommit(drm_fd, atom->req, flags, conn)) { + wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", + conn->output.name, modeset ? "modeset" : "pageflip"); + } + } + + drmModeAtomicSetCursor(atom->req, 0); + + return !ret; +} + +static inline void atomic_add(struct atomic *atom, uint32_t id, uint32_t prop, uint64_t val) { + if (!atom->failed && drmModeAtomicAddProperty(atom->req, id, prop, val) < 0) { + wlr_log_errno(L_ERROR, "Failed to add atomic DRM property"); + atom->failed = true; + } +} + +static void set_plane_props(struct atomic *atom, struct wlr_drm_plane *plane, + uint32_t crtc_id, uint32_t fb_id, bool set_crtc_xy) { + uint32_t id = plane->id; + const union wlr_drm_plane_props *props = &plane->props; + + // The src_* properties are in 16.16 fixed point + atomic_add(atom, id, props->src_x, 0); + atomic_add(atom, id, props->src_y, 0); + atomic_add(atom, id, props->src_w, plane->surf.width << 16); + atomic_add(atom, id, props->src_h, plane->surf.height << 16); + atomic_add(atom, id, props->crtc_w, plane->surf.width); + atomic_add(atom, id, props->crtc_h, plane->surf.height); + atomic_add(atom, id, props->fb_id, fb_id); + atomic_add(atom, id, props->crtc_id, crtc_id); + if (set_crtc_xy) { + atomic_add(atom, id, props->crtc_x, 0); + atomic_add(atom, id, props->crtc_y, 0); + } +} + +static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, + struct wlr_drm_connector *conn, + struct wlr_drm_crtc *crtc, + uint32_t fb_id, drmModeModeInfo *mode) { + if (mode) { + if (crtc->mode_id) { + drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); + } + + if (drmModeCreatePropertyBlob(drm->fd, mode, sizeof(*mode), &crtc->mode_id)) { + wlr_log_errno(L_ERROR, "Unable to create property blob"); + return false; + } + } + + struct atomic atom; + + atomic_begin(crtc, &atom); + atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id); + atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id); + atomic_add(&atom, crtc->id, crtc->props.active, 1); + set_plane_props(&atom, crtc->primary, crtc->id, fb_id, true); + return atomic_commit(drm->fd, &atom, conn, + mode ? DRM_MODE_ATOMIC_ALLOW_MODESET : DRM_MODE_ATOMIC_NONBLOCK, + mode); +} + +static void atomic_conn_enable(struct wlr_drm_backend *drm, + struct wlr_drm_connector *conn, bool enable) { + struct wlr_drm_crtc *crtc = conn->crtc; + struct atomic atom; + + atomic_begin(crtc, &atom); + atomic_add(&atom, crtc->id, crtc->props.active, enable); + atomic_end(drm->fd, &atom); +} + +bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, struct gbm_bo *bo); + +static bool atomic_crtc_set_cursor(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, struct gbm_bo *bo) { + if (!crtc || !crtc->cursor) { + return true; + } + + struct wlr_drm_plane *plane = crtc->cursor; + // We can't use atomic operations on fake planes + if (plane->id == 0) { + return legacy_crtc_set_cursor(drm, crtc, bo); + } + + struct atomic atom; + + atomic_begin(crtc, &atom); + + if (bo) { + set_plane_props(&atom, plane, crtc->id, get_fb_for_bo(bo), false); + } else { + atomic_add(&atom, plane->id, plane->props.fb_id, 0); + atomic_add(&atom, plane->id, plane->props.crtc_id, 0); + } + + return atomic_end(drm->fd, &atom); +} + +bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, int x, int y); + +static bool atomic_crtc_move_cursor(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, int x, int y) { + struct wlr_drm_plane *plane = crtc->cursor; + // We can't use atomic operations on fake planes + if (plane->id == 0) { + return legacy_crtc_move_cursor(drm, crtc, x, y); + } + + struct atomic atom; + + atomic_begin(crtc, &atom); + atomic_add(&atom, plane->id, plane->props.crtc_x, x); + atomic_add(&atom, plane->id, plane->props.crtc_y, y); + return atomic_end(drm->fd, &atom); +} + +const struct wlr_drm_interface atomic_iface = { + .conn_enable = atomic_conn_enable, + .crtc_pageflip = atomic_crtc_pageflip, + .crtc_set_cursor = atomic_crtc_set_cursor, + .crtc_move_cursor = atomic_crtc_move_cursor, +}; diff --git a/backend/drm/drm.c b/backend/drm/drm.c index ccdc92d9..1a5fea9f 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -32,13 +32,13 @@ bool wlr_drm_check_features(struct wlr_drm_backend *drm) { if (getenv("WLR_DRM_NO_ATOMIC")) { wlr_log(L_DEBUG, "WLR_DRM_NO_ATOMIC set, forcing legacy DRM interface"); - drm->iface = &iface_legacy; + drm->iface = &legacy_iface; } else if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_ATOMIC, 1)) { wlr_log(L_DEBUG, "Atomic modesetting unsupported, using legacy DRM interface"); - drm->iface = &iface_legacy; + drm->iface = &legacy_iface; } else { wlr_log(L_DEBUG, "Using atomic DRM interface"); - drm->iface = &iface_atomic; + drm->iface = &atomic_iface; } return true; diff --git a/backend/drm/iface_atomic.c b/backend/drm/iface_atomic.c deleted file mode 100644 index 1aef05d1..00000000 --- a/backend/drm/iface_atomic.c +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include -#include -#include "backend/drm/drm.h" -#include "backend/drm/iface.h" -#include "backend/drm/util.h" - -struct atomic { - drmModeAtomicReq *req; - int cursor; - bool failed; -}; - -static void atomic_begin(struct wlr_drm_crtc *crtc, struct atomic *atom) { - if (!crtc->atomic) { - crtc->atomic = drmModeAtomicAlloc(); - if (!crtc->atomic) { - wlr_log_errno(L_ERROR, "Allocation failed"); - atom->failed = true; - return; - } - } - - atom->req = crtc->atomic; - atom->cursor = drmModeAtomicGetCursor(atom->req); - atom->failed = false; -} - -static bool atomic_end(int drm_fd, struct atomic *atom) { - if (atom->failed) { - return false; - } - - uint32_t flags = DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK; - - if (drmModeAtomicCommit(drm_fd, atom->req, flags, NULL)) { - wlr_log_errno(L_ERROR, "Atomic test failed"); - drmModeAtomicSetCursor(atom->req, atom->cursor); - return false; - } - - return true; -} - -static bool atomic_commit(int drm_fd, struct atomic *atom, - struct wlr_drm_connector *conn, uint32_t flag, bool modeset) { - if (atom->failed) { - return false; - } - - uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | flag; - - int ret = drmModeAtomicCommit(drm_fd, atom->req, flags, conn); - if (ret) { - wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", - conn->output.name, modeset ? "modeset" : "pageflip"); - - // Try to commit without new changes - drmModeAtomicSetCursor(atom->req, atom->cursor); - if (drmModeAtomicCommit(drm_fd, atom->req, flags, conn)) { - wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", - conn->output.name, modeset ? "modeset" : "pageflip"); - } - } - - drmModeAtomicSetCursor(atom->req, 0); - - return !ret; -} - -static inline void atomic_add(struct atomic *atom, uint32_t id, uint32_t prop, uint64_t val) { - if (!atom->failed && drmModeAtomicAddProperty(atom->req, id, prop, val) < 0) { - wlr_log_errno(L_ERROR, "Failed to add atomic DRM property"); - atom->failed = true; - } -} - -static void set_plane_props(struct atomic *atom, struct wlr_drm_plane *plane, - uint32_t crtc_id, uint32_t fb_id, bool set_crtc_xy) { - uint32_t id = plane->id; - const union wlr_drm_plane_props *props = &plane->props; - - // The src_* properties are in 16.16 fixed point - atomic_add(atom, id, props->src_x, 0); - atomic_add(atom, id, props->src_y, 0); - atomic_add(atom, id, props->src_w, plane->surf.width << 16); - atomic_add(atom, id, props->src_h, plane->surf.height << 16); - atomic_add(atom, id, props->crtc_w, plane->surf.width); - atomic_add(atom, id, props->crtc_h, plane->surf.height); - atomic_add(atom, id, props->fb_id, fb_id); - atomic_add(atom, id, props->crtc_id, crtc_id); - if (set_crtc_xy) { - atomic_add(atom, id, props->crtc_x, 0); - atomic_add(atom, id, props->crtc_y, 0); - } -} - -static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, - struct wlr_drm_connector *conn, - struct wlr_drm_crtc *crtc, - uint32_t fb_id, drmModeModeInfo *mode) { - if (mode) { - if (crtc->mode_id) { - drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); - } - - if (drmModeCreatePropertyBlob(drm->fd, mode, sizeof(*mode), &crtc->mode_id)) { - wlr_log_errno(L_ERROR, "Unable to create property blob"); - return false; - } - } - - struct atomic atom; - - atomic_begin(crtc, &atom); - atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id); - atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id); - atomic_add(&atom, crtc->id, crtc->props.active, 1); - set_plane_props(&atom, crtc->primary, crtc->id, fb_id, true); - return atomic_commit(drm->fd, &atom, conn, - mode ? DRM_MODE_ATOMIC_ALLOW_MODESET : DRM_MODE_ATOMIC_NONBLOCK, - mode); -} - -static void atomic_conn_enable(struct wlr_drm_backend *drm, - struct wlr_drm_connector *conn, bool enable) { - struct wlr_drm_crtc *crtc = conn->crtc; - struct atomic atom; - - atomic_begin(crtc, &atom); - atomic_add(&atom, crtc->id, crtc->props.active, enable); - atomic_end(drm->fd, &atom); -} - -bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, - struct wlr_drm_crtc *crtc, struct gbm_bo *bo); - -static bool atomic_crtc_set_cursor(struct wlr_drm_backend *drm, - struct wlr_drm_crtc *crtc, struct gbm_bo *bo) { - if (!crtc || !crtc->cursor) { - return true; - } - - struct wlr_drm_plane *plane = crtc->cursor; - // We can't use atomic operations on fake planes - if (plane->id == 0) { - return legacy_crtc_set_cursor(drm, crtc, bo); - } - - struct atomic atom; - - atomic_begin(crtc, &atom); - - if (bo) { - set_plane_props(&atom, plane, crtc->id, get_fb_for_bo(bo), false); - } else { - atomic_add(&atom, plane->id, plane->props.fb_id, 0); - atomic_add(&atom, plane->id, plane->props.crtc_id, 0); - } - - return atomic_end(drm->fd, &atom); -} - -bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, - struct wlr_drm_crtc *crtc, int x, int y); - -static bool atomic_crtc_move_cursor(struct wlr_drm_backend *drm, - struct wlr_drm_crtc *crtc, int x, int y) { - struct wlr_drm_plane *plane = crtc->cursor; - // We can't use atomic operations on fake planes - if (plane->id == 0) { - return legacy_crtc_move_cursor(drm, crtc, x, y); - } - - struct atomic atom; - - atomic_begin(crtc, &atom); - atomic_add(&atom, plane->id, plane->props.crtc_x, x); - atomic_add(&atom, plane->id, plane->props.crtc_y, y); - return atomic_end(drm->fd, &atom); -} - -const struct wlr_drm_interface iface_atomic = { - .conn_enable = atomic_conn_enable, - .crtc_pageflip = atomic_crtc_pageflip, - .crtc_set_cursor = atomic_crtc_set_cursor, - .crtc_move_cursor = atomic_crtc_move_cursor, -}; diff --git a/backend/drm/iface_legacy.c b/backend/drm/iface_legacy.c deleted file mode 100644 index cf73bb87..00000000 --- a/backend/drm/iface_legacy.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include "backend/drm/drm.h" -#include "backend/drm/iface.h" -#include "backend/drm/util.h" - -static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm, - struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc, - uint32_t fb_id, drmModeModeInfo *mode) { - if (mode) { - if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0, - &conn->id, 1, mode)) { - wlr_log_errno(L_ERROR, "%s: Failed to set CRTC", conn->output.name); - return false; - } - } - - if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, conn)) { - wlr_log_errno(L_ERROR, "%s: Failed to page flip", conn->output.name); - return false; - } - - return true; -} - -static void legacy_conn_enable(struct wlr_drm_backend *drm, - struct wlr_drm_connector *conn, bool enable) { - drmModeConnectorSetProperty(drm->fd, conn->id, conn->props.dpms, - enable ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); -} - -bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, - struct wlr_drm_crtc *crtc, struct gbm_bo *bo) { - if (!crtc || !crtc->cursor) { - return true; - } - - if (!bo) { - drmModeSetCursor(drm->fd, crtc->id, 0, 0, 0); - return true; - } - - struct wlr_drm_plane *plane = crtc->cursor; - - if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(bo).u32, - plane->surf.width, plane->surf.height)) { - wlr_log_errno(L_ERROR, "Failed to set hardware cursor"); - return false; - } - - return true; -} - -bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, - struct wlr_drm_crtc *crtc, int x, int y) { - return !drmModeMoveCursor(drm->fd, crtc->id, x, y); -} - -const struct wlr_drm_interface iface_legacy = { - .conn_enable = legacy_conn_enable, - .crtc_pageflip = legacy_crtc_pageflip, - .crtc_set_cursor = legacy_crtc_set_cursor, - .crtc_move_cursor = legacy_crtc_move_cursor, -}; diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c new file mode 100644 index 00000000..d75eb2cb --- /dev/null +++ b/backend/drm/legacy.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include "backend/drm/drm.h" +#include "backend/drm/iface.h" +#include "backend/drm/util.h" + +static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm, + struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc, + uint32_t fb_id, drmModeModeInfo *mode) { + if (mode) { + if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0, + &conn->id, 1, mode)) { + wlr_log_errno(L_ERROR, "%s: Failed to set CRTC", conn->output.name); + return false; + } + } + + if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, conn)) { + wlr_log_errno(L_ERROR, "%s: Failed to page flip", conn->output.name); + return false; + } + + return true; +} + +static void legacy_conn_enable(struct wlr_drm_backend *drm, + struct wlr_drm_connector *conn, bool enable) { + drmModeConnectorSetProperty(drm->fd, conn->id, conn->props.dpms, + enable ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); +} + +bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, struct gbm_bo *bo) { + if (!crtc || !crtc->cursor) { + return true; + } + + if (!bo) { + drmModeSetCursor(drm->fd, crtc->id, 0, 0, 0); + return true; + } + + struct wlr_drm_plane *plane = crtc->cursor; + + if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(bo).u32, + plane->surf.width, plane->surf.height)) { + wlr_log_errno(L_ERROR, "Failed to set hardware cursor"); + return false; + } + + return true; +} + +bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, int x, int y) { + return !drmModeMoveCursor(drm->fd, crtc->id, x, y); +} + +const struct wlr_drm_interface legacy_iface = { + .conn_enable = legacy_conn_enable, + .crtc_pageflip = legacy_crtc_pageflip, + .crtc_set_cursor = legacy_crtc_set_cursor, + .crtc_move_cursor = legacy_crtc_move_cursor, +}; diff --git a/backend/meson.build b/backend/meson.build index caf2c8b0..c5c73288 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -3,10 +3,10 @@ backend_files = files( 'session/direct-ipc.c', 'session/direct.c', 'session/session.c', + 'drm/atomic.c', 'drm/backend.c', 'drm/drm.c', - 'drm/iface_atomic.c', - 'drm/iface_legacy.c', + 'drm/legacy.c', 'drm/properties.c', 'drm/renderer.c', 'drm/util.c', diff --git a/include/backend/drm/iface.h b/include/backend/drm/iface.h index db1d7ee1..bc61eb51 100644 --- a/include/backend/drm/iface.h +++ b/include/backend/drm/iface.h @@ -29,7 +29,7 @@ struct wlr_drm_interface { struct wlr_drm_crtc *crtc, int x, int y); }; -extern const struct wlr_drm_interface iface_atomic; -extern const struct wlr_drm_interface iface_legacy; +extern const struct wlr_drm_interface atomic_iface; +extern const struct wlr_drm_interface legacy_iface; #endif -- cgit v1.2.3