summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-03-31 10:41:51 +1000
committerDave Airlie <airlied@redhat.com>2015-05-19 09:34:54 +1000
commitcf721e457162d01df56f58a58fb914d267c564c1 (patch)
tree9a0c57502be7abe68f7e29e9206971ad4f52daf9
parentbaa5e7def7dcdbf4bb86d873bec3e4ef35bbfb06 (diff)
backend: add output tile info retrieval.
this just adds backend support for retrieving the tile information from X11 (randr 1.5) and native backends. It stores the tiling information into the output struct.
-rw-r--r--src/backends/meta-monitor-manager-private.h14
-rw-r--r--src/backends/native/meta-monitor-manager-kms.c47
-rw-r--r--src/backends/x11/meta-monitor-manager-xrandr.c37
3 files changed, 98 insertions, 0 deletions
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index 460c789e..efbca28a 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -56,6 +56,7 @@ typedef struct _MetaMonitorMode MetaMonitorMode;
typedef struct _MetaMonitorInfo MetaMonitorInfo;
typedef struct _MetaCRTCInfo MetaCRTCInfo;
typedef struct _MetaOutputInfo MetaOutputInfo;
+typedef struct _MetaTileInfo MetaTileInfo;
typedef enum {
META_MONITOR_TRANSFORM_NORMAL,
@@ -89,6 +90,17 @@ typedef enum {
META_CONNECTOR_TYPE_DSI = 16,
} MetaConnectorType;
+struct _MetaTileInfo {
+ guint32 group_id;
+ guint32 flags;
+ guint32 max_h_tiles;
+ guint32 max_v_tiles;
+ guint32 loc_h_tile;
+ guint32 loc_v_tile;
+ guint32 tile_w;
+ guint32 tile_h;
+};
+
struct _MetaOutput
{
/* The CRTC driving this output, NULL if the output is not enabled */
@@ -141,6 +153,8 @@ struct _MetaOutput
gboolean hotplug_mode_update;
gint suggested_x;
gint suggested_y;
+
+ MetaTileInfo tile_info;
};
struct _MetaCRTC
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index f0d93809..6702a23a 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -55,6 +55,7 @@ typedef struct {
uint32_t dpms_prop_id;
uint32_t edid_blob_id;
+ uint32_t tile_blob_id;
} MetaOutputKms;
typedef struct {
@@ -208,6 +209,9 @@ find_connector_properties (MetaMonitorManagerKms *manager_kms,
output_kms->dpms_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_BLOB) && strcmp (prop->name, "EDID") == 0)
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
+ else if ((prop->flags & DRM_MODE_PROP_BLOB) &&
+ strcmp (prop->name, "TILE") == 0)
+ output_kms->tile_blob_id = output_kms->connector->prop_values[i];
drmModeFreeProperty (prop);
}
@@ -273,6 +277,47 @@ read_output_edid (MetaMonitorManagerKms *manager_kms,
}
}
+static gboolean
+output_get_tile_info (MetaMonitorManagerKms *manager_kms,
+ MetaOutput *output)
+{
+ MetaOutputKms *output_kms = output->driver_private;
+ drmModePropertyBlobPtr tile_blob = NULL;
+ int ret;
+
+ if (output_kms->tile_blob_id == 0)
+ return FALSE;
+
+ tile_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->tile_blob_id);
+ if (!tile_blob)
+ {
+ meta_warning ("Failed to read TILE of output %s: %s\n", output->name, strerror(errno));
+ return FALSE;
+ }
+
+ if (tile_blob->length > 0)
+ {
+ ret = sscanf ((char *)tile_blob->data, "%d:%d:%d:%d:%d:%d:%d:%d",
+ &output->tile_info.group_id,
+ &output->tile_info.flags,
+ &output->tile_info.max_h_tiles,
+ &output->tile_info.max_v_tiles,
+ &output->tile_info.loc_h_tile,
+ &output->tile_info.loc_v_tile,
+ &output->tile_info.tile_w,
+ &output->tile_info.tile_h);
+
+ if (ret != 8)
+ return FALSE;
+ return TRUE;
+ }
+ else
+ {
+ drmModeFreePropertyBlob (tile_blob);
+ return FALSE;
+ }
+}
+
static MetaMonitorMode *
find_meta_mode (MetaMonitorManager *manager,
const drmModeModeInfo *drm_mode)
@@ -622,6 +667,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->scale = get_output_scale (manager, meta_output);
+ output_get_tile_info (manager_kms, meta_output);
+
/* FIXME: backlight is a very driver specific thing unfortunately,
every DDX does its own thing, and the dumb KMS API does not include it.
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 39ee0798..1aa6bdf4 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -409,6 +409,42 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
return NULL;
}
+static void
+output_get_tile_info (MetaMonitorManagerXrandr *manager_xrandr,
+ MetaOutput *output)
+{
+ Atom tile_atom;
+ unsigned char *prop;
+ unsigned long nitems, bytes_after;
+ int actual_format;
+ Atom actual_type;
+
+ if (manager_xrandr->has_randr15 == FALSE)
+ return;
+
+ tile_atom = XInternAtom (manager_xrandr->xdisplay, "TILE", FALSE);
+ XRRGetOutputProperty (manager_xrandr->xdisplay,
+ output->winsys_id,
+ tile_atom, 0, 100, False,
+ False, AnyPropertyType,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, &prop);
+
+ if (actual_type == XA_INTEGER && actual_format == 32 && nitems == 8)
+ {
+ long *values = (long *)prop;
+ output->tile_info.group_id = values[0];
+ output->tile_info.flags = values[1];
+ output->tile_info.max_h_tiles = values[2];
+ output->tile_info.max_v_tiles = values[3];
+ output->tile_info.loc_h_tile = values[4];
+ output->tile_info.loc_v_tile = values[5];
+ output->tile_info.tile_w = values[6];
+ output->tile_info.tile_h = values[7];
+ }
+ XFree (prop);
+}
+
static gboolean
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
@@ -737,6 +773,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
+ output_get_tile_info (manager_xrandr, meta_output);
meta_output->n_modes = output->nmode;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
for (j = 0; j < meta_output->n_modes; j++)