Merge branch 'display_tiling_clean_new' into 'master'

Draft: Display Tiling for DRM backend

See merge request wlroots/wlroots!3344
This commit is contained in:
Christian Kröner 2022-10-13 20:09:09 +00:00
commit 5e9f77f4ff
11 changed files with 333 additions and 8 deletions

View file

@ -170,7 +170,7 @@ static void plane_disable(struct atomic *atom, struct wlr_drm_plane *plane) {
atomic_add(atom, id, props->crtc_id, 0);
}
static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm,
static void set_plane_props(struct atomic *atom, struct wlr_box source_box,
struct wlr_drm_plane *plane, uint32_t crtc_id, int32_t x, int32_t y) {
uint32_t id = plane->id;
const union wlr_drm_plane_props *props = &plane->props;
@ -180,12 +180,14 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm,
goto error;
}
uint32_t width = fb->wlr_buf->width;
uint32_t height = fb->wlr_buf->height;
uint32_t width = source_box.width ? (uint32_t)source_box.width :
(uint32_t)fb->wlr_buf->width;
uint32_t height = source_box.height ? (uint32_t)source_box.height :
(uint32_t)fb->wlr_buf->height;
// The src_* properties are in 16.16 fixed point
atomic_add(atom, id, props->src_x, 0);
atomic_add(atom, id, props->src_y, 0);
atomic_add(atom, id, props->src_x, (uint64_t)source_box.x << 16);
atomic_add(atom, id, props->src_y, (uint64_t)source_box.y << 16);
atomic_add(atom, id, props->src_w, (uint64_t)width << 16);
atomic_add(atom, id, props->src_h, (uint64_t)height << 16);
atomic_add(atom, id, props->crtc_w, width);
@ -292,20 +294,36 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
atomic_add(&atom, crtc->id, crtc->props.mode_id, mode_id);
atomic_add(&atom, crtc->id, crtc->props.active, active);
if (active) {
struct wlr_box source_box;
if (state->base->committed & WLR_OUTPUT_STATE_SOURCE_BOX) {
/**
* Grab source box from output in order to crop the
* buffer.
*/
source_box = state->base->source_box;
}
else {
// Use dummy source box
source_box.x = source_box.y = source_box.width =
source_box.height = 0;
}
if (crtc->props.gamma_lut != 0) {
atomic_add(&atom, crtc->id, crtc->props.gamma_lut, gamma_lut);
}
if (crtc->props.vrr_enabled != 0) {
atomic_add(&atom, crtc->id, crtc->props.vrr_enabled, vrr_enabled);
}
set_plane_props(&atom, drm, crtc->primary, crtc->id, 0, 0);
set_plane_props(&atom, source_box, crtc->primary, crtc->id, 0, 0);
if (crtc->primary->props.fb_damage_clips != 0) {
atomic_add(&atom, crtc->primary->id,
crtc->primary->props.fb_damage_clips, fb_damage_clips);
}
if (crtc->cursor) {
if (drm_connector_is_cursor_visible(conn)) {
set_plane_props(&atom, drm, crtc->cursor, crtc->id,
// Ensure source_box is unset for cursor plane
source_box.x = source_box.y = source_box.width =
source_box.height = 0;
set_plane_props(&atom, source_box, crtc->cursor, crtc->id,
conn->cursor_x, conn->cursor_y);
} else {
plane_disable(&atom, crtc->cursor);

View file

@ -1272,6 +1272,12 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
parse_edid(wlr_conn, edid_len, edid);
free(edid);
size_t tile_len = 0;
uint8_t *tile = get_drm_prop_blob(drm->fd,
wlr_conn->id, wlr_conn->props.tile, &tile_len);
parse_tile(wlr_conn, tile_len, tile);
free(tile);
char *subconnector = NULL;
if (wlr_conn->props.subconnector) {
subconnector = get_drm_prop_enum(drm->fd,

View file

@ -25,6 +25,7 @@ static const struct prop_info connector_info[] = {
{ "DPMS", INDEX(dpms) },
{ "EDID", INDEX(edid) },
{ "PATH", INDEX(path) },
{ "TILE", INDEX(tile) },
{ "content type", INDEX(content_type) },
{ "link-status", INDEX(link_status) },
{ "max bpc", INDEX(max_bpc) },

View file

@ -134,6 +134,70 @@ void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data)
}
}
void parse_tile(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) {
struct wlr_output *output = &conn->output;
if (len > 0) {
int ret;
ret = sscanf((char*)data, "%d:%d:%d:%d:%d:%d:%d:%d",
&output->tile_info.group_id,
&output->tile_info.tile_is_single_monitor,
&output->tile_info.num_h_tile,
&output->tile_info.num_v_tile,
&output->tile_info.tile_h_loc,
&output->tile_info.tile_v_loc,
&output->tile_info.tile_h_size,
&output->tile_info.tile_v_size);
if(ret != 8)
wlr_log(WLR_ERROR, "Unable to understand tile information for "
"output %s", output->name);
else
wlr_log(WLR_INFO, "Output %s TILE information: "
"group ID %d, single monitor %d, total %d horizontal tiles, "
"total %d vertical tiles, horizontal tile %d, vertical tile "
"%d, width %d, height %d",
output->name,
output->tile_info.group_id,
output->tile_info.tile_is_single_monitor,
output->tile_info.num_h_tile,
output->tile_info.num_v_tile,
output->tile_info.tile_h_loc,
output->tile_info.tile_v_loc,
output->tile_info.tile_h_size,
output->tile_info.tile_v_size);
}
else
wlr_log(WLR_DEBUG, "No tile information available for output %s",
output->name);
}
const char *conn_get_name(uint32_t type_id) {
switch (type_id) {
case DRM_MODE_CONNECTOR_Unknown: return "Unknown";
case DRM_MODE_CONNECTOR_VGA: return "VGA";
case DRM_MODE_CONNECTOR_DVII: return "DVI-I";
case DRM_MODE_CONNECTOR_DVID: return "DVI-D";
case DRM_MODE_CONNECTOR_DVIA: return "DVI-A";
case DRM_MODE_CONNECTOR_Composite: return "Composite";
case DRM_MODE_CONNECTOR_SVIDEO: return "SVIDEO";
case DRM_MODE_CONNECTOR_LVDS: return "LVDS";
case DRM_MODE_CONNECTOR_Component: return "Component";
case DRM_MODE_CONNECTOR_9PinDIN: return "DIN";
case DRM_MODE_CONNECTOR_DisplayPort: return "DP";
case DRM_MODE_CONNECTOR_HDMIA: return "HDMI-A";
case DRM_MODE_CONNECTOR_HDMIB: return "HDMI-B";
case DRM_MODE_CONNECTOR_TV: return "TV";
case DRM_MODE_CONNECTOR_eDP: return "eDP";
case DRM_MODE_CONNECTOR_VIRTUAL: return "Virtual";
case DRM_MODE_CONNECTOR_DSI: return "DSI";
case DRM_MODE_CONNECTOR_DPI: return "DPI";
case DRM_MODE_CONNECTOR_WRITEBACK: return "Writeback";
#ifdef DRM_MODE_CONNECTOR_SPI
case DRM_MODE_CONNECTOR_SPI: return "SPI";
#endif
#ifdef DRM_MODE_CONNECTOR_USB
case DRM_MODE_CONNECTOR_USB: return "USB";
#endif
default: return "Unknown";
output->model = strdup(model_str);
if (serial_str[0] != '\0') {
output->serial = strdup(serial_str);