[Intel-gfx] [PATCH] TV: add property control for TV attributes

Zhenyu Wang zhenyu.z.wang at intel.com
Mon Feb 23 16:43:48 CET 2009


This is based on Jesse's origin patch for bug #12763.
But export integer range to user instead of hardware float
point format, and fix different real format on 965G and 945G
for contrast and saturation.
---
 src/i830_tv.c |  211 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 201 insertions(+), 10 deletions(-)

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 9b24055..804e182 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -59,6 +59,10 @@ struct i830_tv_priv {
     Bool force_type;
     char *tv_format;
     int margin[4];
+    uint8_t brightness;
+    uint8_t contrast;
+    uint8_t saturation;
+    uint8_t hue;
     uint32_t save_TV_H_CTL_1;
     uint32_t save_TV_H_CTL_2;
     uint32_t save_TV_H_CTL_3;
@@ -1020,6 +1024,96 @@ i830_float_to_luma (float f)
     return ret;
 }
 
+static uint8_t
+float_to_float_2_6(float fin)
+{
+    uint8_t exp;
+    uint8_t mant;
+    float f = fin;
+    uint32_t tmp;
+
+    if (f < 0) f = -f;
+
+    tmp = f;
+    for (exp = 0; exp <= 3 && tmp > 0; exp++)
+	tmp /= 2;
+
+    mant = (f * (1 << 6) + 0.5);
+    mant >>= exp;
+    if (mant > (1 << 6))
+	mant = (1 << 6) - 1;
+
+    return (exp << 6) | mant;
+}
+
+static uint8_t
+float_to_fix_2_6(float f)
+{
+    uint8_t ret;
+
+    ret = f * (1 << 6);
+    return ret;
+}
+
+static void
+i830_tv_update_brightness(I830Ptr pI830, uint8_t brightness)
+{
+    /* brightness in 2's comp value */
+    uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_BRIGHTNESS_MASK;
+    int8_t bri = brightness - 128; /* remove bias */
+
+    val |= (bri << TV_BRIGHTNESS_SHIFT) & TV_BRIGHTNESS_MASK;
+    OUTREG(TV_CLR_KNOBS, val);
+}
+
+static void
+i830_tv_update_contrast(I830Ptr pI830, uint8_t contrast)
+{
+    uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_CONTRAST_MASK;;
+    float con;
+    uint8_t c;
+
+    if (IS_I965G(pI830)) {
+	/* 2.6 fixed point */
+	con = 3.0 * ((float) contrast / 255);
+	c = float_to_fix_2_6(con);
+    } else {
+	/* 2.6 floating point */
+	con = 8.875 * ((float) contrast / 255);
+	c = float_to_float_2_6(con);
+    }
+    val |= (c << TV_CONTRAST_SHIFT) & TV_CONTRAST_MASK;
+    OUTREG(TV_CLR_KNOBS, val);
+}
+
+static void
+i830_tv_update_saturation(I830Ptr pI830, uint8_t saturation)
+{
+    uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_SATURATION_MASK;
+    float sat;
+    uint8_t s;
+
+    /* same as contrast */
+    if (IS_I965G(pI830)) {
+	sat = 3.0 * ((float) saturation / 255);
+	s = float_to_fix_2_6(sat);
+    } else {
+	sat = 8.875 * ((float) saturation / 255);
+	s = float_to_float_2_6(sat);
+    }
+    val |= (s << TV_SATURATION_SHIFT) & TV_SATURATION_MASK;
+    OUTREG(TV_CLR_KNOBS, val);
+}
+
+static void
+i830_tv_update_hue(I830Ptr pI830, uint8_t hue)
+{
+    uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_HUE_MASK;
+
+    val |= (hue << TV_HUE_SHIFT) & TV_HUE_MASK;
+    OUTREG(TV_CLR_KNOBS, val);
+}
+
 static void
 i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 		DisplayModePtr adjusted_mode)
@@ -1181,14 +1275,6 @@ i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 	    (i830_float_to_csc(color_conversion->bv) << 16) |
 	    (i830_float_to_luma(color_conversion->av)));
 
-    if (IS_I965G(pI830)) {
-	/* 2.6 fixed point value for contrast and saturation modifier,
-	   use 1 as default */
-	OUTREG(TV_CLR_KNOBS, 0x00404000);
-    } else {
-	/* 915/945 uses 2 bits exponent and 6 bits mantissa format */
-	OUTREG(TV_CLR_KNOBS, 0x00606000);
-    }
     OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
 		(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
     {
@@ -1492,6 +1578,26 @@ static char *margin_names[4] = {
     "LEFT", "TOP", "RIGHT", "BOTTOM"
 };
 
+/**
+ *  contrast and saturation has different format on 915/945 with 965.
+ *  On 915/945, it's 2.6 floating point number.
+ *  On 965, it's 2.6 fixed point number.
+ */
+#define TV_BRIGHTNESS_NAME "TV_BRIGHTNESS"
+#define TV_BRIGHTNESS_DEFAULT 128	/* bias */
+static Atom brightness_atom;
+#define TV_CONTRAST_NAME "TV_CONTRAST"
+#define TV_CONTRAST_DEFAULT 0x40
+#define TV_CONTRAST_DEFAULT_945G 0x60
+static Atom contrast_atom;
+#define TV_SATURATION_NAME "TV_SATURATION"
+#define TV_SATURATION_DEFAULT 0x40
+#define TV_SATURATION_DEFAULT_945G 0x60
+static Atom saturation_atom;
+#define TV_HUE_NAME "TV_HUE"
+#define TV_HUE_DEFAULT 0
+static Atom hue_atom;
+
 static Bool
 i830_tv_format_set_property (xf86OutputPtr output)
 {
@@ -1537,6 +1643,62 @@ i830_tv_format_configure_property (xf86OutputPtr output)
 				     num_atoms, (INT32 *) current_atoms);
 }
 
+static void
+i830_tv_color_set_property(xf86OutputPtr output, Atom property,
+			   uint8_t val)
+{
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+
+    if (property == brightness_atom) {
+	dev_priv->brightness = val;
+	i830_tv_update_brightness(pI830, val);
+    } else if (property == contrast_atom) {
+	dev_priv->contrast = val;
+	i830_tv_update_contrast(pI830, val);
+    } else if (property == saturation_atom) {
+	dev_priv->saturation = val;
+	i830_tv_update_saturation(pI830, val);
+    } else if (property == hue_atom) {
+	dev_priv->hue = val;
+	i830_tv_update_hue(pI830, val);
+    }
+}
+
+static void
+i830_tv_color_create_property(xf86OutputPtr output, Atom *property,
+			      char *name, int name_len, uint8_t val)
+{
+    ScrnInfoPtr	pScrn = output->scrn;
+    INT32 range[2];
+    int err = 0;
+
+    *property = MakeAtom(name, name_len - 1, TRUE);
+    range[0] = 0;
+    range[1] = 255;
+    err = RRConfigureOutputProperty(output->randr_output, *property,
+				    FALSE, TRUE, FALSE, 2, range);
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "RRConfigureOutputProperty error, %d\n", err);
+	goto out;
+    }
+    /* Set the current value */
+    i830_tv_color_set_property(output, *property, val);
+
+    err = RRChangeOutputProperty(output->randr_output, *property,
+				 XA_INTEGER, 32, PropModeReplace, 1, &val,
+				 FALSE, FALSE);
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "RRChangeOutputProperty error, %d\n", err);
+    }
+out:
+    return;
+}
+
 #endif /* RANDR_12_INTERFACE */
 
 static void
@@ -1544,10 +1706,10 @@ i830_tv_create_resources(xf86OutputPtr output)
 {
 #ifdef RANDR_12_INTERFACE
     ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-    int			    err;
-    int			    i;
+    int			    err, i;
 
     /* Set up the tv_format property, which takes effect on mode set
      * and accepts strings that match exactly
@@ -1595,6 +1757,23 @@ i830_tv_create_resources(xf86OutputPtr output)
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRChangeOutputProperty error, %d\n", err);
     }
+
+    i830_tv_color_create_property(output, &brightness_atom,
+				  TV_BRIGHTNESS_NAME,
+				  sizeof(TV_BRIGHTNESS_NAME),
+				  TV_BRIGHTNESS_DEFAULT);
+    i830_tv_color_create_property(output, &contrast_atom,
+				  TV_CONTRAST_NAME,
+				  sizeof(TV_CONTRAST_NAME),
+				  IS_I965G(pI830) ? TV_CONTRAST_DEFAULT :
+						TV_CONTRAST_DEFAULT_945G);
+    i830_tv_color_create_property(output, &saturation_atom,
+				  TV_SATURATION_NAME,
+				  sizeof(TV_SATURATION_NAME),
+				  IS_I965G(pI830) ? TV_SATURATION_DEFAULT :
+						TV_SATURATION_DEFAULT_945G);
+    i830_tv_color_create_property(output, &hue_atom, TV_HUE_NAME,
+				  sizeof(TV_HUE_NAME), TV_HUE_DEFAULT);
 #endif /* RANDR_12_INTERFACE */
 }
 
@@ -1699,6 +1878,18 @@ i830_tv_set_property(xf86OutputPtr output, Atom property,
 	    return TRUE;
 	}
     }
+    if (property == brightness_atom || property == contrast_atom ||
+	property == saturation_atom || property == hue_atom) {
+	uint8_t val;
+
+	/* Make sure value is sane */
+	if (value->type != XA_INTEGER || value->format != 32 ||
+	    value->size != 1)
+	    return FALSE;
+
+	memcpy (&val, value->data, 1);
+	i830_tv_color_set_property(output, property, val);
+    }
 
     return TRUE;
 }
-- 
1.5.6.5




More information about the Intel-gfx mailing list