diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-04-15 13:28:07 +0200 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-04-15 13:28:07 +0200 |
commit | 8e5f4360503003b740a90da0423a746d2af85745 (patch) | |
tree | c01d4fc4d501f9dea18c5c4dd1ea2d2a18e40ed7 | |
parent | 9430b32f228071fca7f0c8f1bf98accd65e1979b (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.c | 9 | ||||
-rw-r--r-- | src/wfddevice.h | 3 | ||||
-rw-r--r-- | src/wfdport.c | 59 |
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; |