summaryrefslogtreecommitdiff
path: root/vmwgfx/vmwgfx_tex_video.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2011-12-07 20:19:34 +0100
committerThomas Hellstrom <thellstrom@vmware.com>2011-12-08 09:56:30 +0100
commit121dba0093d24eb0aefa3d27a22f05f85ac66f72 (patch)
treebe883ec2c403a130c0b73d359e03c4134465817f /vmwgfx/vmwgfx_tex_video.c
parent8bdc6004d34e274d815bb3f3e0aa223085ea848c (diff)
vmwgfx: Hook up XV color conversion control attributes
This enables the standard XV color conversion control attributes contrast, scaling, saturation and hue. Currently the attribute change takes effect on the next image only. If we ever implement a ReputImage callback, we can use it to update the image immediately on attribute change. The attribute ranges follow those used by the proprietary Nvidia driver. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
Diffstat (limited to 'vmwgfx/vmwgfx_tex_video.c')
-rw-r--r--vmwgfx/vmwgfx_tex_video.c97
1 files changed, 74 insertions, 23 deletions
diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index b2c5472..2cc44bd 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -35,7 +35,7 @@
#include <fourcc.h>
#include <xa_tracker.h>
#include <xa_context.h>
-
+#include <math.h>
/*XXX get these from pipe's texture limits */
#define IMAGE_MAX_WIDTH 2048
@@ -67,12 +67,14 @@ static const float bt_709[] = {
1.5748f, -0.468124f, 0.f, 0.f
};
-static Atom xvBrightness, xvContrast;
+static Atom xvBrightness, xvContrast, xvSaturation, xvHue;
-#define NUM_TEXTURED_ATTRIBUTES 2
+#define NUM_TEXTURED_ATTRIBUTES 4
static XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = {
- {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
+ {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}
};
#define NUM_FORMATS 3
@@ -105,6 +107,8 @@ struct xorg_xv_port_priv {
int brightness;
int contrast;
+ int saturation;
+ int hue;
int current_set;
struct vmwgfx_dmabuf *bounce[2][3];
@@ -119,6 +123,8 @@ struct xorg_xv_port_priv {
float y_scale;
float rgb_offset;
float rgb_scale;
+ float sinhue;
+ float coshue;
float cm[16];
};
@@ -128,20 +134,32 @@ struct xorg_xv_port_priv {
*
* Applies yuv- and resulting rgb scales and offsets to compute the correct
* color conversion matrix. These scales and offsets are properties of the
- * video stream (and might in the future be adjusted using XV properties as well).
+ * video stream and can be adjusted using XV properties as well.
*/
static void
vmwgfx_update_conversion_matrix(struct xorg_xv_port_priv *priv)
{
int i;
float *cm = priv->cm;
+ static const float *bt;
+
+ bt = (priv->hdtv) ? bt_709 : bt_601;
- memcpy(cm, ((priv->hdtv) ? bt_709 : bt_601), sizeof(bt_601));
+ memcpy(cm, bt, sizeof(bt_601));
/*
- * Adjust for yuv scales in input and rgb scale in the converted output.
+ * Apply hue rotation
*/
+ cm[4] = priv->coshue * bt[4] - priv->sinhue * bt[8];
+ cm[8] = priv->sinhue * bt[4] + priv->coshue * bt[8];
+ cm[5] = priv->coshue * bt[5] - priv->sinhue * bt[9];
+ cm[9] = priv->sinhue * bt[5] + priv->coshue * bt[9];
+ cm[6] = priv->coshue * bt[6] - priv->sinhue * bt[10];
+ cm[10] = priv->sinhue * bt[6] + priv->coshue * bt[10];
+ /*
+ * Adjust for yuv scales in input and rgb scale in the converted output.
+ */
for(i = 0; i < 3; ++i) {
cm[i] *= (priv->y_scale*priv->rgb_scale);
cm[i+4] *= (priv->uv_scale*priv->rgb_scale);
@@ -201,16 +219,41 @@ set_port_attribute(ScrnInfoPtr pScrn,
struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
if (attribute == xvBrightness) {
- if ((value < -128) || (value > 127))
- return BadValue;
- priv->brightness = value;
+ if ((value < -1000) || (value > 1000))
+ return BadValue;
+
+ priv->brightness = value;
+ priv->y_offset = -((float) value)/1000.f;
+
} else if (attribute == xvContrast) {
- if ((value < 0) || (value > 255))
- return BadValue;
- priv->contrast = value;
+ if ((value < -1000) || (value > 1000))
+ return BadValue;
+
+ priv->contrast = value;
+ priv->rgb_scale = ((float) value + 1000.f)/1000.f;
+
+ } else if (attribute == xvSaturation) {
+ if ((value < -1000) || (value > 1000))
+ return BadValue;
+
+ priv->saturation = value;
+ priv->uv_scale = ((float) value + 1000.f)/1000.f;
+
+ } else if (attribute == xvHue) {
+ double hue_angle;
+
+ if ((value < -1000) || (value > 1000))
+ return BadValue;
+
+ priv->hue = value;
+ hue_angle = (double) value * M_PI / 1000.;
+ priv->sinhue = sin(hue_angle);
+ priv->coshue = cos(hue_angle);
+
} else
return BadMatch;
+ vmwgfx_update_conversion_matrix(priv);
return Success;
}
@@ -218,16 +261,20 @@ static int
get_port_attribute(ScrnInfoPtr pScrn,
Atom attribute, INT32 * value, pointer data)
{
- struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
-
- if (attribute == xvBrightness)
- *value = priv->brightness;
- else if (attribute == xvContrast)
- *value = priv->contrast;
- else
- return BadMatch;
+ struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
+
+ if (attribute == xvBrightness)
+ *value = priv->brightness;
+ else if (attribute == xvContrast)
+ *value = priv->contrast;
+ else if (attribute == xvSaturation)
+ *value = priv->saturation;
+ else if (attribute == xvHue)
+ *value = priv->hue;
+ else
+ return BadMatch;
- return Success;
+ return Success;
}
static void
@@ -628,6 +675,8 @@ port_priv_create(struct xa_tracker *xat, struct xa_context *r,
priv->y_scale = 1.f;
priv->rgb_offset = 0.f;
priv->rgb_scale = 1.f;
+ priv->sinhue = 0.f;
+ priv->coshue = 1.f;
vmwgfx_update_conversion_matrix(priv);
@@ -739,6 +788,8 @@ xorg_xv_init(ScreenPtr pScreen)
*/
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
xvContrast = MAKE_ATOM("XV_CONTRAST");
+ xvSaturation = MAKE_ATOM("XV_SATURATION");
+ xvHue = MAKE_ATOM("XV_HUE");
if (ms->xat) {
textured_adapter = xorg_setup_textured_adapter(pScreen);