summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-15 13:28:07 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-15 13:28:07 +0200
commit8e5f4360503003b740a90da0423a746d2af85745 (patch)
treec01d4fc4d501f9dea18c5c4dd1ea2d2a18e40ed7
parent9430b32f228071fca7f0c8f1bf98accd65e1979b (diff)
wfdport: Expose maximum 1 pipeline per port
KMS supports no overlays, so only one pipeline can be bound at a time with a port.
-rw-r--r--src/wfddevice.c9
-rw-r--r--src/wfddevice.h3
-rw-r--r--src/wfdport.c59
3 files changed, 51 insertions, 20 deletions
diff --git a/src/wfddevice.c b/src/wfddevice.c
index 1c32ddb..b802737 100644
--- a/src/wfddevice.c
+++ b/src/wfddevice.c
@@ -48,6 +48,8 @@ struct wfd_device {
int fd;
drmModeResPtr resources;
+ uint32_t choosen_crtcs;
+
struct {
WFDint port_id;
WFDboolean state;
@@ -188,6 +190,7 @@ wfd_create_device(WFDint device_id, const WFDint *attrib_list)
device->device_id = device_id;
device->error = WFD_ERROR_NONE;
+ device->choosen_crtcs = 0;
device->dev = udev_device_new_from_syspath(registry->udev, syspath);
@@ -235,6 +238,12 @@ wfd_device_get_resources(struct wfd_device *device)
return device->resources;
}
+uint32_t *
+wfd_device_get_choosen_crtcs(struct wfd_device *device)
+{
+ return &device->choosen_crtcs;
+}
+
int
wfd_device_get_fd(struct wfd_device *device)
{
diff --git a/src/wfddevice.h b/src/wfddevice.h
index 30e5a9c..9bf5a0c 100644
--- a/src/wfddevice.h
+++ b/src/wfddevice.h
@@ -53,6 +53,9 @@ wfd_device_get_udev_device(struct wfd_device *device);
void *
wfd_device_get_resources(struct wfd_device *device);
+uint32_t *
+wfd_device_get_choosen_crtcs(struct wfd_device *device);
+
int
wfd_device_get_fd(struct wfd_device *device);
diff --git a/src/wfdport.c b/src/wfdport.c
index 32774bd..efba6d2 100644
--- a/src/wfdport.c
+++ b/src/wfdport.c
@@ -45,6 +45,8 @@ struct wfd_port {
struct wfd_pipeline *pipeline;
int pipeline_updated;
+ uint32_t choosen_pipeline;
+
};
WFDint
@@ -84,6 +86,11 @@ void
wfd_port_destroy(struct wfd_device *device,
struct wfd_port *port)
{
+ if (port->choosen_pipeline) {
+ uint32_t *crtcs = wfd_device_get_choosen_crtcs(device);
+ *crtcs &= (1 << port->choosen_pipeline);
+ }
+
port_modes_destroy(device, port);
drmModeFreeConnector(port->connector);
free(port);
@@ -161,19 +168,29 @@ wfd_port_create(struct wfd_device *device,
return port;
}
-static int
-wfd_port_count_bindable_pipelines(struct wfd_device *device,
- struct wfd_port *port)
+static uint32_t
+wfd_port_choose_pipeline(struct wfd_device *device,
+ struct wfd_port *port)
{
drmModeResPtr resources = wfd_device_get_resources(device);
- int count = 0;
int i;
+ uint32_t *crtcs;
- for (i = 0; i < resources->count_crtcs; ++i)
- if (port->possible_crtcs & (1 << i))
- count++;
+ if (port->choosen_pipeline)
+ return port->choosen_pipeline;
- return count;
+ crtcs = wfd_device_get_choosen_crtcs(device);
+
+ for (i = 0; i < resources->count_crtcs; ++i) {
+ if (port->possible_crtcs & (1 << i) &&
+ !(*crtcs & (1 << resources->crtcs[i]))) {
+ *crtcs |= 1 << resources->crtcs[i];
+ port->choosen_pipeline = resources->crtcs[i];
+ break;
+ }
+ }
+
+ return port->choosen_pipeline;
}
WFDint
@@ -187,7 +204,7 @@ wfd_port_get_attribi(struct wfd_device *device,
case WFD_PORT_ATTACHED:
return port->connector->connection == DRM_MODE_CONNECTED;
case WFD_PORT_PIPELINE_ID_COUNT:
- return wfd_port_count_bindable_pipelines(device, port);
+ return wfd_port_choose_pipeline(device, port) != 0 ? 1 : 0;
default:
break;
}
@@ -196,18 +213,20 @@ wfd_port_get_attribi(struct wfd_device *device,
}
static void
-wfd_port_fill_bindable(struct wfd_device *device,
- struct wfd_port *port,
- int count,
- int *value)
+wfd_port_get_bindable_pipelines(struct wfd_device *device,
+ struct wfd_port *port,
+ int count,
+ int *value)
{
- drmModeResPtr resources = wfd_device_get_resources(device);
- int i, j;
+ uint32_t pipeline;
- for (i = 0, j = 0; i < resources->count_crtcs && j < count; ++i) {
- if (port->possible_crtcs & (1 << i))
- value[j++] = resources->crtcs[i];
- }
+ if (count != 1)
+ return;
+
+ pipeline = wfd_port_choose_pipeline(device, port);
+
+ if (pipeline != 0)
+ *value = pipeline;
}
void
@@ -219,7 +238,7 @@ wfd_port_get_attribiv(struct wfd_device *device,
{
switch (attribute) {
case WFD_PORT_BINDABLE_PIPELINE_IDS:
- wfd_port_fill_bindable(device, port, count, value);
+ wfd_port_get_bindable_pipelines(device, port, count, value);
break;
default:
break;