diff --git a/libweston/backend-drm/drm-gbm.c b/libweston/backend-drm/drm-gbm.c index 3ed96091..1799e8da 100644 --- a/libweston/backend-drm/drm-gbm.c +++ b/libweston/backend-drm/drm-gbm.c @@ -118,8 +118,9 @@ drm_backend_create_gl_renderer(struct drm_backend *b) int init_egl(struct drm_backend *b) { - b->gbm = create_gbm_device(b->drm.fd); + struct drm_device *device = b->drm; + b->gbm = create_gbm_device(device->drm.fd); if (!b->gbm) return -1; @@ -145,6 +146,7 @@ static void drm_output_fini_cursor_egl(struct drm_output *output) static int drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b) { + struct drm_device *device = b->drm; unsigned int i; /* No point creating cursors if we don't have a plane for them. */ @@ -154,7 +156,7 @@ drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b) for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) { struct gbm_bo *bo; - bo = gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height, + bo = gbm_bo_create(b->gbm, device->cursor_width, device->cursor_height, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); if (!bo) @@ -173,7 +175,7 @@ drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b) err: weston_log("cursor buffers unavailable, using gl cursors\n"); - b->cursors_are_broken = true; + device->cursors_are_broken = true; drm_output_fini_cursor_egl(output); return -1; } @@ -317,6 +319,7 @@ drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage) static void switch_to_gl_renderer(struct drm_backend *b) { + struct drm_device *device = b->drm; struct drm_output *output; bool dmabuf_support_inited; bool linux_explicit_sync_inited; @@ -330,7 +333,7 @@ switch_to_gl_renderer(struct drm_backend *b) weston_log("Switching to GL renderer\n"); - b->gbm = create_gbm_device(b->drm.fd); + b->gbm = create_gbm_device(device->drm.fd); if (!b->gbm) { weston_log("Failed to create gbm device. " "Aborting renderer switch\n"); diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index 14b5248a..062b8612 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -259,15 +259,8 @@ enum actions_needed_dmabuf_feedback { ACTION_NEEDED_REMOVE_SCANOUT_TRANCHE = (1 << 1), }; -struct drm_backend { - struct weston_backend base; - struct weston_compositor *compositor; - - struct udev *udev; - struct wl_event_source *drm_source; - - struct udev_monitor *udev_monitor; - struct wl_event_source *udev_drm_source; +struct drm_device { + struct drm_backend *backend; struct { int id; @@ -275,50 +268,63 @@ struct drm_backend { char *filename; dev_t devnum; } drm; - struct gbm_device *gbm; - struct wl_listener session_listener; - uint32_t gbm_format; - /* we need these parameters in order to not fail drmModeAddFB2() - * due to out of bounds dimensions, and then mistakenly set - * sprites_are_broken: - */ - int min_width, max_width; - int min_height, max_height; + /* drm_crtc::link */ + struct wl_list crtc_list; struct wl_list plane_list; - void *repaint_data; + /* drm_writeback::link */ + struct wl_list writeback_connector_list; bool state_invalid; - /* drm_crtc::link */ - struct wl_list crtc_list; + bool atomic_modeset; - /* drm_writeback::link */ - struct wl_list writeback_connector_list; + bool aspect_ratio_supported; + + int32_t cursor_width; + int32_t cursor_height; - bool sprites_are_broken; bool cursors_are_broken; + bool sprites_are_broken; - bool atomic_modeset; + void *repaint_data; + + bool fb_modifiers; + + /* we need these parameters in order to not fail drmModeAddFB2() + * due to out of bounds dimensions, and then mistakenly set + * sprites_are_broken: + */ + int min_width, max_width; + int min_height, max_height; +}; + +struct drm_backend { + struct weston_backend base; + struct weston_compositor *compositor; + + struct udev *udev; + struct wl_event_source *drm_source; + + struct udev_monitor *udev_monitor; + struct wl_event_source *udev_drm_source; + + struct drm_device *drm; + struct gbm_device *gbm; + struct wl_listener session_listener; + uint32_t gbm_format; bool use_pixman; bool use_pixman_shadow; struct udev_input input; - int32_t cursor_width; - int32_t cursor_height; - uint32_t pageflip_timeout; bool shutting_down; - bool aspect_ratio_supported; - - bool fb_modifiers; - struct weston_log_scope *debug; }; diff --git a/libweston/backend-drm/drm-virtual.c b/libweston/backend-drm/drm-virtual.c index d3e5b720..24004e14 100644 --- a/libweston/backend-drm/drm-virtual.c +++ b/libweston/backend-drm/drm-virtual.c @@ -92,6 +92,7 @@ drm_virtual_crtc_destroy(struct drm_crtc *crtc) static struct drm_plane * drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output) { + struct drm_device *device = b->drm; struct drm_plane *plane; struct weston_drm_format *fmt; uint64_t mod; @@ -115,7 +116,7 @@ drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output) /* If output supports linear modifier, we add it to the plane. * Otherwise we add DRM_FORMAT_MOD_INVALID, as explicit modifiers * are not supported. */ - if ((output->gbm_bo_flags & GBM_BO_USE_LINEAR) && b->fb_modifiers) + if ((output->gbm_bo_flags & GBM_BO_USE_LINEAR) && device->fb_modifiers) mod = DRM_FORMAT_MOD_LINEAR; else mod = DRM_FORMAT_MOD_INVALID; @@ -124,7 +125,7 @@ drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output) goto err; weston_plane_init(&plane->base, b->compositor, 0, 0); - wl_list_insert(&b->plane_list, &plane->link); + wl_list_insert(&device->plane_list, &plane->link); return plane; @@ -192,11 +193,13 @@ drm_virtual_output_repaint(struct weston_output *output_base, struct drm_plane_state *scanout_state; struct drm_pending_state *pending_state; struct drm_backend *backend; + struct drm_device *device; assert(output->virtual); backend = output->backend; - pending_state = backend->repaint_data; + device = backend->drm; + pending_state = device->repaint_data; if (output->disable_pending || output->destroy_pending) goto err; diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index 5625d7cf..89838afd 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -71,6 +71,7 @@ static const char default_seat[] = "seat0"; static void drm_backend_create_faked_zpos(struct drm_backend *b) { + struct drm_device *device = b->drm; struct drm_plane *plane; uint64_t zpos = 0ULL; uint64_t zpos_min_primary; @@ -78,7 +79,7 @@ drm_backend_create_faked_zpos(struct drm_backend *b) uint64_t zpos_min_cursor; zpos_min_primary = zpos; - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { /* if the property is there, bail out sooner */ if (plane->props[WDRM_PLANE_ZPOS].prop_id != 0) return; @@ -89,14 +90,14 @@ drm_backend_create_faked_zpos(struct drm_backend *b) } zpos_min_overlay = zpos; - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { if (plane->type != WDRM_PLANE_TYPE_OVERLAY) continue; zpos++; } zpos_min_cursor = zpos; - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { if (plane->type != WDRM_PLANE_TYPE_CURSOR) continue; zpos++; @@ -105,7 +106,7 @@ drm_backend_create_faked_zpos(struct drm_backend *b) drm_debug(b, "[drm-backend] zpos property not found. " "Using invented immutable zpos values:\n"); /* assume that invented zpos values are immutable */ - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { if (plane->type == WDRM_PLANE_TYPE_PRIMARY) { plane->zpos_min = zpos_min_primary; plane->zpos_max = zpos_min_primary; @@ -194,9 +195,10 @@ drm_plane_is_available(struct drm_plane *plane, struct drm_output *output) struct drm_crtc * drm_crtc_find(struct drm_backend *b, uint32_t crtc_id) { + struct drm_device *device = b->drm; struct drm_crtc *crtc; - wl_list_for_each(crtc, &b->crtc_list, link) { + wl_list_for_each(crtc, &device->crtc_list, link) { if (crtc->crtc_id == crtc_id) return crtc; } @@ -225,7 +227,7 @@ drm_writeback_find_by_connector(struct drm_backend *backend, uint32_t connector_ { struct drm_writeback *writeback; - wl_list_for_each(writeback, &backend->writeback_connector_list, link) { + wl_list_for_each(writeback, &backend->drm->writeback_connector_list, link) { if (writeback->connector.connector_id == connector_id) return writeback; } @@ -356,6 +358,7 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage) struct drm_property_info *damage_info = &scanout_plane->props[WDRM_PLANE_FB_DAMAGE_CLIPS]; struct drm_backend *b = to_drm_backend(c); + struct drm_device *device = b->drm; struct drm_fb *fb; pixman_region32_t scanout_damage; pixman_box32_t *rects; @@ -433,7 +436,7 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage) * that it will consider the whole plane damaged. While this may * affect efficiency, it should still produce correct results. */ - drmModeCreatePropertyBlob(b->drm.fd, rects, + drmModeCreatePropertyBlob(device->drm.fd, rects, sizeof(*rects) * n_rects, &scanout_state->damage_blob_id); @@ -448,11 +451,13 @@ drm_output_repaint(struct weston_output *output_base, pixman_region32_t *damage) struct drm_plane_state *scanout_state; struct drm_pending_state *pending_state; struct drm_backend *backend; + struct drm_device *device; assert(!output->virtual); backend = output->backend; - pending_state = backend->repaint_data; + device = backend->drm; + pending_state = device->repaint_data; if (output->disable_pending || output->destroy_pending) goto err; @@ -523,6 +528,7 @@ drm_output_start_repaint_loop(struct weston_output *output_base) struct drm_plane *scanout_plane = output->scanout_plane; struct drm_backend *backend = to_drm_backend(output_base->compositor); + struct drm_device *device = backend->drm; struct timespec ts, tnow; struct timespec vbl2now; int64_t refresh_nsec; @@ -544,14 +550,14 @@ drm_output_start_repaint_loop(struct weston_output *output_base) /* Need to smash all state in from scratch; current timings might not * be what we want, page flip might not work, etc. */ - if (backend->state_invalid) + if (device->state_invalid) goto finish_frame; assert(scanout_plane->state_cur->output == output); /* Try to get current msc and timestamp via instant query */ vbl.request.type |= drm_waitvblank_pipe(output->crtc); - ret = drmWaitVBlank(backend->drm.fd, &vbl); + ret = drmWaitVBlank(device->drm.fd, &vbl); /* Error ret or zero timestamp means failure to get valid timestamp */ if ((ret == 0) && (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0)) { @@ -615,15 +621,16 @@ static void drm_repaint_begin(struct weston_compositor *compositor) { struct drm_backend *b = to_drm_backend(compositor); + struct drm_device *device = b->drm; struct drm_pending_state *pending_state; pending_state = drm_pending_state_alloc(b); - b->repaint_data = pending_state; + device->repaint_data = pending_state; if (weston_log_scope_is_enabled(b->debug)) { char *dbg = weston_compositor_print_scene_graph(compositor); drm_debug(b, "[repaint] Beginning repaint; pending_state %p\n", - b->repaint_data); + device->repaint_data); drm_debug(b, "%s", dbg); free(dbg); } @@ -642,7 +649,8 @@ static int drm_repaint_flush(struct weston_compositor *compositor) { struct drm_backend *b = to_drm_backend(compositor); - struct drm_pending_state *pending_state = b->repaint_data; + struct drm_device *device = b->drm; + struct drm_pending_state *pending_state = device->repaint_data; int ret; ret = drm_pending_state_apply(pending_state); @@ -650,7 +658,7 @@ drm_repaint_flush(struct weston_compositor *compositor) weston_log("repaint-flush failed: %s\n", strerror(errno)); drm_debug(b, "[repaint] flushed pending_state %p\n", pending_state); - b->repaint_data = NULL; + device->repaint_data = NULL; return (ret == -EACCES) ? -1 : 0; } @@ -665,11 +673,12 @@ static void drm_repaint_cancel(struct weston_compositor *compositor) { struct drm_backend *b = to_drm_backend(compositor); - struct drm_pending_state *pending_state = b->repaint_data; + struct drm_device *device = b->drm; + struct drm_pending_state *pending_state = device->repaint_data; drm_pending_state_free(pending_state); drm_debug(b, "[repaint] cancel pending_state %p\n", pending_state); - b->repaint_data = NULL; + device->repaint_data = NULL; } static int @@ -682,6 +691,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo { struct drm_output *output = to_drm_output(output_base); struct drm_backend *b = to_drm_backend(output_base->compositor); + struct drm_device *device = b->drm; struct drm_mode *drm_mode = drm_output_choose_mode(output, mode); if (!drm_mode) { @@ -705,7 +715,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo * sledgehammer modeswitch first, and only later showing new * content. */ - b->state_invalid = true; + device->state_invalid = true; if (b->use_pixman) { drm_output_fini_pixman(output); @@ -750,6 +760,7 @@ init_pixman(struct drm_backend *b) static struct drm_plane * drm_plane_create(struct drm_backend *b, const drmModePlane *kplane) { + struct drm_device *device = b->drm; struct drm_plane *plane, *tmp; drmModeObjectProperties *props; uint64_t *zpos_range_values; @@ -768,7 +779,7 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane) weston_drm_format_array_init(&plane->formats); - props = drmModeObjectGetProperties(b->drm.fd, kplane->plane_id, + props = drmModeObjectGetProperties(device->drm.fd, kplane->plane_id, DRM_MODE_OBJECT_PLANE); if (!props) { weston_log("couldn't get plane properties\n"); @@ -795,7 +806,7 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane) } if (drm_plane_populate_formats(plane, kplane, props, - b->fb_modifiers) < 0) { + device->fb_modifiers) < 0) { drmModeFreeObjectProperties(props); goto err; } @@ -807,14 +818,14 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane) weston_plane_init(&plane->base, b->compositor, 0, 0); - wl_list_for_each(tmp, &b->plane_list, link) { + wl_list_for_each(tmp, &device->plane_list, link) { if (tmp->zpos_max > plane->zpos_max) { wl_list_insert(tmp->link.prev, &plane->link); break; } } if (plane->link.next == NULL) - wl_list_insert(b->plane_list.prev, &plane->link); + wl_list_insert(&device->plane_list, &plane->link); return plane; @@ -838,9 +849,10 @@ static struct drm_plane * drm_output_find_special_plane(struct drm_backend *b, struct drm_output *output, enum wdrm_plane_type type) { + struct drm_device *device = b->drm; struct drm_plane *plane; - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { struct drm_output *tmp; bool found_elsewhere = false; @@ -881,8 +893,11 @@ drm_output_find_special_plane(struct drm_backend *b, struct drm_output *output, static void drm_plane_destroy(struct drm_plane *plane) { + struct drm_backend *backend = plane->backend; + struct drm_device *device = backend->drm; + if (plane->type == WDRM_PLANE_TYPE_OVERLAY) - drmModeSetPlane(plane->backend->drm.fd, plane->plane_id, + drmModeSetPlane(device->drm.fd, plane->plane_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); drm_plane_state_free(plane->state_cur, true); drm_property_info_free(plane->props, WDRM_PLANE__COUNT); @@ -904,12 +919,14 @@ drm_plane_destroy(struct drm_plane *plane) static void create_sprites(struct drm_backend *b) { + struct drm_device *device = b->drm; drmModePlaneRes *kplane_res; drmModePlane *kplane; struct drm_plane *drm_plane; uint32_t i; uint32_t next_plane_idx = 0; - kplane_res = drmModeGetPlaneResources(b->drm.fd); + kplane_res = drmModeGetPlaneResources(device->drm.fd); + if (!kplane_res) { weston_log("failed to get plane resources: %s\n", strerror(errno)); @@ -917,7 +934,7 @@ create_sprites(struct drm_backend *b) } for (i = 0; i < kplane_res->count_planes; i++) { - kplane = drmModeGetPlane(b->drm.fd, kplane_res->planes[i]); + kplane = drmModeGetPlane(device->drm.fd, kplane_res->planes[i]); if (!kplane) continue; @@ -932,7 +949,7 @@ create_sprites(struct drm_backend *b) &b->compositor->primary_plane); } - wl_list_for_each (drm_plane, &b->plane_list, link) + wl_list_for_each (drm_plane, &device->plane_list, link) drm_plane->plane_idx = next_plane_idx++; drmModeFreePlaneResources(kplane_res); @@ -948,9 +965,10 @@ create_sprites(struct drm_backend *b) static void destroy_sprites(struct drm_backend *b) { + struct drm_device *device = b->drm; struct drm_plane *plane, *next; - wl_list_for_each_safe(plane, next, &b->plane_list, link) + wl_list_for_each_safe(plane, next, &device->plane_list, link) drm_plane_destroy(plane); } @@ -1034,7 +1052,8 @@ drm_set_dpms(struct weston_output *output_base, enum dpms_enum level) { struct drm_output *output = to_drm_output(output_base); struct drm_backend *b = to_drm_backend(output_base->compositor); - struct drm_pending_state *pending_state = b->repaint_data; + struct drm_device *device = b->drm; + struct drm_pending_state *pending_state = device->repaint_data; struct drm_output_state *state; int ret; @@ -1254,6 +1273,7 @@ drm_output_attach_head(struct weston_output *output_base, struct weston_head *head_base) { struct drm_backend *b = to_drm_backend(output_base->compositor); + struct drm_device *device = b->drm; if (wl_list_length(&output_base->head_list) >= MAX_CLONED_CONNECTORS) return -1; @@ -1270,7 +1290,7 @@ drm_output_attach_head(struct weston_output *output_base, /* XXX: Doing it globally, what guarantees another output's update * will not clear the flag before this output is updated? */ - b->state_invalid = true; + device->state_invalid = true; weston_output_schedule_repaint(output_base); @@ -1282,6 +1302,7 @@ drm_output_detach_head(struct weston_output *output_base, struct weston_head *head_base) { struct drm_backend *b = to_drm_backend(output_base->compositor); + struct drm_device *device = b->drm; if (!output_base->enabled) return; @@ -1289,7 +1310,7 @@ drm_output_detach_head(struct weston_output *output_base, /* Need to go through modeset to drop connectors that should no longer * be driven. */ /* XXX: Ideally we'd do this per-output, not globally. */ - b->state_invalid = true; + device->state_invalid = true; weston_output_schedule_repaint(output_base); } @@ -1321,7 +1342,8 @@ parse_gbm_format(const char *s, uint32_t default_value, uint32_t *gbm_format) static int drm_head_read_current_setup(struct drm_head *head, struct drm_backend *backend) { - int drm_fd = backend->drm.fd; + struct drm_device *device = backend->drm; + int drm_fd = device->drm.fd; drmModeConnector *conn = head->connector.conn; drmModeEncoder *encoder; drmModeCrtc *crtc; @@ -1371,11 +1393,12 @@ static int drm_output_init_gamma_size(struct drm_output *output) { struct drm_backend *backend = to_drm_backend(output->base.compositor); + struct drm_device *device = backend->drm; drmModeCrtc *crtc; assert(output->base.compositor); assert(output->crtc); - crtc = drmModeGetCrtc(backend->drm.fd, output->crtc->crtc_id); + crtc = drmModeGetCrtc(device->drm.fd, output->crtc->crtc_id); if (!crtc) return -1; @@ -1389,13 +1412,15 @@ drm_output_init_gamma_size(struct drm_output *output) static uint32_t drm_connector_get_possible_crtcs_mask(struct drm_connector *connector) { + struct drm_backend *backend = connector->backend; + struct drm_device *device = backend->drm; uint32_t possible_crtcs = 0; drmModeConnector *conn = connector->conn; drmModeEncoder *encoder; int i; for (i = 0; i < conn->count_encoders; i++) { - encoder = drmModeGetEncoder(connector->backend->drm.fd, + encoder = drmModeGetEncoder(device->drm.fd, conn->encoders[i]); if (!encoder) continue; @@ -1416,6 +1441,7 @@ static struct drm_crtc * drm_output_pick_crtc(struct drm_output *output) { struct drm_backend *backend; + struct drm_device *device; struct weston_head *base; struct drm_head *head; struct drm_crtc *crtc; @@ -1429,6 +1455,7 @@ drm_output_pick_crtc(struct drm_output *output) bool match; backend = to_drm_backend(output->base.compositor); + device = backend->drm; /* This algorithm ignores drmModeEncoder::possible_clones restriction, * because it is more often set wrong than not in the kernel. */ @@ -1447,7 +1474,7 @@ drm_output_pick_crtc(struct drm_output *output) /* Find a crtc that could drive each connector individually at least, * and prefer existing routings. */ - wl_list_for_each(crtc, &backend->crtc_list, link) { + wl_list_for_each(crtc, &device->crtc_list, link) { /* Could the crtc not drive each connector? */ if (!(possible_crtcs & (1 << crtc->pipe))) @@ -1510,7 +1537,7 @@ drm_output_pick_crtc(struct drm_output *output) } /* Otherwise pick any available crtc. */ - wl_list_for_each(crtc, &backend->crtc_list, link) { + wl_list_for_each(crtc, &device->crtc_list, link) { if (!crtc->output) return crtc; } @@ -1524,10 +1551,11 @@ drm_output_pick_crtc(struct drm_output *output) static struct drm_crtc * drm_crtc_create(struct drm_backend *b, uint32_t crtc_id, uint32_t pipe) { + struct drm_device *device = b->drm; struct drm_crtc *crtc; drmModeObjectPropertiesPtr props; - props = drmModeObjectGetProperties(b->drm.fd, crtc_id, + props = drmModeObjectGetProperties(device->drm.fd, crtc_id, DRM_MODE_OBJECT_CRTC); if (!props) { weston_log("failed to get CRTC properties\n"); @@ -1546,7 +1574,7 @@ drm_crtc_create(struct drm_backend *b, uint32_t crtc_id, uint32_t pipe) crtc->output = NULL; /* Add it to the last position of the DRM-backend CRTC list */ - wl_list_insert(b->crtc_list.prev, &crtc->link); + wl_list_insert(device->crtc_list.prev, &crtc->link); ret: drmModeFreeObjectProperties(props); @@ -1584,6 +1612,7 @@ drm_crtc_destroy(struct drm_crtc *crtc) static int drm_backend_create_crtc_list(struct drm_backend *b, drmModeRes *resources) { + struct drm_device *device = b->drm; struct drm_crtc *crtc, *crtc_tmp; int i; @@ -1599,7 +1628,7 @@ drm_backend_create_crtc_list(struct drm_backend *b, drmModeRes *resources) return 0; err: - wl_list_for_each_safe(crtc, crtc_tmp, &b->crtc_list, link) + wl_list_for_each_safe(crtc, crtc_tmp, &device->crtc_list, link) drm_crtc_destroy(crtc); return -1; } @@ -1612,6 +1641,7 @@ static int drm_output_init_planes(struct drm_output *output) { struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; output->scanout_plane = drm_output_find_special_plane(b, output, @@ -1637,7 +1667,7 @@ drm_output_init_planes(struct drm_output *output) &output->cursor_plane->base, NULL); else - b->cursors_are_broken = true; + device->cursors_are_broken = true; return 0; } @@ -1649,6 +1679,7 @@ static void drm_output_deinit_planes(struct drm_output *output) { struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; /* If the compositor is already shutting down, the planes have already * been destroyed. */ @@ -1660,7 +1691,7 @@ drm_output_deinit_planes(struct drm_output *output) wl_list_remove(&output->cursor_plane->base.link); wl_list_init(&output->cursor_plane->base.link); /* Turn off hardware cursor */ - drmModeSetCursor(b->drm.fd, output->crtc->crtc_id, 0, 0, 0); + drmModeSetCursor(device->drm.fd, output->crtc->crtc_id, 0, 0, 0); } /* With universal planes, the planes are allocated at startup, @@ -1682,6 +1713,7 @@ static struct weston_drm_format_array * get_scanout_formats(struct drm_backend *b) { struct weston_compositor *ec = b->compositor; + struct drm_device *device = b->drm; const struct weston_drm_format_array *renderer_formats; struct weston_drm_format_array *scanout_formats, union_planes_formats; struct drm_plane *plane; @@ -1702,7 +1734,7 @@ get_scanout_formats(struct drm_backend *b) weston_drm_format_array_init(scanout_formats); /* Compute the union of the format/modifiers of the KMS planes */ - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { /* The scanout formats are used by the dma-buf feedback. But for * now cursor planes do not support dma-buf buffers, only wl_shm * buffers. So we skip cursor planes here. */ @@ -1771,13 +1803,14 @@ static void drm_output_detach_crtc(struct drm_output *output) { struct drm_backend *b = output->backend; + struct drm_device *device = b->drm; struct drm_crtc *crtc = output->crtc; crtc->output = NULL; output->crtc = NULL; /* Force resetting unused CRTCs */ - b->state_invalid = true; + device->state_invalid = true; } static int @@ -1847,6 +1880,7 @@ drm_output_deinit(struct weston_output *base) { struct drm_output *output = to_drm_output(base); struct drm_backend *b = to_drm_backend(base->compositor); + struct drm_device *device = b->drm; if (b->use_pixman) drm_output_fini_pixman(output); @@ -1857,7 +1891,7 @@ drm_output_deinit(struct weston_output *base) drm_output_detach_crtc(output); if (output->hdr_output_metadata_blob_id) { - drmModeDestroyPropertyBlob(b->drm.fd, + drmModeDestroyPropertyBlob(device->drm.fd, output->hdr_output_metadata_blob_id); output->hdr_output_metadata_blob_id = 0; } @@ -2003,9 +2037,11 @@ drm_head_get_current_protection(struct drm_head *head) static int drm_connector_update_properties(struct drm_connector *connector) { + struct drm_backend *backend = connector->backend; + struct drm_device *device = backend->drm; drmModeObjectProperties *props; - props = drmModeObjectGetProperties(connector->backend->drm.fd, + props = drmModeObjectGetProperties(device->drm.fd, connector->connector_id, DRM_MODE_OBJECT_CONNECTOR); if (!props) { @@ -2280,6 +2316,7 @@ drm_output_create(struct weston_compositor *compositor, const char *name) static int drm_writeback_create(struct drm_backend *b, drmModeConnector *conn) { + struct drm_device *device = b->drm; struct drm_writeback *writeback; int ret; @@ -2294,7 +2331,7 @@ drm_writeback_create(struct drm_backend *b, drmModeConnector *conn) if (ret < 0) goto err; - wl_list_insert(&b->writeback_connector_list, &writeback->link); + wl_list_insert(&device->writeback_connector_list, &writeback->link); return 0; err: @@ -2357,18 +2394,19 @@ static int drm_backend_discover_connectors(struct drm_backend *b, struct udev_device *drm_device, drmModeRes *resources) { + struct drm_device *device = b->drm; drmModeConnector *conn; int i, ret; - b->min_width = resources->min_width; - b->max_width = resources->max_width; - b->min_height = resources->min_height; - b->max_height = resources->max_height; + device->min_width = resources->min_width; + device->max_width = resources->max_width; + device->min_height = resources->min_height; + device->max_height = resources->max_height; for (i = 0; i < resources->count_connectors; i++) { uint32_t connector_id = resources->connectors[i]; - conn = drmModeGetConnector(b->drm.fd, connector_id); + conn = drmModeGetConnector(device->drm.fd, connector_id); if (!conn) continue; @@ -2394,6 +2432,7 @@ resources_has_connector(drmModeRes *resources, uint32_t connector_id) static void drm_backend_update_connectors(struct drm_backend *b, struct udev_device *drm_device) { + struct drm_device *device = b->drm; drmModeRes *resources; drmModeConnector *conn; struct weston_head *base, *base_next; @@ -2402,7 +2441,7 @@ drm_backend_update_connectors(struct drm_backend *b, struct udev_device *drm_dev uint32_t connector_id; int i, ret; - resources = drmModeGetResources(b->drm.fd); + resources = drmModeGetResources(device->drm.fd); if (!resources) { weston_log("drmModeGetResources failed\n"); return; @@ -2412,7 +2451,7 @@ drm_backend_update_connectors(struct drm_backend *b, struct udev_device *drm_dev for (i = 0; i < resources->count_connectors; i++) { connector_id = resources->connectors[i]; - conn = drmModeGetConnector(b->drm.fd, connector_id); + conn = drmModeGetConnector(device->drm.fd, connector_id); if (!conn) continue; @@ -2452,7 +2491,7 @@ drm_backend_update_connectors(struct drm_backend *b, struct udev_device *drm_dev /* Destroy writeback objects of writeback connectors that have * disappeared. */ wl_list_for_each_safe(writeback, writeback_next, - &b->writeback_connector_list, link) { + &b->drm->writeback_connector_list, link) { connector_id = writeback->connector.connector_id; if (resources_has_connector(resources, connector_id)) @@ -2513,16 +2552,17 @@ drm_backend_update_conn_props(struct drm_backend *b, } static int -udev_event_is_hotplug(struct drm_backend *b, struct udev_device *device) +udev_event_is_hotplug(struct drm_backend *b, struct udev_device *udev_device) { + struct drm_device *device = b->drm; const char *sysnum; const char *val; - sysnum = udev_device_get_sysnum(device); - if (!sysnum || atoi(sysnum) != b->drm.id) + sysnum = udev_device_get_sysnum(udev_device); + if (!sysnum || atoi(sysnum) != device->drm.id) return 0; - val = udev_device_get_property_value(device, "HOTPLUG"); + val = udev_device_get_property_value(udev_device, "HOTPLUG"); if (!val) return 0; @@ -2531,7 +2571,7 @@ udev_event_is_hotplug(struct drm_backend *b, struct udev_device *device) static int udev_event_is_conn_prop_change(struct drm_backend *b, - struct udev_device *device, + struct udev_device *udev_device, uint32_t *connector_id, uint32_t *property_id) @@ -2539,13 +2579,13 @@ udev_event_is_conn_prop_change(struct drm_backend *b, const char *val; int id; - val = udev_device_get_property_value(device, "CONNECTOR"); + val = udev_device_get_property_value(udev_device, "CONNECTOR"); if (!val || !safe_strtoint(val, &id)) return 0; else *connector_id = id; - val = udev_device_get_property_value(device, "PROPERTY"); + val = udev_device_get_property_value(udev_device, "PROPERTY"); if (!val || !safe_strtoint(val, &id)) return 0; else @@ -2579,6 +2619,7 @@ static void drm_destroy(struct weston_compositor *ec) { struct drm_backend *b = to_drm_backend(ec); + struct drm_device *device = b->drm; struct weston_head *base, *next; struct drm_crtc *crtc, *crtc_tmp; struct drm_writeback *writeback, *writeback_tmp; @@ -2596,14 +2637,14 @@ drm_destroy(struct weston_compositor *ec) b->debug = NULL; weston_compositor_shutdown(ec); - wl_list_for_each_safe(crtc, crtc_tmp, &b->crtc_list, link) + wl_list_for_each_safe(crtc, crtc_tmp, &b->drm->crtc_list, link) drm_crtc_destroy(crtc); wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) drm_head_destroy(to_drm_head(base)); wl_list_for_each_safe(writeback, writeback_tmp, - &b->writeback_connector_list, link) + &b->drm->writeback_connector_list, link) drm_writeback_destroy(writeback); #ifdef BUILD_DRM_GBM @@ -2614,10 +2655,10 @@ drm_destroy(struct weston_compositor *ec) udev_monitor_unref(b->udev_monitor); udev_unref(b->udev); - weston_launcher_close(ec->launcher, b->drm.fd); + weston_launcher_close(ec->launcher, device->drm.fd); weston_launcher_destroy(ec->launcher); - free(b->drm.filename); + free(device->drm.filename); free(b); } @@ -2626,6 +2667,7 @@ session_notify(struct wl_listener *listener, void *data) { struct weston_compositor *compositor = data; struct drm_backend *b = to_drm_backend(compositor); + struct drm_device *device = b->drm; struct drm_plane *plane; struct drm_output *output; struct drm_crtc *crtc; @@ -2634,7 +2676,7 @@ session_notify(struct wl_listener *listener, void *data) weston_log("activating session\n"); weston_compositor_wake(compositor); weston_compositor_damage_all(compositor); - b->state_invalid = true; + device->state_invalid = true; udev_input_enable(&b->input); } else { weston_log("deactivating session\n"); @@ -2654,7 +2696,7 @@ session_notify(struct wl_listener *listener, void *data) crtc = output->crtc; output->base.repaint_needed = false; if (output->cursor_plane) - drmModeSetCursor(b->drm.fd, crtc->crtc_id, + drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0); } @@ -2662,10 +2704,10 @@ session_notify(struct wl_listener *listener, void *data) struct drm_output, base.link); crtc = output->crtc; - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { if (plane->type != WDRM_PLANE_TYPE_OVERLAY) continue; - drmModeSetPlane(b->drm.fd, plane->plane_id, crtc->crtc_id, + drmModeSetPlane(device->drm.fd, plane->plane_id, crtc->crtc_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } } @@ -2679,16 +2721,17 @@ session_notify(struct wl_listener *listener, void *data) * the compositor session. * * @param compositor The compositor instance. - * @param device The device being added/removed. + * @param devnum The device being added/removed. * @param added Whether the device is being added (or removed) */ static void drm_device_changed(struct weston_compositor *compositor, - dev_t device, bool added) + dev_t devnum, bool added) { struct drm_backend *b = to_drm_backend(compositor); + struct drm_device *device = b->drm; - if (b->drm.fd < 0 || b->drm.devnum != device || + if (device->drm.fd < 0 || device->drm.devnum != devnum || compositor->session_active == added) return; @@ -2701,18 +2744,20 @@ drm_device_changed(struct weston_compositor *compositor, * sets b->drm.fd and b->drm.filename to the opened device. */ static bool -drm_device_is_kms(struct drm_backend *b, struct udev_device *device) +drm_device_is_kms(struct drm_backend *b, struct udev_device *udev_device) { - const char *filename = udev_device_get_devnode(device); - const char *sysnum = udev_device_get_sysnum(device); - dev_t devnum = udev_device_get_devnum(device); + struct drm_device *device = b->drm; + struct weston_compositor *compositor = b->compositor; + const char *filename = udev_device_get_devnode(udev_device); + const char *sysnum = udev_device_get_sysnum(udev_device); + dev_t devnum = udev_device_get_devnum(udev_device); drmModeRes *res; int id = -1, fd; if (!filename) return false; - fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR); + fd = weston_launcher_open(compositor->launcher, filename, O_RDWR); if (fd < 0) return false; @@ -2733,14 +2778,14 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device) /* We can be called successfully on multiple devices; if we have, * clean up old entries. */ - if (b->drm.fd >= 0) - weston_launcher_close(b->compositor->launcher, b->drm.fd); - free(b->drm.filename); + if (device->drm.fd >= 0) + weston_launcher_close(compositor->launcher, device->drm.fd); + free(device->drm.filename); - b->drm.fd = fd; - b->drm.id = id; - b->drm.filename = strdup(filename); - b->drm.devnum = devnum; + device->drm.fd = fd; + device->drm.id = id; + device->drm.filename = strdup(filename); + device->drm.devnum = devnum; drmModeFreeResources(res); @@ -2766,10 +2811,11 @@ out_fd: static struct udev_device* find_primary_gpu(struct drm_backend *b, const char *seat) { + struct drm_device *device = b->drm; struct udev_enumerate *e; struct udev_list_entry *entry; const char *path, *device_seat, *id; - struct udev_device *device, *drm_device, *pci; + struct udev_device *dev, *drm_device, *pci; e = udev_enumerate_new(b->udev); udev_enumerate_add_match_subsystem(e, "drm"); @@ -2781,18 +2827,18 @@ find_primary_gpu(struct drm_backend *b, const char *seat) bool is_boot_vga = false; path = udev_list_entry_get_name(entry); - device = udev_device_new_from_syspath(b->udev, path); - if (!device) + dev = udev_device_new_from_syspath(b->udev, path); + if (!dev) continue; - device_seat = udev_device_get_property_value(device, "ID_SEAT"); + device_seat = udev_device_get_property_value(dev, "ID_SEAT"); if (!device_seat) device_seat = default_seat; if (strcmp(device_seat, seat)) { - udev_device_unref(device); + udev_device_unref(dev); continue; } - pci = udev_device_get_parent_with_subsystem_devtype(device, + pci = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL); if (pci) { id = udev_device_get_sysattr_value(pci, "boot_vga"); @@ -2804,15 +2850,15 @@ find_primary_gpu(struct drm_backend *b, const char *seat) * device isn't our boot-VGA device, we aren't going to use * it. */ if (!is_boot_vga && drm_device) { - udev_device_unref(device); + udev_device_unref(dev); continue; } /* Make sure this device is actually capable of modesetting; - * if this call succeeds, b->drm.{fd,filename} will be set, + * if this call succeeds, device->drm.{fd,filename} will be set, * and any old values freed. */ - if (!drm_device_is_kms(b, device)) { - udev_device_unref(device); + if (!drm_device_is_kms(b, dev)) { + udev_device_unref(dev); continue; } @@ -2821,7 +2867,7 @@ find_primary_gpu(struct drm_backend *b, const char *seat) if (is_boot_vga) { if (drm_device) udev_device_unref(drm_device); - drm_device = device; + drm_device = dev; break; } @@ -2829,12 +2875,12 @@ find_primary_gpu(struct drm_backend *b, const char *seat) * trump existing saved devices with boot-VGA devices, so if * we end up here, this must be the first device we've seen. */ assert(!drm_device); - drm_device = device; + drm_device = dev; } /* If we're returning a device to use, we must have an open FD for * it. */ - assert(!!drm_device == (b->drm.fd >= 0)); + assert(!!drm_device == (device->drm.fd >= 0)); udev_enumerate_unref(e); return drm_device; @@ -2843,25 +2889,26 @@ find_primary_gpu(struct drm_backend *b, const char *seat) static struct udev_device * open_specific_drm_device(struct drm_backend *b, const char *name) { - struct udev_device *device; + struct drm_device *device = b->drm; + struct udev_device *udev_device; - device = udev_device_new_from_subsystem_sysname(b->udev, "drm", name); - if (!device) { + udev_device = udev_device_new_from_subsystem_sysname(b->udev, "drm", name); + if (!udev_device) { weston_log("ERROR: could not open DRM device '%s'\n", name); return NULL; } - if (!drm_device_is_kms(b, device)) { - udev_device_unref(device); + if (!drm_device_is_kms(b, udev_device)) { + udev_device_unref(udev_device); weston_log("ERROR: DRM device '%s' is not a KMS device.\n", name); return NULL; } /* If we're returning a device to use, we must have an open FD for * it. */ - assert(b->drm.fd >= 0); + assert(device->drm.fd >= 0); - return device; + return udev_device; } static void @@ -2869,15 +2916,16 @@ planes_binding(struct weston_keyboard *keyboard, const struct timespec *time, uint32_t key, void *data) { struct drm_backend *b = data; + struct drm_device *device = b->drm; switch (key) { case KEY_C: - b->cursors_are_broken ^= true; + device->cursors_are_broken ^= true; break; case KEY_V: /* We don't support overlay-plane usage with legacy KMS. */ - if (b->atomic_modeset) - b->sprites_are_broken ^= true; + if (device->atomic_modeset) + device->sprites_are_broken ^= true; break; default: break; @@ -2901,17 +2949,19 @@ static void recorder_frame_notify(struct wl_listener *listener, void *data) { struct drm_output *output; + struct drm_device *device; struct drm_backend *b; int fd, ret; output = container_of(listener, struct drm_output, recorder_frame_listener); b = to_drm_backend(output->base.compositor); + device = b->drm; if (!output->recorder) return; - ret = drmPrimeHandleToFD(b->drm.fd, + ret = drmPrimeHandleToFD(device->drm.fd, output->scanout_plane->state_cur->fb->handles[0], DRM_CLOEXEC, &fd); if (ret) { @@ -2932,15 +2982,16 @@ static void * create_recorder(struct drm_backend *b, int width, int height, const char *filename) { + struct drm_device *device = b->drm; int fd; drm_magic_t magic; - fd = open(b->drm.filename, O_RDWR | O_CLOEXEC); + fd = open(device->drm.filename, O_RDWR | O_CLOEXEC); if (fd < 0) return NULL; drmGetMagic(fd, &magic); - drmAuthMagic(b->drm.fd, magic); + drmAuthMagic(device->drm.fd, magic); return vaapi_recorder_create(fd, width, height, filename); } @@ -3007,6 +3058,7 @@ drm_backend_create(struct weston_compositor *compositor, struct weston_drm_backend_config *config) { struct drm_backend *b; + struct drm_device *device; struct udev_device *drm_device; struct wl_event_loop *loop; const char *seat_id = default_seat; @@ -3028,8 +3080,14 @@ drm_backend_create(struct weston_compositor *compositor, if (b == NULL) return NULL; - b->state_invalid = true; - b->drm.fd = -1; + device = zalloc(sizeof *device); + if (device == NULL) + return NULL; + device->state_invalid = true; + device->drm.fd = -1; + device->backend = b; + + b->drm = device; b->compositor = compositor; b->use_pixman = config->use_pixman; @@ -3098,19 +3156,19 @@ drm_backend_create(struct weston_compositor *compositor, weston_setup_vt_switch_bindings(compositor); - res = drmModeGetResources(b->drm.fd); + res = drmModeGetResources(b->drm->drm.fd); if (!res) { weston_log("Failed to get drmModeRes\n"); goto err_udev_dev; } - wl_list_init(&b->crtc_list); + wl_list_init(&b->drm->crtc_list); if (drm_backend_create_crtc_list(b, res) == -1) { weston_log("Failed to create CRTC list for DRM-backend\n"); goto err_create_crtc_list; } - wl_list_init(&b->plane_list); + wl_list_init(&device->plane_list); create_sprites(b); if (udev_input_init(&b->input, @@ -3120,9 +3178,9 @@ drm_backend_create(struct weston_compositor *compositor, goto err_sprite; } - wl_list_init(&b->writeback_connector_list); + wl_list_init(&b->drm->writeback_connector_list); if (drm_backend_discover_connectors(b, drm_device, res) < 0) { - weston_log("Failed to create heads for %s\n", b->drm.filename); + weston_log("Failed to create heads for %s\n", b->drm->drm.filename); goto err_udev_input; } @@ -3133,13 +3191,13 @@ drm_backend_create(struct weston_compositor *compositor, /* A this point we have some idea of whether or not we have a working * cursor plane. */ - if (!b->cursors_are_broken) + if (!device->cursors_are_broken) compositor->capabilities |= WESTON_CAP_CURSOR_PLANE; loop = wl_display_get_event_loop(compositor->wl_display); b->drm_source = - wl_event_loop_add_fd(loop, b->drm.fd, - WL_EVENT_READABLE, on_drm_input, b); + wl_event_loop_add_fd(loop, b->drm->drm.fd, + WL_EVENT_READABLE, on_drm_input, b->drm); b->udev_monitor = udev_monitor_new_from_netlink(b->udev, "udev"); if (b->udev_monitor == NULL) { @@ -3202,7 +3260,7 @@ drm_backend_create(struct weston_compositor *compositor, " synchronization support failed.\n"); } - if (b->atomic_modeset) + if (device->atomic_modeset) if (weston_compositor_enable_content_protection(compositor) < 0) weston_log("Error: initializing content-protection " "support failed.\n"); diff --git a/libweston/backend-drm/fb.c b/libweston/backend-drm/fb.c index 1d518df3..4fa06ce8 100644 --- a/libweston/backend-drm/fb.c +++ b/libweston/backend-drm/fb.c @@ -71,13 +71,14 @@ drm_fb_destroy_dumb(struct drm_fb *fb) static int drm_fb_addfb(struct drm_backend *b, struct drm_fb *fb) { + struct drm_device *device = b->drm; int ret = -EINVAL; uint64_t mods[4] = { }; size_t i; /* If we have a modifier set, we must only use the WithModifiers * entrypoint; we cannot import it through legacy ioctls. */ - if (b->fb_modifiers && fb->modifier != DRM_FORMAT_MOD_INVALID) { + if (device->fb_modifiers && fb->modifier != DRM_FORMAT_MOD_INVALID) { /* KMS demands that if a modifier is set, it must be the same * for all planes. */ for (i = 0; i < ARRAY_LENGTH(mods) && fb->handles[i]; i++) @@ -115,6 +116,7 @@ struct drm_fb * drm_fb_create_dumb(struct drm_backend *b, int width, int height, uint32_t format) { + struct drm_device *device = b->drm; struct drm_fb *fb; int ret; @@ -145,7 +147,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int height, create_arg.width = width; create_arg.height = height; - ret = drmIoctl(b->drm.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg); + ret = drmIoctl(device->drm.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg); if (ret) goto err_fb; @@ -157,7 +159,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int height, fb->size = create_arg.size; fb->width = width; fb->height = height; - fb->fd = b->drm.fd; + fb->fd = device->drm.fd; if (drm_fb_addfb(b, fb) != 0) { weston_log("failed to create kms fb: %s\n", strerror(errno)); @@ -171,18 +173,18 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int height, goto err_add_fb; fb->map = mmap(NULL, fb->size, PROT_WRITE, - MAP_SHARED, b->drm.fd, map_arg.offset); + MAP_SHARED, device->drm.fd, map_arg.offset); if (fb->map == MAP_FAILED) goto err_add_fb; return fb; err_add_fb: - drmModeRmFB(b->drm.fd, fb->fb_id); + drmModeRmFB(device->drm.fd, fb->fb_id); err_bo: memset(&destroy_arg, 0, sizeof(destroy_arg)); destroy_arg.handle = create_arg.handle; - drmIoctl(b->drm.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); + drmIoctl(device->drm.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); err_fb: free(fb); return NULL; @@ -227,6 +229,7 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf, * of GBM_BO_IMPORT_FD_MODIFIER. */ return NULL; #else + struct drm_device *device = backend->drm; struct drm_fb *fb; int i; struct gbm_import_fd_modifier_data import_mod = { @@ -287,7 +290,7 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf, fb->height = dmabuf->attributes.height; fb->modifier = dmabuf->attributes.modifier[0]; fb->size = 0; - fb->fd = backend->drm.fd; + fb->fd = device->drm.fd; ARRAY_COPY(fb->strides, dmabuf->attributes.stride); ARRAY_COPY(fb->offsets, dmabuf->attributes.offset); @@ -302,10 +305,10 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf, if (is_opaque) fb->format = pixel_format_get_opaque_substitute(fb->format); - if (backend->min_width > fb->width || - fb->width > backend->max_width || - backend->min_height > fb->height || - fb->height > backend->max_height) { + if (device->min_width > fb->width || + fb->width > device->max_width || + device->min_height > fb->height || + fb->height > device->max_height) { weston_log("bo geometry out of bounds\n"); goto err_free; } @@ -342,6 +345,7 @@ struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend, bool is_opaque, enum drm_fb_type type) { + struct drm_device *device = backend->drm; struct drm_fb *fb = gbm_bo_get_user_data(bo); #ifdef HAVE_GBM_MODIFIERS int i; @@ -359,7 +363,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend, fb->type = type; fb->refcnt = 1; fb->bo = bo; - fb->fd = backend->drm.fd; + fb->fd = device->drm.fd; fb->width = gbm_bo_get_width(bo); fb->height = gbm_bo_get_height(bo); @@ -392,10 +396,10 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend, if (is_opaque) fb->format = pixel_format_get_opaque_substitute(fb->format); - if (backend->min_width > fb->width || - fb->width > backend->max_width || - backend->min_height > fb->height || - fb->height > backend->max_height) { + if (device->min_width > fb->width || + fb->width > device->max_width || + device->min_height > fb->height || + fb->height > device->max_height) { weston_log("bo geometry out of bounds\n"); goto err_free; } @@ -529,6 +533,7 @@ drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev, { struct drm_output *output = state->output; struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; struct weston_buffer *buffer = ev->surface->buffer_ref.buffer; struct drm_buffer_fb *buf_fb; bool is_opaque = weston_view_is_opaque(ev, &ev->transform.boundingbox); @@ -603,7 +608,7 @@ drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev, /* Check if this buffer can ever go on any planes. If it can't, we have * no reason to ever have a drm_fb, so we fail it here. */ - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { /* only SHM buffers can go into cursor planes */ if (plane->type == WDRM_PLANE_TYPE_CURSOR) continue; diff --git a/libweston/backend-drm/kms-color.c b/libweston/backend-drm/kms-color.c index 476480d5..55925665 100644 --- a/libweston/backend-drm/kms-color.c +++ b/libweston/backend-drm/kms-color.c @@ -108,6 +108,7 @@ weston_hdr_metadata_type1_to_kms(struct hdr_metadata_infoframe *dst, int drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output) { + struct drm_device *device = output->backend->drm; const struct weston_hdr_metadata_type1 *src; struct hdr_output_metadata meta; uint32_t blob_id = 0; @@ -160,7 +161,7 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output) return -1; } - ret = drmModeCreatePropertyBlob(output->backend->drm.fd, + ret = drmModeCreatePropertyBlob(device->drm.fd, &meta, sizeof meta, &blob_id); if (ret != 0) { weston_log("Error: failed to create KMS blob for HDR metadata on output '%s': %s\n", @@ -168,7 +169,7 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output) return -1; } - drmModeDestroyPropertyBlob(output->backend->drm.fd, + drmModeDestroyPropertyBlob(device->drm.fd, output->hdr_output_metadata_blob_id); output->hdr_output_metadata_blob_id = blob_id; diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c index b84eb881..2b159586 100644 --- a/libweston/backend-drm/kms.c +++ b/libweston/backend-drm/kms.c @@ -288,6 +288,7 @@ drm_property_info_populate(struct drm_backend *b, unsigned int num_infos, drmModeObjectProperties *props) { + struct drm_device *device = b->drm; drmModePropertyRes *prop; unsigned i, j; @@ -314,7 +315,7 @@ drm_property_info_populate(struct drm_backend *b, for (i = 0; i < props->count_props; i++) { unsigned int k; - prop = drmModeGetProperty(b->drm.fd, props->props[i]); + prop = drmModeGetProperty(device->drm.fd, props->props[i]); if (!prop) continue; @@ -436,6 +437,8 @@ drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane, const drmModeObjectProperties *props, const bool use_modifiers) { + struct drm_backend *backend = plane->backend; + struct drm_device *device = backend->drm; unsigned i, j; drmModePropertyBlobRes *blob = NULL; struct drm_format_modifier_blob *fmt_mod_blob; @@ -454,7 +457,7 @@ drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane, if (blob_id == 0) goto fallback; - blob = drmModeGetPropertyBlob(plane->backend->drm.fd, blob_id); + blob = drmModeGetPropertyBlob(device->drm.fd, blob_id); if (!blob) goto fallback; @@ -515,12 +518,13 @@ drm_output_set_gamma(struct weston_output *output_base, struct drm_output *output = to_drm_output(output_base); struct drm_backend *backend = to_drm_backend(output->base.compositor); + struct drm_device *device = backend->drm; /* check */ if (output_base->gamma_size != size) return; - rc = drmModeCrtcSetGamma(backend->drm.fd, + rc = drmModeCrtcSetGamma(device->drm.fd, output->crtc->crtc_id, size, r, g, b); if (rc) @@ -539,6 +543,7 @@ drm_output_assign_state(struct drm_output_state *state, { struct drm_output *output = state->output; struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; struct drm_plane_state *plane_state; struct drm_head *head; @@ -555,13 +560,13 @@ drm_output_assign_state(struct drm_output_state *state, output->state_cur = state; - if (b->atomic_modeset && mode == DRM_STATE_APPLY_ASYNC) { + if (device->atomic_modeset && mode == DRM_STATE_APPLY_ASYNC) { drm_debug(b, "\t[CRTC:%u] setting pending flip\n", output->crtc->crtc_id); output->atomic_complete_pending = true; } - if (b->atomic_modeset && + if (device->atomic_modeset && state->protection == WESTON_HDCP_DISABLE) wl_list_for_each(head, &output->base.head_list, base.output_link) weston_head_set_content_protection_status(&head->base, @@ -583,7 +588,7 @@ drm_output_assign_state(struct drm_output_state *state, continue; } - if (b->atomic_modeset) + if (device->atomic_modeset) continue; assert(plane->type != WDRM_PLANE_TYPE_OVERLAY); @@ -597,6 +602,7 @@ drm_output_set_cursor(struct drm_output_state *output_state) { struct drm_output *output = output_state->output; struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; struct drm_crtc *crtc = output->crtc; struct drm_plane *plane = output->cursor_plane; struct drm_plane_state *state; @@ -612,7 +618,7 @@ drm_output_set_cursor(struct drm_output_state *output_state) if (!state->fb) { pixman_region32_fini(&plane->base.damage); pixman_region32_init(&plane->base.damage); - drmModeSetCursor(b->drm.fd, crtc->crtc_id, 0, 0, 0); + drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0); return; } @@ -621,8 +627,8 @@ drm_output_set_cursor(struct drm_output_state *output_state) handle = output->gbm_cursor_handle[output->current_cursor]; if (plane->state_cur->fb != state->fb) { - if (drmModeSetCursor(b->drm.fd, crtc->crtc_id, handle, - b->cursor_width, b->cursor_height)) { + if (drmModeSetCursor(device->drm.fd, crtc->crtc_id, handle, + device->cursor_width, device->cursor_height)) { weston_log("failed to set cursor: %s\n", strerror(errno)); goto err; @@ -632,7 +638,7 @@ drm_output_set_cursor(struct drm_output_state *output_state) pixman_region32_fini(&plane->base.damage); pixman_region32_init(&plane->base.damage); - if (drmModeMoveCursor(b->drm.fd, crtc->crtc_id, + if (drmModeMoveCursor(device->drm.fd, crtc->crtc_id, state->dest_x, state->dest_y)) { weston_log("failed to move cursor: %s\n", strerror(errno)); goto err; @@ -641,8 +647,8 @@ drm_output_set_cursor(struct drm_output_state *output_state) return; err: - b->cursors_are_broken = true; - drmModeSetCursor(b->drm.fd, crtc->crtc_id, 0, 0, 0); + device->cursors_are_broken = true; + drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0); } static int @@ -650,6 +656,7 @@ drm_output_apply_state_legacy(struct drm_output_state *state) { struct drm_output *output = state->output; struct drm_backend *backend = to_drm_backend(output->base.compositor); + struct drm_device *device = backend->drm; struct drm_plane *scanout_plane = output->scanout_plane; struct drm_crtc *crtc = output->crtc; struct drm_property_info *dpms_prop; @@ -681,14 +688,14 @@ drm_output_apply_state_legacy(struct drm_output_state *state) if (state->dpms != WESTON_DPMS_ON) { if (output->cursor_plane) { - ret = drmModeSetCursor(backend->drm.fd, crtc->crtc_id, + ret = drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0); if (ret) weston_log("drmModeSetCursor failed disable: %s\n", strerror(errno)); } - ret = drmModeSetCrtc(backend->drm.fd, crtc->crtc_id, 0, 0, 0, + ret = drmModeSetCrtc(device->drm.fd, crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); if (ret) weston_log("drmModeSetCrtc failed disabling: %s\n", @@ -722,12 +729,12 @@ drm_output_apply_state_legacy(struct drm_output_state *state) assert(scanout_state->in_fence_fd == -1); mode = to_drm_mode(output->base.current_mode); - if (backend->state_invalid || + if (device->state_invalid || !scanout_plane->state_cur->fb || scanout_plane->state_cur->fb->strides[0] != scanout_state->fb->strides[0]) { - ret = drmModeSetCrtc(backend->drm.fd, crtc->crtc_id, + ret = drmModeSetCrtc(device->drm.fd, crtc->crtc_id, scanout_state->fb->fb_id, 0, 0, connectors, n_conn, @@ -743,7 +750,7 @@ drm_output_apply_state_legacy(struct drm_output_state *state) crtc->crtc_id, scanout_state->plane->plane_id, pinfo ? pinfo->drm_format_name : "UNKNOWN"); - if (drmModePageFlip(backend->drm.fd, crtc->crtc_id, + if (drmModePageFlip(device->drm.fd, crtc->crtc_id, scanout_state->fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, output) < 0) { weston_log("queueing pageflip failed: %s\n", strerror(errno)); @@ -764,7 +771,7 @@ drm_output_apply_state_legacy(struct drm_output_state *state) if (dpms_prop->prop_id == 0) continue; - ret = drmModeConnectorSetProperty(backend->drm.fd, + ret = drmModeConnectorSetProperty(device->drm.fd, head->connector.connector_id, dpms_prop->prop_id, state->dpms); @@ -1059,6 +1066,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, enum drm_state_apply_mode mode) { struct drm_backend *b = pending_state->backend; + struct drm_device *device = b->drm; struct drm_output_state *output_state, *tmp; struct drm_plane *plane; drmModeAtomicReq *req = drmModeAtomicAlloc(); @@ -1080,7 +1088,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, break; } - if (b->state_invalid) { + if (device->state_invalid) { struct weston_head *head_base; struct drm_head *head; struct drm_crtc *crtc; @@ -1117,7 +1125,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, ret = -1; } - wl_list_for_each(crtc, &b->crtc_list, link) { + wl_list_for_each(crtc, &device->crtc_list, link) { struct drm_property_info *info; drmModeObjectProperties *props; uint64_t active; @@ -1130,7 +1138,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, * off, as the kernel will refuse to generate an event * for an off->off state and fail the commit. */ - props = drmModeObjectGetProperties(b->drm.fd, + props = drmModeObjectGetProperties(device->drm.fd, crtc->crtc_id, DRM_MODE_OBJECT_CRTC); if (!props) { @@ -1153,7 +1161,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, /* Disable all the planes; planes which are being used will * override this state in the output-state application. */ - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { drm_debug(b, "\t\t[atomic] starting with plane %lu disabled\n", (unsigned long) plane->plane_id); plane_add_prop(req, plane, WDRM_PLANE_CRTC_ID, 0); @@ -1176,7 +1184,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, goto out; } - ret = drmModeAtomicCommit(b->drm.fd, req, flags, b); + ret = drmModeAtomicCommit(device->drm.fd, req, flags, b); drm_debug(b, "[atomic] drmModeAtomicCommit\n"); /* Test commits do not take ownership of the state; return @@ -1196,7 +1204,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state, link) drm_output_assign_state(output_state, mode); - b->state_invalid = false; + device->state_invalid = false; assert(wl_list_empty(&pending_state->output_list)); @@ -1228,8 +1236,9 @@ int drm_pending_state_test(struct drm_pending_state *pending_state) { struct drm_backend *b = pending_state->backend; + struct drm_device *device = b->drm; - if (b->atomic_modeset) + if (device->atomic_modeset) return drm_pending_state_apply_atomic(pending_state, DRM_STATE_TEST_ONLY); @@ -1249,23 +1258,24 @@ int drm_pending_state_apply(struct drm_pending_state *pending_state) { struct drm_backend *b = pending_state->backend; + struct drm_device *device = b->drm; struct drm_output_state *output_state, *tmp; struct drm_crtc *crtc; - if (b->atomic_modeset) + if (device->atomic_modeset) return drm_pending_state_apply_atomic(pending_state, DRM_STATE_APPLY_ASYNC); - if (b->state_invalid) { + if (device->state_invalid) { /* If we need to reset all our state (e.g. because we've * just started, or just been VT-switched in), explicitly * disable all the CRTCs we aren't using. This also disables * all connectors on these CRTCs, so we don't need to do that * separately with the pre-atomic API. */ - wl_list_for_each(crtc, &b->crtc_list, link) { + wl_list_for_each(crtc, &device->crtc_list, link) { if (crtc->output) continue; - drmModeSetCrtc(b->drm.fd, crtc->crtc_id, 0, 0, 0, + drmModeSetCrtc(device->drm.fd, crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); } } @@ -1288,7 +1298,7 @@ drm_pending_state_apply(struct drm_pending_state *pending_state) weston_output_repaint_failed(&output->base); drm_output_state_free(output->state_cur); output->state_cur = drm_output_state_alloc(output, NULL); - b->state_invalid = true; + device->state_invalid = true; if (!b->use_pixman) { drm_output_fini_egl(output); drm_output_init_egl(output, b); @@ -1296,7 +1306,7 @@ drm_pending_state_apply(struct drm_pending_state *pending_state) } } - b->state_invalid = false; + device->state_invalid = false; assert(wl_list_empty(&pending_state->output_list)); @@ -1315,24 +1325,25 @@ drm_pending_state_apply(struct drm_pending_state *pending_state) int drm_pending_state_apply_sync(struct drm_pending_state *pending_state) { - struct drm_backend *b = pending_state->backend; + struct drm_backend *backend = pending_state->backend; + struct drm_device *device = backend->drm; struct drm_output_state *output_state, *tmp; struct drm_crtc *crtc; - if (b->atomic_modeset) + if (device->atomic_modeset) return drm_pending_state_apply_atomic(pending_state, DRM_STATE_APPLY_SYNC); - if (b->state_invalid) { + if (device->state_invalid) { /* If we need to reset all our state (e.g. because we've * just started, or just been VT-switched in), explicitly * disable all the CRTCs we aren't using. This also disables * all connectors on these CRTCs, so we don't need to do that * separately with the pre-atomic API. */ - wl_list_for_each(crtc, &b->crtc_list, link) { + wl_list_for_each(crtc, &device->crtc_list, link) { if (crtc->output) continue; - drmModeSetCrtc(b->drm.fd, crtc->crtc_id, 0, 0, 0, + drmModeSetCrtc(device->drm.fd, crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); } } @@ -1349,7 +1360,7 @@ drm_pending_state_apply_sync(struct drm_pending_state *pending_state) } } - b->state_invalid = false; + device->state_invalid = false; assert(wl_list_empty(&pending_state->output_list)); @@ -1375,13 +1386,14 @@ page_flip_handler(int fd, unsigned int frame, { struct drm_output *output = data; struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC | WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION | WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK; drm_output_update_msc(output, frame); - assert(!b->atomic_modeset); + assert(!device->atomic_modeset); assert(output->page_flip_pending); output->page_flip_pending = false; @@ -1393,6 +1405,7 @@ atomic_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, unsigned int crtc_id, void *data) { struct drm_backend *b = data; + struct drm_device *device = b->drm; struct drm_crtc *crtc; struct drm_output *output; uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC | @@ -1413,7 +1426,7 @@ atomic_flip_handler(int fd, unsigned int frame, unsigned int sec, drm_output_update_msc(output, frame); drm_debug(b, "[atomic][CRTC:%u] flip processing started\n", crtc_id); - assert(b->atomic_modeset); + assert(device->atomic_modeset); assert(output->atomic_complete_pending); output->atomic_complete_pending = false; @@ -1424,12 +1437,12 @@ atomic_flip_handler(int fd, unsigned int frame, unsigned int sec, int on_drm_input(int fd, uint32_t mask, void *data) { - struct drm_backend *b = data; + struct drm_device *device = data; drmEventContext evctx; memset(&evctx, 0, sizeof evctx); evctx.version = 3; - if (b->atomic_modeset) + if (device->atomic_modeset) evctx.page_flip_handler2 = atomic_flip_handler; else evctx.page_flip_handler = page_flip_handler; @@ -1441,12 +1454,13 @@ on_drm_input(int fd, uint32_t mask, void *data) int init_kms_caps(struct drm_backend *b) { + struct drm_device *device = b->drm; uint64_t cap; int ret; - weston_log("using %s\n", b->drm.filename); + weston_log("using %s\n", device->drm.filename); - ret = drmGetCap(b->drm.fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap); + ret = drmGetCap(device->drm.fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap); if (ret != 0 || cap != 1) { weston_log("Error: kernel DRM KMS does not support DRM_CAP_TIMESTAMP_MONOTONIC.\n"); return -1; @@ -1457,43 +1471,43 @@ init_kms_caps(struct drm_backend *b) return -1; } - ret = drmGetCap(b->drm.fd, DRM_CAP_CURSOR_WIDTH, &cap); + ret = drmGetCap(device->drm.fd, DRM_CAP_CURSOR_WIDTH, &cap); if (ret == 0) - b->cursor_width = cap; + device->cursor_width = cap; else - b->cursor_width = 64; + device->cursor_width = 64; - ret = drmGetCap(b->drm.fd, DRM_CAP_CURSOR_HEIGHT, &cap); + ret = drmGetCap(device->drm.fd, DRM_CAP_CURSOR_HEIGHT, &cap); if (ret == 0) - b->cursor_height = cap; + device->cursor_height = cap; else - b->cursor_height = 64; + device->cursor_height = 64; - ret = drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + ret = drmSetClientCap(device->drm.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (ret) { weston_log("Error: drm card doesn't support universal planes!\n"); return -1; } if (!getenv("WESTON_DISABLE_ATOMIC")) { - ret = drmGetCap(b->drm.fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &cap); + ret = drmGetCap(device->drm.fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &cap); if (ret != 0) cap = 0; - ret = drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_ATOMIC, 1); - b->atomic_modeset = ((ret == 0) && (cap == 1)); + ret = drmSetClientCap(device->drm.fd, DRM_CLIENT_CAP_ATOMIC, 1); + device->atomic_modeset = ((ret == 0) && (cap == 1)); } weston_log("DRM: %s atomic modesetting\n", - b->atomic_modeset ? "supports" : "does not support"); + device->atomic_modeset ? "supports" : "does not support"); if (!getenv("WESTON_DISABLE_GBM_MODIFIERS")) { - ret = drmGetCap(b->drm.fd, DRM_CAP_ADDFB2_MODIFIERS, &cap); + ret = drmGetCap(device->drm.fd, DRM_CAP_ADDFB2_MODIFIERS, &cap); if (ret == 0) - b->fb_modifiers = cap; + device->fb_modifiers = cap; } weston_log("DRM: %s GBM modifiers\n", - b->fb_modifiers ? "supports" : "does not support"); + device->fb_modifiers ? "supports" : "does not support"); - drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1); + drmSetClientCap(device->drm.fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1); /* * KMS support for hardware planes cannot properly synchronize @@ -1503,13 +1517,13 @@ init_kms_caps(struct drm_backend *b) * to a fraction. For cursors, it's not so bad, so they are * enabled. */ - if (!b->atomic_modeset || getenv("WESTON_FORCE_RENDERER")) - b->sprites_are_broken = true; + if (!device->atomic_modeset || getenv("WESTON_FORCE_RENDERER")) + device->sprites_are_broken = true; - ret = drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_ASPECT_RATIO, 1); - b->aspect_ratio_supported = (ret == 0); + ret = drmSetClientCap(device->drm.fd, DRM_CLIENT_CAP_ASPECT_RATIO, 1); + device->aspect_ratio_supported = (ret == 0); weston_log("DRM: %s picture aspect ratio\n", - b->aspect_ratio_supported ? "supports" : "does not support"); + device->aspect_ratio_supported ? "supports" : "does not support"); return 0; } diff --git a/libweston/backend-drm/modes.c b/libweston/backend-drm/modes.c index f6b4248f..a228572b 100644 --- a/libweston/backend-drm/modes.c +++ b/libweston/backend-drm/modes.c @@ -100,12 +100,13 @@ drm_subpixel_to_wayland(int drm_value) int drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode) { + struct drm_device *device = backend->drm; int ret; if (mode->blob_id) return 0; - ret = drmModeCreatePropertyBlob(backend->drm.fd, + ret = drmModeCreatePropertyBlob(device->drm.fd, &mode->mode_info, sizeof(mode->mode_info), &mode->blob_id); @@ -320,6 +321,8 @@ find_and_parse_output_edid(struct drm_head *head, const char **serial_number, uint32_t *eotf_mask) { + struct drm_backend *backend = head->backend; + struct drm_device *device = backend->drm; drmModePropertyBlobPtr edid_blob = NULL; uint32_t blob_id; int rc; @@ -331,7 +334,7 @@ find_and_parse_output_edid(struct drm_head *head, if (!blob_id) return; - edid_blob = drmModeGetPropertyBlob(head->backend->drm.fd, blob_id); + edid_blob = drmModeGetPropertyBlob(device->drm.fd, blob_id); if (!edid_blob) return; @@ -360,7 +363,7 @@ prune_eotf_modes_by_kms_support(struct drm_head *head, uint32_t *eotf_mask) /* Without the KMS property, cannot do anything but SDR. */ info = &head->connector.props[WDRM_CONNECTOR_HDR_OUTPUT_METADATA]; - if (!head->backend->atomic_modeset || info->prop_id == 0) + if (!head->backend->drm->atomic_modeset || info->prop_id == 0) *eotf_mask = WESTON_EOTF_MODE_SDR; } @@ -426,8 +429,10 @@ drm_output_add_mode(struct drm_output *output, const drmModeModeInfo *info) static void drm_output_destroy_mode(struct drm_backend *backend, struct drm_mode *mode) { + struct drm_device *device = backend->drm; + if (mode->blob_id) - drmModeDestroyPropertyBlob(backend->drm.fd, mode->blob_id); + drmModeDestroyPropertyBlob(device->drm.fd, mode->blob_id); wl_list_remove(&mode->base.link); free(mode); } @@ -488,15 +493,17 @@ drm_output_choose_mode(struct drm_output *output, enum weston_mode_aspect_ratio src_aspect = WESTON_MODE_PIC_AR_NONE; enum weston_mode_aspect_ratio target_aspect = WESTON_MODE_PIC_AR_NONE; struct drm_backend *b; + struct drm_device *device; b = to_drm_backend(output->base.compositor); + device = b->drm; target_aspect = target_mode->aspect_ratio; src_aspect = output->base.current_mode->aspect_ratio; if (output->base.current_mode->width == target_mode->width && output->base.current_mode->height == target_mode->height && (output->base.current_mode->refresh == target_mode->refresh || target_mode->refresh == 0)) { - if (!b->aspect_ratio_supported || src_aspect == target_aspect) + if (!device->aspect_ratio_supported || src_aspect == target_aspect) return to_drm_mode(output->base.current_mode); } @@ -507,7 +514,7 @@ drm_output_choose_mode(struct drm_output *output, mode->mode_info.vdisplay == target_mode->height) { if (mode->base.refresh == target_mode->refresh || target_mode->refresh == 0) { - if (!b->aspect_ratio_supported || + if (!device->aspect_ratio_supported || src_aspect == target_aspect) return mode; else if (!mode_fall_back) @@ -574,6 +581,7 @@ drm_output_choose_initial_mode(struct drm_backend *backend, const char *modeline, const drmModeModeInfo *current_mode) { + struct drm_device *device = backend->drm; struct drm_mode *preferred = NULL; struct drm_mode *current = NULL; struct drm_mode *configured = NULL; @@ -592,7 +600,7 @@ drm_output_choose_initial_mode(struct drm_backend *backend, if (mode == WESTON_DRM_BACKEND_OUTPUT_PREFERRED && modeline) { n = sscanf(modeline, "%dx%d@%d %u:%u", &width, &height, &refresh, &aspect_width, &aspect_height); - if (backend->aspect_ratio_supported && n == 5) { + if (device->aspect_ratio_supported && n == 5) { if (aspect_width == 4 && aspect_height == 3) aspect_ratio = WESTON_MODE_PIC_AR_4_3; else if (aspect_width == 16 && aspect_height == 9) @@ -623,7 +631,7 @@ drm_output_choose_initial_mode(struct drm_backend *backend, if (width == drm_mode->base.width && height == drm_mode->base.height && (refresh == 0 || refresh == drm_mode->mode_info.vrefresh)) { - if (!backend->aspect_ratio_supported || + if (!device->aspect_ratio_supported || aspect_ratio == drm_mode->base.aspect_ratio) configured = drm_mode; else diff --git a/libweston/backend-drm/state-helpers.c b/libweston/backend-drm/state-helpers.c index 245ee087..d184602d 100644 --- a/libweston/backend-drm/state-helpers.c +++ b/libweston/backend-drm/state-helpers.c @@ -73,6 +73,9 @@ drm_plane_state_alloc(struct drm_output_state *state_output, void drm_plane_state_free(struct drm_plane_state *state, bool force) { + struct drm_backend *backend; + struct drm_device *device; + if (!state) return; @@ -86,7 +89,10 @@ drm_plane_state_free(struct drm_plane_state *state, bool force) * by the kernel, which means we can safely discard it. */ if (state->damage_blob_id != 0) { - drmModeDestroyPropertyBlob(state->plane->backend->drm.fd, + backend = state->plane->backend; + device = backend->drm; + + drmModeDestroyPropertyBlob(device->drm.fd, state->damage_blob_id); state->damage_blob_id = 0; } diff --git a/libweston/backend-drm/state-propose.c b/libweston/backend-drm/state-propose.c index 82da1f37..f1291711 100644 --- a/libweston/backend-drm/state-propose.c +++ b/libweston/backend-drm/state-propose.c @@ -86,10 +86,11 @@ drm_output_try_view_on_plane(struct drm_plane *plane, struct weston_compositor *ec = output->base.compositor; struct weston_surface *surface = ev->surface; struct drm_backend *b = to_drm_backend(ec); + struct drm_device *device = b->drm; struct drm_plane_state *state = NULL; - assert(!b->sprites_are_broken); - assert(b->atomic_modeset); + assert(!device->sprites_are_broken); + assert(device->atomic_modeset); assert(fb); assert(mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY || (mode == DRM_OUTPUT_PROPOSE_STATE_MIXED && @@ -162,16 +163,17 @@ static void cursor_bo_update(struct drm_plane_state *plane_state, struct weston_view *ev) { struct drm_backend *b = plane_state->plane->backend; + struct drm_device *device = b->drm; struct gbm_bo *bo = plane_state->fb->bo; struct weston_buffer *buffer = ev->surface->buffer_ref.buffer; - uint32_t buf[b->cursor_width * b->cursor_height]; + uint32_t buf[device->cursor_width * device->cursor_height]; int32_t stride; uint8_t *s; int i; assert(buffer && buffer->shm_buffer); - assert(buffer->width <= b->cursor_width); - assert(buffer->height <= b->cursor_height); + assert(buffer->width <= device->cursor_width); + assert(buffer->height <= device->cursor_height); memset(buf, 0, sizeof buf); stride = wl_shm_buffer_get_stride(buffer->shm_buffer); @@ -179,7 +181,7 @@ cursor_bo_update(struct drm_plane_state *plane_state, struct weston_view *ev) wl_shm_buffer_begin_access(buffer->shm_buffer); for (i = 0; i < buffer->height; i++) - memcpy(buf + i * b->cursor_width, + memcpy(buf + i * device->cursor_width, s + i * stride, buffer->width * 4); wl_shm_buffer_end_access(buffer->shm_buffer); @@ -194,12 +196,13 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state, { struct drm_output *output = output_state->output; struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; struct drm_plane *plane = output->cursor_plane; struct drm_plane_state *plane_state; bool needs_update = false; const char *p_name = drm_output_get_plane_type_name(plane); - assert(!b->cursors_are_broken); + assert(!device->cursors_are_broken); assert(plane); assert(plane->state_cur->complete); assert(!plane->state_cur->output || plane->state_cur->output == output); @@ -220,8 +223,8 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state, } if (plane_state->src_x != 0 || plane_state->src_y != 0 || - plane_state->src_w > (unsigned) b->cursor_width << 16 || - plane_state->src_h > (unsigned) b->cursor_height << 16 || + plane_state->src_w > (unsigned) device->cursor_width << 16 || + plane_state->src_h > (unsigned) device->cursor_height << 16 || plane_state->src_w != plane_state->dest_w << 16 || plane_state->src_h != plane_state->dest_h << 16) { drm_debug(b, "\t\t\t\t[%s] not assigning view %p to %s plane " @@ -260,10 +263,10 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state, * a buffer which is always cursor_width x cursor_height, even if the * surface we want to promote is actually smaller than this. Manually * mangle the plane state to deal with this. */ - plane_state->src_w = b->cursor_width << 16; - plane_state->src_h = b->cursor_height << 16; - plane_state->dest_w = b->cursor_width; - plane_state->dest_h = b->cursor_height; + plane_state->src_w = device->cursor_width << 16; + plane_state->src_h = device->cursor_height << 16; + plane_state->dest_w = device->cursor_width; + plane_state->dest_h = device->cursor_height; drm_debug(b, "\t\t\t\t[%s] provisionally assigned view %p to cursor\n", p_name, ev); @@ -328,7 +331,8 @@ dmabuf_feedback_maybe_update(struct drm_backend *b, struct weston_view *ev, { struct weston_dmabuf_feedback *dmabuf_feedback = ev->surface->dmabuf_feedback; struct weston_dmabuf_feedback_tranche *scanout_tranche; - dev_t scanout_dev = b->drm.devnum; + struct drm_device *device = b->drm; + dev_t scanout_dev = device->drm.devnum; uint32_t scanout_flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT; uint32_t action_needed = ACTION_NEEDED_NONE; struct timespec current_time, delta_time; @@ -428,6 +432,7 @@ drm_output_find_plane_for_view(struct drm_output_state *state, { struct drm_output *output = state->output; struct drm_backend *b = to_drm_backend(output->base.compositor); + struct drm_device *device = b->drm; struct drm_plane_state *ps = NULL; struct drm_plane *plane; @@ -454,7 +459,7 @@ drm_output_find_plane_for_view(struct drm_output_state *state, FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; return NULL; } else if (buffer->type == WESTON_BUFFER_SHM) { - if (!output->cursor_plane || b->cursors_are_broken) { + if (!output->cursor_plane || device->cursors_are_broken) { pnode->try_view_on_plane_failure_reasons |= FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; return NULL; @@ -471,8 +476,8 @@ drm_output_find_plane_for_view(struct drm_output_state *state, return NULL; } - if (buffer->width > b->cursor_width || - buffer->height > b->cursor_height) { + if (buffer->width > device->cursor_width || + buffer->height > device->cursor_height) { drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane " "(buffer (%dx%d) too large for cursor plane)\n", ev, buffer->width, buffer->height); @@ -507,7 +512,7 @@ drm_output_find_plane_for_view(struct drm_output_state *state, state); /* assemble a list with possible candidates */ - wl_list_for_each(plane, &b->plane_list, link) { + wl_list_for_each(plane, &device->plane_list, link) { const char *p_name = drm_output_get_plane_type_name(plane); uint64_t zpos; @@ -912,7 +917,8 @@ void drm_assign_planes(struct weston_output *output_base) { struct drm_backend *b = to_drm_backend(output_base->compositor); - struct drm_pending_state *pending_state = b->repaint_data; + struct drm_device *device = b->drm; + struct drm_pending_state *pending_state = device->repaint_data; struct drm_output *output = to_drm_output(output_base); struct drm_output_state *state = NULL; struct drm_plane_state *plane_state; @@ -923,7 +929,7 @@ drm_assign_planes(struct weston_output *output_base) drm_debug(b, "\t[repaint] preparing state for output %s (%lu)\n", output_base->name, (unsigned long) output_base->id); - if (!b->sprites_are_broken && !output->virtual && b->gbm) { + if (!device->sprites_are_broken && !output->virtual && b->gbm) { drm_debug(b, "\t[repaint] trying planes-only build state\n"); state = drm_output_propose_state(output_base, pending_state, mode); if (!state) { @@ -985,8 +991,8 @@ drm_assign_planes(struct weston_output *output_base) buffer->type == WESTON_BUFFER_RENDERER_OPAQUE) ev->surface->keep_buffer = true; else if (buffer->type == WESTON_BUFFER_SHM && - (ev->surface->width <= b->cursor_width && - ev->surface->height <= b->cursor_height)) + (ev->surface->width <= device->cursor_width && + ev->surface->height <= device->cursor_height)) ev->surface->keep_buffer = true; }