aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2019-04-09 23:36:35 +0300
committerDrew DeVault <sir@cmpwn.com>2019-06-07 09:06:11 -0400
commite516ea4c798d4c02e77836d5e8196decb90a8774 (patch)
tree3fa5a19fdf2b79084a4c02a393794efe1ca0635e /backend
parent96d6fde5dc7ed2e9897297ed459246cb4133a30f (diff)
backend/drm: check format when scanning out DMA-BUF
Diffstat (limited to 'backend')
-rw-r--r--backend/drm/drm.c45
-rw-r--r--backend/drm/properties.c39
2 files changed, 63 insertions, 21 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 2e9ce589..a2a117d6 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -123,6 +123,8 @@ static bool init_planes(struct wlr_drm_backend *drm) {
uint32_t rgb_format = DRM_FORMAT_INVALID;
for (size_t j = 0; j < plane->count_formats; ++j) {
uint32_t fmt = plane->formats[j];
+ wlr_drm_format_set_add(&p->formats, fmt, DRM_FORMAT_MOD_INVALID);
+
if (fmt == DRM_FORMAT_ARGB8888) {
// Prefer formats with alpha channel
rgb_format = fmt;
@@ -141,6 +143,38 @@ static bool init_planes(struct wlr_drm_backend *drm) {
}
p->drm_format = rgb_format;
+ if (p->props.in_formats) {
+ uint64_t blob_id;
+ if (!get_drm_prop(drm->fd, p->id, p->props.in_formats, &blob_id)) {
+ wlr_log(WLR_ERROR, "Failed to read IN_FORMATS property");
+ drmModeFreePlane(plane);
+ goto error_planes;
+ }
+
+ drmModePropertyBlobRes *blob =
+ drmModeGetPropertyBlob(drm->fd, blob_id);
+ if (!blob) {
+ wlr_log(WLR_ERROR, "Failed to read IN_FORMATS blob");
+ drmModeFreePlane(plane);
+ goto error_planes;
+ }
+
+ struct drm_format_modifier_blob *data = blob->data;
+ uint32_t *fmts = (uint32_t *)((char *)data + data->formats_offset);
+ struct drm_format_modifier *mods = (struct drm_format_modifier *)
+ ((char *)data + data->modifiers_offset);
+ for (uint32_t i = 0; i < data->count_modifiers; ++i) {
+ for (int j = 0; j < 64; ++j) {
+ if (mods[i].formats & ((uint64_t)1 << j)) {
+ wlr_drm_format_set_add(&p->formats,
+ fmts[j + mods[i].offset], mods[i].modifier);
+ }
+ }
+ }
+
+ drmModeFreePropertyBlob(blob);
+ }
+
drmModeFreePlane(plane);
}
@@ -215,6 +249,11 @@ void finish_drm_resources(struct wlr_drm_backend *drm) {
return;
}
+ for (size_t i = 0; i < drm->num_planes; ++i) {
+ struct wlr_drm_plane *p = &drm->planes[i];
+ wlr_drm_format_set_finish(&p->formats);
+ }
+
for (size_t i = 0; i < drm->num_crtcs; ++i) {
struct wlr_drm_crtc *crtc = &drm->crtcs[i];
drmModeAtomicFree(crtc->atomic);
@@ -833,11 +872,13 @@ static bool drm_connector_set_dmabuf(struct wlr_output *output,
return false;
}
- // TODO: check plane input formats
-
if (attribs->width != output->width || attribs->height != output->height) {
return false;
}
+ if (!wlr_drm_format_set_has(&crtc->primary->formats,
+ attribs->format, attribs->modifier)) {
+ return false;
+ }
struct gbm_bo *bo = import_gbm_bo(&drm->renderer, attribs);
if (bo == NULL) {
diff --git a/backend/drm/properties.c b/backend/drm/properties.c
index 5541d1be..010b71d4 100644
--- a/backend/drm/properties.c
+++ b/backend/drm/properties.c
@@ -19,38 +19,39 @@ struct prop_info {
static const struct prop_info connector_info[] = {
#define INDEX(name) (offsetof(union wlr_drm_connector_props, name) / sizeof(uint32_t))
- { "CRTC_ID", INDEX(crtc_id) },
- { "DPMS", INDEX(dpms) },
- { "EDID", INDEX(edid) },
- { "PATH", INDEX(path) },
+ { "CRTC_ID", INDEX(crtc_id) },
+ { "DPMS", INDEX(dpms) },
+ { "EDID", INDEX(edid) },
+ { "PATH", INDEX(path) },
{ "link-status", INDEX(link_status) },
#undef INDEX
};
static const struct prop_info crtc_info[] = {
#define INDEX(name) (offsetof(union wlr_drm_crtc_props, name) / sizeof(uint32_t))
- { "ACTIVE", INDEX(active) },
- { "GAMMA_LUT", INDEX(gamma_lut) },
+ { "ACTIVE", INDEX(active) },
+ { "GAMMA_LUT", INDEX(gamma_lut) },
{ "GAMMA_LUT_SIZE", INDEX(gamma_lut_size) },
- { "MODE_ID", INDEX(mode_id) },
- { "rotation", INDEX(rotation) },
- { "scaling mode", INDEX(scaling_mode) },
+ { "MODE_ID", INDEX(mode_id) },
+ { "rotation", INDEX(rotation) },
+ { "scaling mode", INDEX(scaling_mode) },
#undef INDEX
};
static const struct prop_info plane_info[] = {
#define INDEX(name) (offsetof(union wlr_drm_plane_props, name) / sizeof(uint32_t))
- { "CRTC_H", INDEX(crtc_h) },
+ { "CRTC_H", INDEX(crtc_h) },
{ "CRTC_ID", INDEX(crtc_id) },
- { "CRTC_W", INDEX(crtc_w) },
- { "CRTC_X", INDEX(crtc_x) },
- { "CRTC_Y", INDEX(crtc_y) },
- { "FB_ID", INDEX(fb_id) },
- { "SRC_H", INDEX(src_h) },
- { "SRC_W", INDEX(src_w) },
- { "SRC_X", INDEX(src_x) },
- { "SRC_Y", INDEX(src_y) },
- { "type", INDEX(type) },
+ { "CRTC_W", INDEX(crtc_w) },
+ { "CRTC_X", INDEX(crtc_x) },
+ { "CRTC_Y", INDEX(crtc_y) },
+ { "FB_ID", INDEX(fb_id) },
+ { "IN_FORMATS", INDEX(in_formats) },
+ { "SRC_H", INDEX(src_h) },
+ { "SRC_W", INDEX(src_w) },
+ { "SRC_X", INDEX(src_x) },
+ { "SRC_Y", INDEX(src_y) },
+ { "type", INDEX(type) },
#undef INDEX
};