From 540e39248d3818fd41204072d55c1fdd3b49c546 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Mon, 18 Apr 2011 14:33:24 +0200 Subject: wfdport: Support WFD_PORT_GAMMA --- src/Makefile.am | 2 +- src/wfdapi.c | 39 +++++++++++++++++++++---- src/wfdport.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/wfdport.h | 9 ++++++ 4 files changed, 133 insertions(+), 6 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 6c89155..0a9e36f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,7 @@ noinst_HEADERS = \ wfdevent.h -libWFD_la_LIBADD = $(OWFDRM_LIBS) +libWFD_la_LIBADD = $(OWFDRM_LIBS) -lm libWFD_la_SOURCES = \ wfdapi.c \ wfhandle.c \ diff --git a/src/wfdapi.c b/src/wfdapi.c index 5479310..d565b15 100644 --- a/src/wfdapi.c +++ b/src/wfdapi.c @@ -589,11 +589,25 @@ wfdGetPortAttribi(WFDDevice device_handle, } WFD_API_CALL WFDfloat WFD_APIENTRY -wfdGetPortAttribf(WFDDevice device, - WFDPort port, +wfdGetPortAttribf(WFDDevice device_handle, + WFDPort port_handle, WFDPortConfigAttrib attrib) WFD_APIEXIT { - return 0.; + struct wfd_device *device; + struct wfd_port *port; + + device = wf_handle_get_object(device_handle, DEVICE_HANDLE); + if (device == NULL) + return 0; + wfd_device_set_error(device, WFD_ERROR_NONE); + + port = wf_handle_get_object(port_handle, PORT_HANDLE); + if (port == NULL) { + wfd_device_set_error(device, WFD_ERROR_BAD_HANDLE); + return 0; + } + + return wfd_port_get_attribf(device, port, attrib); } @@ -682,11 +696,26 @@ wfdSetPortAttribi(WFDDevice device_handle, WFD_API_CALL void WFD_APIENTRY -wfdSetPortAttribf(WFDDevice device, - WFDPort port, +wfdSetPortAttribf(WFDDevice device_handle, + WFDPort port_handle, WFDPortConfigAttrib attrib, WFDfloat value) WFD_APIEXIT { + struct wfd_device *device; + struct wfd_port *port; + + device = wf_handle_get_object(device_handle, DEVICE_HANDLE); + if (device == NULL) + return; + wfd_device_set_error(device, WFD_ERROR_NONE); + + port = wf_handle_get_object(port_handle, PORT_HANDLE); + if (port == NULL) { + wfd_device_set_error(device, WFD_ERROR_BAD_HANDLE); + return; + } + + wfd_port_set_attribf(device, port, attrib, value); } diff --git a/src/wfdport.c b/src/wfdport.c index c94a32c..d95dbcb 100644 --- a/src/wfdport.c +++ b/src/wfdport.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wfhandle.h" #include "wfdport.h" @@ -54,6 +55,9 @@ struct wfd_port { WFDint power_mode; uint32_t edid_enum_id; + + float gamma; + float gamma_range[2]; }; WFDint @@ -193,6 +197,9 @@ wfd_port_create(struct wfd_device *device, port->mode = NULL; port->mode_handle = WFD_INVALID_HANDLE; + port->gamma = 1.0; + port->gamma_range[0] = 0.1; + port->gamma_range[1] = 10.0; return port; } @@ -304,6 +311,22 @@ wfd_port_get_attribi(struct wfd_device *device, return 0; } +WFDfloat +wfd_port_get_attribf(struct wfd_device *device, + struct wfd_port *port, + WFDPortConfigAttrib attribute) +{ + switch (attribute) { + case WFD_PORT_GAMMA: + return port->gamma; + default: + wfd_device_set_error(device, WFD_ERROR_BAD_ATTRIBUTE); + break; + } + + return 0.0; +} + static void wfd_port_get_bindable_pipelines(struct wfd_device *device, struct wfd_port *port, @@ -382,6 +405,11 @@ wfd_port_get_attribfv(struct wfd_device *device, return; value[0] = value[1] = value[2] = 0.0; break; + case WFD_PORT_GAMMA_RANGE: + if (count != 2) + return; + value[0] = port->gamma_range[0]; + value[1] = port->gamma_range[1]; default: wfd_device_set_error(device, WFD_ERROR_BAD_ATTRIBUTE); break; @@ -430,6 +458,28 @@ wfd_port_set_attribi(struct wfd_device *device, } } +void +wfd_port_set_attribf(struct wfd_device *device, + struct wfd_port *port, + WFDPortConfigAttrib attribute, + WFDfloat value) +{ + switch (attribute) { + case WFD_PORT_GAMMA: + if (value < port->gamma_range[0] || + value > port->gamma_range[1]) { + wfd_device_set_error(device, + WFD_ERROR_ILLEGAL_ARGUMENT); + return; + } + + port->gamma = value; + default: + wfd_device_set_error(device, WFD_ERROR_BAD_ATTRIBUTE); + break; + } +} + void wfd_port_set_attribiv(struct wfd_device *device, struct wfd_port *port, @@ -632,6 +682,43 @@ wfd_port_get_display_data(struct wfd_device *device, return num; } +static inline double +dmin(double a, double b) +{ + return a < b ? a : b; +} + +static void +wfd_port_commit_gamma(struct wfd_device *device, + struct wfd_port *port) +{ + int fd = wfd_device_get_fd(device); + uint16_t *gamma; + uint16_t *red, *green, *blue; + int i, size = 256; + + gamma = malloc(3 * size * sizeof *gamma); + if (gamma == NULL) + return; + + for (i = 0; i < size; ++i) { + if (port->gamma == 1.0) { + gamma[i] = (i << 8) + i; + continue; + } + + gamma[i] = dmin(pow((double)i/(double)(size-1), port->gamma), + 1.0) * 65535.0; + } + + red = green = blue = gamma; + + drmModeCrtcSetGamma(fd, port->connector->connector_id, + size, red, green, blue); + free(gamma); +} + + int wfd_port_commit(struct wfd_device *device, struct wfd_port *port) @@ -688,6 +775,8 @@ wfd_port_commit(struct wfd_device *device, return ret; } + wfd_port_commit_gamma(device, port); + return ret; } diff --git a/src/wfdport.h b/src/wfdport.h index eaaedc9..28a24b1 100644 --- a/src/wfdport.h +++ b/src/wfdport.h @@ -48,6 +48,10 @@ WFDint wfd_port_get_attribi(struct wfd_device *device, struct wfd_port *port, WFDPortConfigAttrib attribute); +WFDfloat +wfd_port_get_attribf(struct wfd_device *device, + struct wfd_port *port, + WFDPortConfigAttrib attribute); void wfd_port_get_attribiv(struct wfd_device *device, struct wfd_port *port, @@ -67,6 +71,11 @@ wfd_port_set_attribi(struct wfd_device *device, WFDPortConfigAttrib attribute, WFDint value); void +wfd_port_set_attribf(struct wfd_device *device, + struct wfd_port *port, + WFDPortConfigAttrib attribute, + WFDfloat value); +void wfd_port_set_attribiv(struct wfd_device *device, struct wfd_port *port, WFDPortConfigAttrib attribute, -- cgit v1.2.3