backend-drm: extract device from backend
Extract the kms device from the backend to allow a better separation of the backend and the kms device. This will allow to handle multiple kms devices with a single drm backend. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
This commit is contained in:
parent
2860933ded
commit
0d967bd7f4
@ -118,8 +118,9 @@ drm_backend_create_gl_renderer(struct drm_backend *b)
|
|||||||
int
|
int
|
||||||
init_egl(struct drm_backend *b)
|
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)
|
if (!b->gbm)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -145,6 +146,7 @@ static void drm_output_fini_cursor_egl(struct drm_output *output)
|
|||||||
static int
|
static int
|
||||||
drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b)
|
drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* No point creating cursors if we don't have a plane for them. */
|
/* 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++) {
|
for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
|
||||||
struct gbm_bo *bo;
|
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_FORMAT_ARGB8888,
|
||||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
||||||
if (!bo)
|
if (!bo)
|
||||||
@ -173,7 +175,7 @@ drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b)
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
weston_log("cursor buffers unavailable, using gl cursors\n");
|
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);
|
drm_output_fini_cursor_egl(output);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -317,6 +319,7 @@ drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage)
|
|||||||
static void
|
static void
|
||||||
switch_to_gl_renderer(struct drm_backend *b)
|
switch_to_gl_renderer(struct drm_backend *b)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_output *output;
|
struct drm_output *output;
|
||||||
bool dmabuf_support_inited;
|
bool dmabuf_support_inited;
|
||||||
bool linux_explicit_sync_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");
|
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) {
|
if (!b->gbm) {
|
||||||
weston_log("Failed to create gbm device. "
|
weston_log("Failed to create gbm device. "
|
||||||
"Aborting renderer switch\n");
|
"Aborting renderer switch\n");
|
||||||
|
@ -259,6 +259,48 @@ enum actions_needed_dmabuf_feedback {
|
|||||||
ACTION_NEEDED_REMOVE_SCANOUT_TRANCHE = (1 << 1),
|
ACTION_NEEDED_REMOVE_SCANOUT_TRANCHE = (1 << 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct drm_device {
|
||||||
|
struct drm_backend *backend;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int id;
|
||||||
|
int fd;
|
||||||
|
char *filename;
|
||||||
|
dev_t devnum;
|
||||||
|
} drm;
|
||||||
|
|
||||||
|
/* drm_crtc::link */
|
||||||
|
struct wl_list crtc_list;
|
||||||
|
|
||||||
|
struct wl_list plane_list;
|
||||||
|
|
||||||
|
/* drm_writeback::link */
|
||||||
|
struct wl_list writeback_connector_list;
|
||||||
|
|
||||||
|
bool state_invalid;
|
||||||
|
|
||||||
|
bool atomic_modeset;
|
||||||
|
|
||||||
|
bool aspect_ratio_supported;
|
||||||
|
|
||||||
|
int32_t cursor_width;
|
||||||
|
int32_t cursor_height;
|
||||||
|
|
||||||
|
bool cursors_are_broken;
|
||||||
|
bool sprites_are_broken;
|
||||||
|
|
||||||
|
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 drm_backend {
|
||||||
struct weston_backend base;
|
struct weston_backend base;
|
||||||
struct weston_compositor *compositor;
|
struct weston_compositor *compositor;
|
||||||
@ -269,56 +311,20 @@ struct drm_backend {
|
|||||||
struct udev_monitor *udev_monitor;
|
struct udev_monitor *udev_monitor;
|
||||||
struct wl_event_source *udev_drm_source;
|
struct wl_event_source *udev_drm_source;
|
||||||
|
|
||||||
struct {
|
struct drm_device *drm;
|
||||||
int id;
|
|
||||||
int fd;
|
|
||||||
char *filename;
|
|
||||||
dev_t devnum;
|
|
||||||
} drm;
|
|
||||||
struct gbm_device *gbm;
|
struct gbm_device *gbm;
|
||||||
struct wl_listener session_listener;
|
struct wl_listener session_listener;
|
||||||
uint32_t gbm_format;
|
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;
|
|
||||||
|
|
||||||
struct wl_list plane_list;
|
|
||||||
|
|
||||||
void *repaint_data;
|
|
||||||
|
|
||||||
bool state_invalid;
|
|
||||||
|
|
||||||
/* drm_crtc::link */
|
|
||||||
struct wl_list crtc_list;
|
|
||||||
|
|
||||||
/* drm_writeback::link */
|
|
||||||
struct wl_list writeback_connector_list;
|
|
||||||
|
|
||||||
bool sprites_are_broken;
|
|
||||||
bool cursors_are_broken;
|
|
||||||
|
|
||||||
bool atomic_modeset;
|
|
||||||
|
|
||||||
bool use_pixman;
|
bool use_pixman;
|
||||||
bool use_pixman_shadow;
|
bool use_pixman_shadow;
|
||||||
|
|
||||||
struct udev_input input;
|
struct udev_input input;
|
||||||
|
|
||||||
int32_t cursor_width;
|
|
||||||
int32_t cursor_height;
|
|
||||||
|
|
||||||
uint32_t pageflip_timeout;
|
uint32_t pageflip_timeout;
|
||||||
|
|
||||||
bool shutting_down;
|
bool shutting_down;
|
||||||
|
|
||||||
bool aspect_ratio_supported;
|
|
||||||
|
|
||||||
bool fb_modifiers;
|
|
||||||
|
|
||||||
struct weston_log_scope *debug;
|
struct weston_log_scope *debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ drm_virtual_crtc_destroy(struct drm_crtc *crtc)
|
|||||||
static struct drm_plane *
|
static struct drm_plane *
|
||||||
drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output)
|
drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
struct weston_drm_format *fmt;
|
struct weston_drm_format *fmt;
|
||||||
uint64_t mod;
|
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.
|
/* If output supports linear modifier, we add it to the plane.
|
||||||
* Otherwise we add DRM_FORMAT_MOD_INVALID, as explicit modifiers
|
* Otherwise we add DRM_FORMAT_MOD_INVALID, as explicit modifiers
|
||||||
* are not supported. */
|
* 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;
|
mod = DRM_FORMAT_MOD_LINEAR;
|
||||||
else
|
else
|
||||||
mod = DRM_FORMAT_MOD_INVALID;
|
mod = DRM_FORMAT_MOD_INVALID;
|
||||||
@ -124,7 +125,7 @@ drm_virtual_plane_create(struct drm_backend *b, struct drm_output *output)
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
weston_plane_init(&plane->base, b->compositor, 0, 0);
|
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;
|
return plane;
|
||||||
|
|
||||||
@ -192,11 +193,13 @@ drm_virtual_output_repaint(struct weston_output *output_base,
|
|||||||
struct drm_plane_state *scanout_state;
|
struct drm_plane_state *scanout_state;
|
||||||
struct drm_pending_state *pending_state;
|
struct drm_pending_state *pending_state;
|
||||||
struct drm_backend *backend;
|
struct drm_backend *backend;
|
||||||
|
struct drm_device *device;
|
||||||
|
|
||||||
assert(output->virtual);
|
assert(output->virtual);
|
||||||
|
|
||||||
backend = output->backend;
|
backend = output->backend;
|
||||||
pending_state = backend->repaint_data;
|
device = backend->drm;
|
||||||
|
pending_state = device->repaint_data;
|
||||||
|
|
||||||
if (output->disable_pending || output->destroy_pending)
|
if (output->disable_pending || output->destroy_pending)
|
||||||
goto err;
|
goto err;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -71,13 +71,14 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
|
|||||||
static int
|
static int
|
||||||
drm_fb_addfb(struct drm_backend *b, struct drm_fb *fb)
|
drm_fb_addfb(struct drm_backend *b, struct drm_fb *fb)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
uint64_t mods[4] = { };
|
uint64_t mods[4] = { };
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* If we have a modifier set, we must only use the WithModifiers
|
/* If we have a modifier set, we must only use the WithModifiers
|
||||||
* entrypoint; we cannot import it through legacy ioctls. */
|
* 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
|
/* KMS demands that if a modifier is set, it must be the same
|
||||||
* for all planes. */
|
* for all planes. */
|
||||||
for (i = 0; i < ARRAY_LENGTH(mods) && fb->handles[i]; i++)
|
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,
|
drm_fb_create_dumb(struct drm_backend *b, int width, int height,
|
||||||
uint32_t format)
|
uint32_t format)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_fb *fb;
|
struct drm_fb *fb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -145,7 +147,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int height,
|
|||||||
create_arg.width = width;
|
create_arg.width = width;
|
||||||
create_arg.height = height;
|
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)
|
if (ret)
|
||||||
goto err_fb;
|
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->size = create_arg.size;
|
||||||
fb->width = width;
|
fb->width = width;
|
||||||
fb->height = height;
|
fb->height = height;
|
||||||
fb->fd = b->drm.fd;
|
fb->fd = device->drm.fd;
|
||||||
|
|
||||||
if (drm_fb_addfb(b, fb) != 0) {
|
if (drm_fb_addfb(b, fb) != 0) {
|
||||||
weston_log("failed to create kms fb: %s\n", strerror(errno));
|
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;
|
goto err_add_fb;
|
||||||
|
|
||||||
fb->map = mmap(NULL, fb->size, PROT_WRITE,
|
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)
|
if (fb->map == MAP_FAILED)
|
||||||
goto err_add_fb;
|
goto err_add_fb;
|
||||||
|
|
||||||
return fb;
|
return fb;
|
||||||
|
|
||||||
err_add_fb:
|
err_add_fb:
|
||||||
drmModeRmFB(b->drm.fd, fb->fb_id);
|
drmModeRmFB(device->drm.fd, fb->fb_id);
|
||||||
err_bo:
|
err_bo:
|
||||||
memset(&destroy_arg, 0, sizeof(destroy_arg));
|
memset(&destroy_arg, 0, sizeof(destroy_arg));
|
||||||
destroy_arg.handle = create_arg.handle;
|
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:
|
err_fb:
|
||||||
free(fb);
|
free(fb);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -227,6 +229,7 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
|
|||||||
* of GBM_BO_IMPORT_FD_MODIFIER. */
|
* of GBM_BO_IMPORT_FD_MODIFIER. */
|
||||||
return NULL;
|
return NULL;
|
||||||
#else
|
#else
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
struct drm_fb *fb;
|
struct drm_fb *fb;
|
||||||
int i;
|
int i;
|
||||||
struct gbm_import_fd_modifier_data import_mod = {
|
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->height = dmabuf->attributes.height;
|
||||||
fb->modifier = dmabuf->attributes.modifier[0];
|
fb->modifier = dmabuf->attributes.modifier[0];
|
||||||
fb->size = 0;
|
fb->size = 0;
|
||||||
fb->fd = backend->drm.fd;
|
fb->fd = device->drm.fd;
|
||||||
|
|
||||||
ARRAY_COPY(fb->strides, dmabuf->attributes.stride);
|
ARRAY_COPY(fb->strides, dmabuf->attributes.stride);
|
||||||
ARRAY_COPY(fb->offsets, dmabuf->attributes.offset);
|
ARRAY_COPY(fb->offsets, dmabuf->attributes.offset);
|
||||||
@ -302,10 +305,10 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
|
|||||||
if (is_opaque)
|
if (is_opaque)
|
||||||
fb->format = pixel_format_get_opaque_substitute(fb->format);
|
fb->format = pixel_format_get_opaque_substitute(fb->format);
|
||||||
|
|
||||||
if (backend->min_width > fb->width ||
|
if (device->min_width > fb->width ||
|
||||||
fb->width > backend->max_width ||
|
fb->width > device->max_width ||
|
||||||
backend->min_height > fb->height ||
|
device->min_height > fb->height ||
|
||||||
fb->height > backend->max_height) {
|
fb->height > device->max_height) {
|
||||||
weston_log("bo geometry out of bounds\n");
|
weston_log("bo geometry out of bounds\n");
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
@ -342,6 +345,7 @@ struct drm_fb *
|
|||||||
drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
|
drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
|
||||||
bool is_opaque, enum drm_fb_type type)
|
bool is_opaque, enum drm_fb_type type)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
struct drm_fb *fb = gbm_bo_get_user_data(bo);
|
struct drm_fb *fb = gbm_bo_get_user_data(bo);
|
||||||
#ifdef HAVE_GBM_MODIFIERS
|
#ifdef HAVE_GBM_MODIFIERS
|
||||||
int i;
|
int i;
|
||||||
@ -359,7 +363,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
|
|||||||
fb->type = type;
|
fb->type = type;
|
||||||
fb->refcnt = 1;
|
fb->refcnt = 1;
|
||||||
fb->bo = bo;
|
fb->bo = bo;
|
||||||
fb->fd = backend->drm.fd;
|
fb->fd = device->drm.fd;
|
||||||
|
|
||||||
fb->width = gbm_bo_get_width(bo);
|
fb->width = gbm_bo_get_width(bo);
|
||||||
fb->height = gbm_bo_get_height(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)
|
if (is_opaque)
|
||||||
fb->format = pixel_format_get_opaque_substitute(fb->format);
|
fb->format = pixel_format_get_opaque_substitute(fb->format);
|
||||||
|
|
||||||
if (backend->min_width > fb->width ||
|
if (device->min_width > fb->width ||
|
||||||
fb->width > backend->max_width ||
|
fb->width > device->max_width ||
|
||||||
backend->min_height > fb->height ||
|
device->min_height > fb->height ||
|
||||||
fb->height > backend->max_height) {
|
fb->height > device->max_height) {
|
||||||
weston_log("bo geometry out of bounds\n");
|
weston_log("bo geometry out of bounds\n");
|
||||||
goto err_free;
|
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_output *output = state->output;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
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 weston_buffer *buffer = ev->surface->buffer_ref.buffer;
|
||||||
struct drm_buffer_fb *buf_fb;
|
struct drm_buffer_fb *buf_fb;
|
||||||
bool is_opaque = weston_view_is_opaque(ev, &ev->transform.boundingbox);
|
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
|
/* 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. */
|
* 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 */
|
/* only SHM buffers can go into cursor planes */
|
||||||
if (plane->type == WDRM_PLANE_TYPE_CURSOR)
|
if (plane->type == WDRM_PLANE_TYPE_CURSOR)
|
||||||
continue;
|
continue;
|
||||||
|
@ -108,6 +108,7 @@ weston_hdr_metadata_type1_to_kms(struct hdr_metadata_infoframe *dst,
|
|||||||
int
|
int
|
||||||
drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
|
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;
|
const struct weston_hdr_metadata_type1 *src;
|
||||||
struct hdr_output_metadata meta;
|
struct hdr_output_metadata meta;
|
||||||
uint32_t blob_id = 0;
|
uint32_t blob_id = 0;
|
||||||
@ -160,7 +161,7 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drmModeCreatePropertyBlob(output->backend->drm.fd,
|
ret = drmModeCreatePropertyBlob(device->drm.fd,
|
||||||
&meta, sizeof meta, &blob_id);
|
&meta, sizeof meta, &blob_id);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
weston_log("Error: failed to create KMS blob for HDR metadata on output '%s': %s\n",
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeDestroyPropertyBlob(output->backend->drm.fd,
|
drmModeDestroyPropertyBlob(device->drm.fd,
|
||||||
output->hdr_output_metadata_blob_id);
|
output->hdr_output_metadata_blob_id);
|
||||||
|
|
||||||
output->hdr_output_metadata_blob_id = blob_id;
|
output->hdr_output_metadata_blob_id = blob_id;
|
||||||
|
@ -288,6 +288,7 @@ drm_property_info_populate(struct drm_backend *b,
|
|||||||
unsigned int num_infos,
|
unsigned int num_infos,
|
||||||
drmModeObjectProperties *props)
|
drmModeObjectProperties *props)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
drmModePropertyRes *prop;
|
drmModePropertyRes *prop;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
|
||||||
@ -314,7 +315,7 @@ drm_property_info_populate(struct drm_backend *b,
|
|||||||
for (i = 0; i < props->count_props; i++) {
|
for (i = 0; i < props->count_props; i++) {
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
|
|
||||||
prop = drmModeGetProperty(b->drm.fd, props->props[i]);
|
prop = drmModeGetProperty(device->drm.fd, props->props[i]);
|
||||||
if (!prop)
|
if (!prop)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -436,6 +437,8 @@ drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
|
|||||||
const drmModeObjectProperties *props,
|
const drmModeObjectProperties *props,
|
||||||
const bool use_modifiers)
|
const bool use_modifiers)
|
||||||
{
|
{
|
||||||
|
struct drm_backend *backend = plane->backend;
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
drmModePropertyBlobRes *blob = NULL;
|
drmModePropertyBlobRes *blob = NULL;
|
||||||
struct drm_format_modifier_blob *fmt_mod_blob;
|
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)
|
if (blob_id == 0)
|
||||||
goto fallback;
|
goto fallback;
|
||||||
|
|
||||||
blob = drmModeGetPropertyBlob(plane->backend->drm.fd, blob_id);
|
blob = drmModeGetPropertyBlob(device->drm.fd, blob_id);
|
||||||
if (!blob)
|
if (!blob)
|
||||||
goto fallback;
|
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_output *output = to_drm_output(output_base);
|
||||||
struct drm_backend *backend =
|
struct drm_backend *backend =
|
||||||
to_drm_backend(output->base.compositor);
|
to_drm_backend(output->base.compositor);
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (output_base->gamma_size != size)
|
if (output_base->gamma_size != size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rc = drmModeCrtcSetGamma(backend->drm.fd,
|
rc = drmModeCrtcSetGamma(device->drm.fd,
|
||||||
output->crtc->crtc_id,
|
output->crtc->crtc_id,
|
||||||
size, r, g, b);
|
size, r, g, b);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -539,6 +543,7 @@ drm_output_assign_state(struct drm_output_state *state,
|
|||||||
{
|
{
|
||||||
struct drm_output *output = state->output;
|
struct drm_output *output = state->output;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_plane_state *plane_state;
|
struct drm_plane_state *plane_state;
|
||||||
struct drm_head *head;
|
struct drm_head *head;
|
||||||
|
|
||||||
@ -555,13 +560,13 @@ drm_output_assign_state(struct drm_output_state *state,
|
|||||||
|
|
||||||
output->state_cur = 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",
|
drm_debug(b, "\t[CRTC:%u] setting pending flip\n",
|
||||||
output->crtc->crtc_id);
|
output->crtc->crtc_id);
|
||||||
output->atomic_complete_pending = true;
|
output->atomic_complete_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b->atomic_modeset &&
|
if (device->atomic_modeset &&
|
||||||
state->protection == WESTON_HDCP_DISABLE)
|
state->protection == WESTON_HDCP_DISABLE)
|
||||||
wl_list_for_each(head, &output->base.head_list, base.output_link)
|
wl_list_for_each(head, &output->base.head_list, base.output_link)
|
||||||
weston_head_set_content_protection_status(&head->base,
|
weston_head_set_content_protection_status(&head->base,
|
||||||
@ -583,7 +588,7 @@ drm_output_assign_state(struct drm_output_state *state,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b->atomic_modeset)
|
if (device->atomic_modeset)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
assert(plane->type != WDRM_PLANE_TYPE_OVERLAY);
|
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_output *output = output_state->output;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_crtc *crtc = output->crtc;
|
struct drm_crtc *crtc = output->crtc;
|
||||||
struct drm_plane *plane = output->cursor_plane;
|
struct drm_plane *plane = output->cursor_plane;
|
||||||
struct drm_plane_state *state;
|
struct drm_plane_state *state;
|
||||||
@ -612,7 +618,7 @@ drm_output_set_cursor(struct drm_output_state *output_state)
|
|||||||
if (!state->fb) {
|
if (!state->fb) {
|
||||||
pixman_region32_fini(&plane->base.damage);
|
pixman_region32_fini(&plane->base.damage);
|
||||||
pixman_region32_init(&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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,8 +627,8 @@ drm_output_set_cursor(struct drm_output_state *output_state)
|
|||||||
|
|
||||||
handle = output->gbm_cursor_handle[output->current_cursor];
|
handle = output->gbm_cursor_handle[output->current_cursor];
|
||||||
if (plane->state_cur->fb != state->fb) {
|
if (plane->state_cur->fb != state->fb) {
|
||||||
if (drmModeSetCursor(b->drm.fd, crtc->crtc_id, handle,
|
if (drmModeSetCursor(device->drm.fd, crtc->crtc_id, handle,
|
||||||
b->cursor_width, b->cursor_height)) {
|
device->cursor_width, device->cursor_height)) {
|
||||||
weston_log("failed to set cursor: %s\n",
|
weston_log("failed to set cursor: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
@ -632,7 +638,7 @@ drm_output_set_cursor(struct drm_output_state *output_state)
|
|||||||
pixman_region32_fini(&plane->base.damage);
|
pixman_region32_fini(&plane->base.damage);
|
||||||
pixman_region32_init(&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)) {
|
state->dest_x, state->dest_y)) {
|
||||||
weston_log("failed to move cursor: %s\n", strerror(errno));
|
weston_log("failed to move cursor: %s\n", strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
@ -641,8 +647,8 @@ drm_output_set_cursor(struct drm_output_state *output_state)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
b->cursors_are_broken = true;
|
device->cursors_are_broken = true;
|
||||||
drmModeSetCursor(b->drm.fd, crtc->crtc_id, 0, 0, 0);
|
drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -650,6 +656,7 @@ drm_output_apply_state_legacy(struct drm_output_state *state)
|
|||||||
{
|
{
|
||||||
struct drm_output *output = state->output;
|
struct drm_output *output = state->output;
|
||||||
struct drm_backend *backend = to_drm_backend(output->base.compositor);
|
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_plane *scanout_plane = output->scanout_plane;
|
||||||
struct drm_crtc *crtc = output->crtc;
|
struct drm_crtc *crtc = output->crtc;
|
||||||
struct drm_property_info *dpms_prop;
|
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 (state->dpms != WESTON_DPMS_ON) {
|
||||||
if (output->cursor_plane) {
|
if (output->cursor_plane) {
|
||||||
ret = drmModeSetCursor(backend->drm.fd, crtc->crtc_id,
|
ret = drmModeSetCursor(device->drm.fd, crtc->crtc_id,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
weston_log("drmModeSetCursor failed disable: %s\n",
|
weston_log("drmModeSetCursor failed disable: %s\n",
|
||||||
strerror(errno));
|
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);
|
NULL, 0, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
weston_log("drmModeSetCrtc failed disabling: %s\n",
|
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);
|
assert(scanout_state->in_fence_fd == -1);
|
||||||
|
|
||||||
mode = to_drm_mode(output->base.current_mode);
|
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 ||
|
||||||
scanout_plane->state_cur->fb->strides[0] !=
|
scanout_plane->state_cur->fb->strides[0] !=
|
||||||
scanout_state->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,
|
scanout_state->fb->fb_id,
|
||||||
0, 0,
|
0, 0,
|
||||||
connectors, n_conn,
|
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,
|
crtc->crtc_id, scanout_state->plane->plane_id,
|
||||||
pinfo ? pinfo->drm_format_name : "UNKNOWN");
|
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,
|
scanout_state->fb->fb_id,
|
||||||
DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
|
DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
|
||||||
weston_log("queueing pageflip failed: %s\n", strerror(errno));
|
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)
|
if (dpms_prop->prop_id == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = drmModeConnectorSetProperty(backend->drm.fd,
|
ret = drmModeConnectorSetProperty(device->drm.fd,
|
||||||
head->connector.connector_id,
|
head->connector.connector_id,
|
||||||
dpms_prop->prop_id,
|
dpms_prop->prop_id,
|
||||||
state->dpms);
|
state->dpms);
|
||||||
@ -1059,6 +1066,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
|
|||||||
enum drm_state_apply_mode mode)
|
enum drm_state_apply_mode mode)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = pending_state->backend;
|
struct drm_backend *b = pending_state->backend;
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_output_state *output_state, *tmp;
|
struct drm_output_state *output_state, *tmp;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
||||||
@ -1080,7 +1088,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b->state_invalid) {
|
if (device->state_invalid) {
|
||||||
struct weston_head *head_base;
|
struct weston_head *head_base;
|
||||||
struct drm_head *head;
|
struct drm_head *head;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
@ -1117,7 +1125,7 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
|
|||||||
ret = -1;
|
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;
|
struct drm_property_info *info;
|
||||||
drmModeObjectProperties *props;
|
drmModeObjectProperties *props;
|
||||||
uint64_t active;
|
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
|
* off, as the kernel will refuse to generate an event
|
||||||
* for an off->off state and fail the commit.
|
* for an off->off state and fail the commit.
|
||||||
*/
|
*/
|
||||||
props = drmModeObjectGetProperties(b->drm.fd,
|
props = drmModeObjectGetProperties(device->drm.fd,
|
||||||
crtc->crtc_id,
|
crtc->crtc_id,
|
||||||
DRM_MODE_OBJECT_CRTC);
|
DRM_MODE_OBJECT_CRTC);
|
||||||
if (!props) {
|
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
|
/* Disable all the planes; planes which are being used will
|
||||||
* override this state in the output-state application. */
|
* 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",
|
drm_debug(b, "\t\t[atomic] starting with plane %lu disabled\n",
|
||||||
(unsigned long) plane->plane_id);
|
(unsigned long) plane->plane_id);
|
||||||
plane_add_prop(req, plane, WDRM_PLANE_CRTC_ID, 0);
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drmModeAtomicCommit(b->drm.fd, req, flags, b);
|
ret = drmModeAtomicCommit(device->drm.fd, req, flags, b);
|
||||||
drm_debug(b, "[atomic] drmModeAtomicCommit\n");
|
drm_debug(b, "[atomic] drmModeAtomicCommit\n");
|
||||||
|
|
||||||
/* Test commits do not take ownership of the state; return
|
/* 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)
|
link)
|
||||||
drm_output_assign_state(output_state, mode);
|
drm_output_assign_state(output_state, mode);
|
||||||
|
|
||||||
b->state_invalid = false;
|
device->state_invalid = false;
|
||||||
|
|
||||||
assert(wl_list_empty(&pending_state->output_list));
|
assert(wl_list_empty(&pending_state->output_list));
|
||||||
|
|
||||||
@ -1228,8 +1236,9 @@ int
|
|||||||
drm_pending_state_test(struct drm_pending_state *pending_state)
|
drm_pending_state_test(struct drm_pending_state *pending_state)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = pending_state->backend;
|
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,
|
return drm_pending_state_apply_atomic(pending_state,
|
||||||
DRM_STATE_TEST_ONLY);
|
DRM_STATE_TEST_ONLY);
|
||||||
|
|
||||||
@ -1249,23 +1258,24 @@ int
|
|||||||
drm_pending_state_apply(struct drm_pending_state *pending_state)
|
drm_pending_state_apply(struct drm_pending_state *pending_state)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = pending_state->backend;
|
struct drm_backend *b = pending_state->backend;
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_output_state *output_state, *tmp;
|
struct drm_output_state *output_state, *tmp;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
if (b->atomic_modeset)
|
if (device->atomic_modeset)
|
||||||
return drm_pending_state_apply_atomic(pending_state,
|
return drm_pending_state_apply_atomic(pending_state,
|
||||||
DRM_STATE_APPLY_ASYNC);
|
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
|
/* If we need to reset all our state (e.g. because we've
|
||||||
* just started, or just been VT-switched in), explicitly
|
* just started, or just been VT-switched in), explicitly
|
||||||
* disable all the CRTCs we aren't using. This also disables
|
* disable all the CRTCs we aren't using. This also disables
|
||||||
* all connectors on these CRTCs, so we don't need to do that
|
* all connectors on these CRTCs, so we don't need to do that
|
||||||
* separately with the pre-atomic API. */
|
* 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)
|
if (crtc->output)
|
||||||
continue;
|
continue;
|
||||||
drmModeSetCrtc(b->drm.fd, crtc->crtc_id, 0, 0, 0,
|
drmModeSetCrtc(device->drm.fd, crtc->crtc_id, 0, 0, 0,
|
||||||
NULL, 0, NULL);
|
NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1288,7 +1298,7 @@ drm_pending_state_apply(struct drm_pending_state *pending_state)
|
|||||||
weston_output_repaint_failed(&output->base);
|
weston_output_repaint_failed(&output->base);
|
||||||
drm_output_state_free(output->state_cur);
|
drm_output_state_free(output->state_cur);
|
||||||
output->state_cur = drm_output_state_alloc(output, NULL);
|
output->state_cur = drm_output_state_alloc(output, NULL);
|
||||||
b->state_invalid = true;
|
device->state_invalid = true;
|
||||||
if (!b->use_pixman) {
|
if (!b->use_pixman) {
|
||||||
drm_output_fini_egl(output);
|
drm_output_fini_egl(output);
|
||||||
drm_output_init_egl(output, b);
|
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));
|
assert(wl_list_empty(&pending_state->output_list));
|
||||||
|
|
||||||
@ -1315,24 +1325,25 @@ drm_pending_state_apply(struct drm_pending_state *pending_state)
|
|||||||
int
|
int
|
||||||
drm_pending_state_apply_sync(struct drm_pending_state *pending_state)
|
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_output_state *output_state, *tmp;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
if (b->atomic_modeset)
|
if (device->atomic_modeset)
|
||||||
return drm_pending_state_apply_atomic(pending_state,
|
return drm_pending_state_apply_atomic(pending_state,
|
||||||
DRM_STATE_APPLY_SYNC);
|
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
|
/* If we need to reset all our state (e.g. because we've
|
||||||
* just started, or just been VT-switched in), explicitly
|
* just started, or just been VT-switched in), explicitly
|
||||||
* disable all the CRTCs we aren't using. This also disables
|
* disable all the CRTCs we aren't using. This also disables
|
||||||
* all connectors on these CRTCs, so we don't need to do that
|
* all connectors on these CRTCs, so we don't need to do that
|
||||||
* separately with the pre-atomic API. */
|
* 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)
|
if (crtc->output)
|
||||||
continue;
|
continue;
|
||||||
drmModeSetCrtc(b->drm.fd, crtc->crtc_id, 0, 0, 0,
|
drmModeSetCrtc(device->drm.fd, crtc->crtc_id, 0, 0, 0,
|
||||||
NULL, 0, NULL);
|
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));
|
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_output *output = data;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC |
|
uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC |
|
||||||
WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
|
WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
|
||||||
WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
|
WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
|
||||||
|
|
||||||
drm_output_update_msc(output, frame);
|
drm_output_update_msc(output, frame);
|
||||||
|
|
||||||
assert(!b->atomic_modeset);
|
assert(!device->atomic_modeset);
|
||||||
assert(output->page_flip_pending);
|
assert(output->page_flip_pending);
|
||||||
output->page_flip_pending = false;
|
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)
|
unsigned int usec, unsigned int crtc_id, void *data)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = data;
|
struct drm_backend *b = data;
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_output *output;
|
struct drm_output *output;
|
||||||
uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC |
|
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_output_update_msc(output, frame);
|
||||||
|
|
||||||
drm_debug(b, "[atomic][CRTC:%u] flip processing started\n", crtc_id);
|
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);
|
assert(output->atomic_complete_pending);
|
||||||
output->atomic_complete_pending = false;
|
output->atomic_complete_pending = false;
|
||||||
|
|
||||||
@ -1424,12 +1437,12 @@ atomic_flip_handler(int fd, unsigned int frame, unsigned int sec,
|
|||||||
int
|
int
|
||||||
on_drm_input(int fd, uint32_t mask, void *data)
|
on_drm_input(int fd, uint32_t mask, void *data)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = data;
|
struct drm_device *device = data;
|
||||||
drmEventContext evctx;
|
drmEventContext evctx;
|
||||||
|
|
||||||
memset(&evctx, 0, sizeof evctx);
|
memset(&evctx, 0, sizeof evctx);
|
||||||
evctx.version = 3;
|
evctx.version = 3;
|
||||||
if (b->atomic_modeset)
|
if (device->atomic_modeset)
|
||||||
evctx.page_flip_handler2 = atomic_flip_handler;
|
evctx.page_flip_handler2 = atomic_flip_handler;
|
||||||
else
|
else
|
||||||
evctx.page_flip_handler = page_flip_handler;
|
evctx.page_flip_handler = page_flip_handler;
|
||||||
@ -1441,12 +1454,13 @@ on_drm_input(int fd, uint32_t mask, void *data)
|
|||||||
int
|
int
|
||||||
init_kms_caps(struct drm_backend *b)
|
init_kms_caps(struct drm_backend *b)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
uint64_t cap;
|
uint64_t cap;
|
||||||
int ret;
|
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) {
|
if (ret != 0 || cap != 1) {
|
||||||
weston_log("Error: kernel DRM KMS does not support DRM_CAP_TIMESTAMP_MONOTONIC.\n");
|
weston_log("Error: kernel DRM KMS does not support DRM_CAP_TIMESTAMP_MONOTONIC.\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1457,43 +1471,43 @@ init_kms_caps(struct drm_backend *b)
|
|||||||
return -1;
|
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)
|
if (ret == 0)
|
||||||
b->cursor_width = cap;
|
device->cursor_width = cap;
|
||||||
else
|
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)
|
if (ret == 0)
|
||||||
b->cursor_height = cap;
|
device->cursor_height = cap;
|
||||||
else
|
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) {
|
if (ret) {
|
||||||
weston_log("Error: drm card doesn't support universal planes!\n");
|
weston_log("Error: drm card doesn't support universal planes!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getenv("WESTON_DISABLE_ATOMIC")) {
|
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)
|
if (ret != 0)
|
||||||
cap = 0;
|
cap = 0;
|
||||||
ret = drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
ret = drmSetClientCap(device->drm.fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||||
b->atomic_modeset = ((ret == 0) && (cap == 1));
|
device->atomic_modeset = ((ret == 0) && (cap == 1));
|
||||||
}
|
}
|
||||||
weston_log("DRM: %s atomic modesetting\n",
|
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")) {
|
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)
|
if (ret == 0)
|
||||||
b->fb_modifiers = cap;
|
device->fb_modifiers = cap;
|
||||||
}
|
}
|
||||||
weston_log("DRM: %s GBM modifiers\n",
|
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
|
* 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
|
* to a fraction. For cursors, it's not so bad, so they are
|
||||||
* enabled.
|
* enabled.
|
||||||
*/
|
*/
|
||||||
if (!b->atomic_modeset || getenv("WESTON_FORCE_RENDERER"))
|
if (!device->atomic_modeset || getenv("WESTON_FORCE_RENDERER"))
|
||||||
b->sprites_are_broken = true;
|
device->sprites_are_broken = true;
|
||||||
|
|
||||||
ret = drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_ASPECT_RATIO, 1);
|
ret = drmSetClientCap(device->drm.fd, DRM_CLIENT_CAP_ASPECT_RATIO, 1);
|
||||||
b->aspect_ratio_supported = (ret == 0);
|
device->aspect_ratio_supported = (ret == 0);
|
||||||
weston_log("DRM: %s picture aspect ratio\n",
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -100,12 +100,13 @@ drm_subpixel_to_wayland(int drm_value)
|
|||||||
int
|
int
|
||||||
drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode)
|
drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (mode->blob_id)
|
if (mode->blob_id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = drmModeCreatePropertyBlob(backend->drm.fd,
|
ret = drmModeCreatePropertyBlob(device->drm.fd,
|
||||||
&mode->mode_info,
|
&mode->mode_info,
|
||||||
sizeof(mode->mode_info),
|
sizeof(mode->mode_info),
|
||||||
&mode->blob_id);
|
&mode->blob_id);
|
||||||
@ -320,6 +321,8 @@ find_and_parse_output_edid(struct drm_head *head,
|
|||||||
const char **serial_number,
|
const char **serial_number,
|
||||||
uint32_t *eotf_mask)
|
uint32_t *eotf_mask)
|
||||||
{
|
{
|
||||||
|
struct drm_backend *backend = head->backend;
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
drmModePropertyBlobPtr edid_blob = NULL;
|
drmModePropertyBlobPtr edid_blob = NULL;
|
||||||
uint32_t blob_id;
|
uint32_t blob_id;
|
||||||
int rc;
|
int rc;
|
||||||
@ -331,7 +334,7 @@ find_and_parse_output_edid(struct drm_head *head,
|
|||||||
if (!blob_id)
|
if (!blob_id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
edid_blob = drmModeGetPropertyBlob(head->backend->drm.fd, blob_id);
|
edid_blob = drmModeGetPropertyBlob(device->drm.fd, blob_id);
|
||||||
if (!edid_blob)
|
if (!edid_blob)
|
||||||
return;
|
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. */
|
/* Without the KMS property, cannot do anything but SDR. */
|
||||||
|
|
||||||
info = &head->connector.props[WDRM_CONNECTOR_HDR_OUTPUT_METADATA];
|
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;
|
*eotf_mask = WESTON_EOTF_MODE_SDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,8 +429,10 @@ drm_output_add_mode(struct drm_output *output, const drmModeModeInfo *info)
|
|||||||
static void
|
static void
|
||||||
drm_output_destroy_mode(struct drm_backend *backend, struct drm_mode *mode)
|
drm_output_destroy_mode(struct drm_backend *backend, struct drm_mode *mode)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
|
|
||||||
if (mode->blob_id)
|
if (mode->blob_id)
|
||||||
drmModeDestroyPropertyBlob(backend->drm.fd, mode->blob_id);
|
drmModeDestroyPropertyBlob(device->drm.fd, mode->blob_id);
|
||||||
wl_list_remove(&mode->base.link);
|
wl_list_remove(&mode->base.link);
|
||||||
free(mode);
|
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 src_aspect = WESTON_MODE_PIC_AR_NONE;
|
||||||
enum weston_mode_aspect_ratio target_aspect = WESTON_MODE_PIC_AR_NONE;
|
enum weston_mode_aspect_ratio target_aspect = WESTON_MODE_PIC_AR_NONE;
|
||||||
struct drm_backend *b;
|
struct drm_backend *b;
|
||||||
|
struct drm_device *device;
|
||||||
|
|
||||||
b = to_drm_backend(output->base.compositor);
|
b = to_drm_backend(output->base.compositor);
|
||||||
|
device = b->drm;
|
||||||
target_aspect = target_mode->aspect_ratio;
|
target_aspect = target_mode->aspect_ratio;
|
||||||
src_aspect = output->base.current_mode->aspect_ratio;
|
src_aspect = output->base.current_mode->aspect_ratio;
|
||||||
if (output->base.current_mode->width == target_mode->width &&
|
if (output->base.current_mode->width == target_mode->width &&
|
||||||
output->base.current_mode->height == target_mode->height &&
|
output->base.current_mode->height == target_mode->height &&
|
||||||
(output->base.current_mode->refresh == target_mode->refresh ||
|
(output->base.current_mode->refresh == target_mode->refresh ||
|
||||||
target_mode->refresh == 0)) {
|
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);
|
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) {
|
mode->mode_info.vdisplay == target_mode->height) {
|
||||||
if (mode->base.refresh == target_mode->refresh ||
|
if (mode->base.refresh == target_mode->refresh ||
|
||||||
target_mode->refresh == 0) {
|
target_mode->refresh == 0) {
|
||||||
if (!b->aspect_ratio_supported ||
|
if (!device->aspect_ratio_supported ||
|
||||||
src_aspect == target_aspect)
|
src_aspect == target_aspect)
|
||||||
return mode;
|
return mode;
|
||||||
else if (!mode_fall_back)
|
else if (!mode_fall_back)
|
||||||
@ -574,6 +581,7 @@ drm_output_choose_initial_mode(struct drm_backend *backend,
|
|||||||
const char *modeline,
|
const char *modeline,
|
||||||
const drmModeModeInfo *current_mode)
|
const drmModeModeInfo *current_mode)
|
||||||
{
|
{
|
||||||
|
struct drm_device *device = backend->drm;
|
||||||
struct drm_mode *preferred = NULL;
|
struct drm_mode *preferred = NULL;
|
||||||
struct drm_mode *current = NULL;
|
struct drm_mode *current = NULL;
|
||||||
struct drm_mode *configured = 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) {
|
if (mode == WESTON_DRM_BACKEND_OUTPUT_PREFERRED && modeline) {
|
||||||
n = sscanf(modeline, "%dx%d@%d %u:%u", &width, &height,
|
n = sscanf(modeline, "%dx%d@%d %u:%u", &width, &height,
|
||||||
&refresh, &aspect_width, &aspect_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)
|
if (aspect_width == 4 && aspect_height == 3)
|
||||||
aspect_ratio = WESTON_MODE_PIC_AR_4_3;
|
aspect_ratio = WESTON_MODE_PIC_AR_4_3;
|
||||||
else if (aspect_width == 16 && aspect_height == 9)
|
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 &&
|
if (width == drm_mode->base.width &&
|
||||||
height == drm_mode->base.height &&
|
height == drm_mode->base.height &&
|
||||||
(refresh == 0 || refresh == drm_mode->mode_info.vrefresh)) {
|
(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)
|
aspect_ratio == drm_mode->base.aspect_ratio)
|
||||||
configured = drm_mode;
|
configured = drm_mode;
|
||||||
else
|
else
|
||||||
|
@ -73,6 +73,9 @@ drm_plane_state_alloc(struct drm_output_state *state_output,
|
|||||||
void
|
void
|
||||||
drm_plane_state_free(struct drm_plane_state *state, bool force)
|
drm_plane_state_free(struct drm_plane_state *state, bool force)
|
||||||
{
|
{
|
||||||
|
struct drm_backend *backend;
|
||||||
|
struct drm_device *device;
|
||||||
|
|
||||||
if (!state)
|
if (!state)
|
||||||
return;
|
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.
|
* by the kernel, which means we can safely discard it.
|
||||||
*/
|
*/
|
||||||
if (state->damage_blob_id != 0) {
|
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);
|
||||||
state->damage_blob_id = 0;
|
state->damage_blob_id = 0;
|
||||||
}
|
}
|
||||||
|
@ -86,10 +86,11 @@ drm_output_try_view_on_plane(struct drm_plane *plane,
|
|||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
struct weston_surface *surface = ev->surface;
|
struct weston_surface *surface = ev->surface;
|
||||||
struct drm_backend *b = to_drm_backend(ec);
|
struct drm_backend *b = to_drm_backend(ec);
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct drm_plane_state *state = NULL;
|
struct drm_plane_state *state = NULL;
|
||||||
|
|
||||||
assert(!b->sprites_are_broken);
|
assert(!device->sprites_are_broken);
|
||||||
assert(b->atomic_modeset);
|
assert(device->atomic_modeset);
|
||||||
assert(fb);
|
assert(fb);
|
||||||
assert(mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY ||
|
assert(mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY ||
|
||||||
(mode == DRM_OUTPUT_PROPOSE_STATE_MIXED &&
|
(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)
|
cursor_bo_update(struct drm_plane_state *plane_state, struct weston_view *ev)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = plane_state->plane->backend;
|
struct drm_backend *b = plane_state->plane->backend;
|
||||||
|
struct drm_device *device = b->drm;
|
||||||
struct gbm_bo *bo = plane_state->fb->bo;
|
struct gbm_bo *bo = plane_state->fb->bo;
|
||||||
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
|
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;
|
int32_t stride;
|
||||||
uint8_t *s;
|
uint8_t *s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(buffer && buffer->shm_buffer);
|
assert(buffer && buffer->shm_buffer);
|
||||||
assert(buffer->width <= b->cursor_width);
|
assert(buffer->width <= device->cursor_width);
|
||||||
assert(buffer->height <= b->cursor_height);
|
assert(buffer->height <= device->cursor_height);
|
||||||
|
|
||||||
memset(buf, 0, sizeof buf);
|
memset(buf, 0, sizeof buf);
|
||||||
stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
|
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);
|
wl_shm_buffer_begin_access(buffer->shm_buffer);
|
||||||
for (i = 0; i < buffer->height; i++)
|
for (i = 0; i < buffer->height; i++)
|
||||||
memcpy(buf + i * b->cursor_width,
|
memcpy(buf + i * device->cursor_width,
|
||||||
s + i * stride,
|
s + i * stride,
|
||||||
buffer->width * 4);
|
buffer->width * 4);
|
||||||
wl_shm_buffer_end_access(buffer->shm_buffer);
|
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_output *output = output_state->output;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
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 *plane = output->cursor_plane;
|
||||||
struct drm_plane_state *plane_state;
|
struct drm_plane_state *plane_state;
|
||||||
bool needs_update = false;
|
bool needs_update = false;
|
||||||
const char *p_name = drm_output_get_plane_type_name(plane);
|
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);
|
||||||
assert(plane->state_cur->complete);
|
assert(plane->state_cur->complete);
|
||||||
assert(!plane->state_cur->output || plane->state_cur->output == output);
|
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 ||
|
if (plane_state->src_x != 0 || plane_state->src_y != 0 ||
|
||||||
plane_state->src_w > (unsigned) b->cursor_width << 16 ||
|
plane_state->src_w > (unsigned) device->cursor_width << 16 ||
|
||||||
plane_state->src_h > (unsigned) b->cursor_height << 16 ||
|
plane_state->src_h > (unsigned) device->cursor_height << 16 ||
|
||||||
plane_state->src_w != plane_state->dest_w << 16 ||
|
plane_state->src_w != plane_state->dest_w << 16 ||
|
||||||
plane_state->src_h != plane_state->dest_h << 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 "
|
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
|
* a buffer which is always cursor_width x cursor_height, even if the
|
||||||
* surface we want to promote is actually smaller than this. Manually
|
* surface we want to promote is actually smaller than this. Manually
|
||||||
* mangle the plane state to deal with this. */
|
* mangle the plane state to deal with this. */
|
||||||
plane_state->src_w = b->cursor_width << 16;
|
plane_state->src_w = device->cursor_width << 16;
|
||||||
plane_state->src_h = b->cursor_height << 16;
|
plane_state->src_h = device->cursor_height << 16;
|
||||||
plane_state->dest_w = b->cursor_width;
|
plane_state->dest_w = device->cursor_width;
|
||||||
plane_state->dest_h = b->cursor_height;
|
plane_state->dest_h = device->cursor_height;
|
||||||
|
|
||||||
drm_debug(b, "\t\t\t\t[%s] provisionally assigned view %p to cursor\n",
|
drm_debug(b, "\t\t\t\t[%s] provisionally assigned view %p to cursor\n",
|
||||||
p_name, ev);
|
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 *dmabuf_feedback = ev->surface->dmabuf_feedback;
|
||||||
struct weston_dmabuf_feedback_tranche *scanout_tranche;
|
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 scanout_flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT;
|
||||||
uint32_t action_needed = ACTION_NEEDED_NONE;
|
uint32_t action_needed = ACTION_NEEDED_NONE;
|
||||||
struct timespec current_time, delta_time;
|
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_output *output = state->output;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
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_state *ps = NULL;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
@ -454,7 +459,7 @@ drm_output_find_plane_for_view(struct drm_output_state *state,
|
|||||||
FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE;
|
FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (buffer->type == WESTON_BUFFER_SHM) {
|
} 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 |=
|
pnode->try_view_on_plane_failure_reasons |=
|
||||||
FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE;
|
FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -471,8 +476,8 @@ drm_output_find_plane_for_view(struct drm_output_state *state,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer->width > b->cursor_width ||
|
if (buffer->width > device->cursor_width ||
|
||||||
buffer->height > b->cursor_height) {
|
buffer->height > device->cursor_height) {
|
||||||
drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
|
drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
|
||||||
"(buffer (%dx%d) too large for cursor plane)\n",
|
"(buffer (%dx%d) too large for cursor plane)\n",
|
||||||
ev, buffer->width, buffer->height);
|
ev, buffer->width, buffer->height);
|
||||||
@ -507,7 +512,7 @@ drm_output_find_plane_for_view(struct drm_output_state *state,
|
|||||||
state);
|
state);
|
||||||
|
|
||||||
/* assemble a list with possible candidates */
|
/* 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);
|
const char *p_name = drm_output_get_plane_type_name(plane);
|
||||||
uint64_t zpos;
|
uint64_t zpos;
|
||||||
|
|
||||||
@ -912,7 +917,8 @@ void
|
|||||||
drm_assign_planes(struct weston_output *output_base)
|
drm_assign_planes(struct weston_output *output_base)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = to_drm_backend(output_base->compositor);
|
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 *output = to_drm_output(output_base);
|
||||||
struct drm_output_state *state = NULL;
|
struct drm_output_state *state = NULL;
|
||||||
struct drm_plane_state *plane_state;
|
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",
|
drm_debug(b, "\t[repaint] preparing state for output %s (%lu)\n",
|
||||||
output_base->name, (unsigned long) output_base->id);
|
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");
|
drm_debug(b, "\t[repaint] trying planes-only build state\n");
|
||||||
state = drm_output_propose_state(output_base, pending_state, mode);
|
state = drm_output_propose_state(output_base, pending_state, mode);
|
||||||
if (!state) {
|
if (!state) {
|
||||||
@ -985,8 +991,8 @@ drm_assign_planes(struct weston_output *output_base)
|
|||||||
buffer->type == WESTON_BUFFER_RENDERER_OPAQUE)
|
buffer->type == WESTON_BUFFER_RENDERER_OPAQUE)
|
||||||
ev->surface->keep_buffer = true;
|
ev->surface->keep_buffer = true;
|
||||||
else if (buffer->type == WESTON_BUFFER_SHM &&
|
else if (buffer->type == WESTON_BUFFER_SHM &&
|
||||||
(ev->surface->width <= b->cursor_width &&
|
(ev->surface->width <= device->cursor_width &&
|
||||||
ev->surface->height <= b->cursor_height))
|
ev->surface->height <= device->cursor_height))
|
||||||
ev->surface->keep_buffer = true;
|
ev->surface->keep_buffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user