nv10_xv_ovl.c revision fda9279d
1/* 2 * Copyright 2007 Arthur Huillet 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include "xf86xv.h" 28#include <X11/extensions/Xv.h> 29#include "exa.h" 30#include "damage.h" 31#include "dixstruct.h" 32#include "fourcc.h" 33 34#include "nv_include.h" 35#include "nv_dma.h" 36 37extern Atom xvBrightness, xvContrast, xvColorKey, xvSaturation; 38extern Atom xvHue, xvAutopaintColorKey, xvSetDefaults, xvDoubleBuffer; 39extern Atom xvITURBT709, xvSyncToVBlank, xvOnCRTCNb; 40 41/** 42 * NV10PutOverlayImage 43 * program hardware to overlay image into front buffer 44 * 45 * @param pScrn screen 46 * @param offset card offset to the pixel data 47 * @param id format of image 48 * @param dstPitch pitch of the pixel data in VRAM 49 * @param dstBox destination box 50 * @param x1 first source point - x 51 * @param y1 first source point - y 52 * @param x2 second source point - x 53 * @param y2 second source point - y 54 * @param width width of the source image = x2 - x1 55 * @param height height 56 * @param src_w width of the image data in VRAM 57 * @param src_h height 58 * @param drw_w width of the image to draw to screen 59 * @param drw_h height 60 * @param clipBoxes ??? 61 */ 62void 63NV10PutOverlayImage(ScrnInfoPtr pScrn, 64 struct nouveau_bo *src, int offset, int uvoffset, int id, 65 int dstPitch, BoxPtr dstBox, int x1, int y1, int x2, int y2, 66 short width, short height, short src_w, short src_h, 67 short drw_w, short drw_h, RegionPtr clipBoxes) 68{ 69 NVPtr pNv = NVPTR(pScrn); 70 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 71#ifdef NVOVL_SUPPORT 72 int buffer = pPriv->currentBuffer; 73 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 74 xf86CrtcPtr crtc = xf86_config->crtc[pPriv->overlayCRTC]; 75 76 if (crtc->mode.Flags & V_DBLSCAN) { 77 dstBox->y1 <<= 1; 78 dstBox->y2 <<= 1; 79 drw_h <<= 1; 80 } 81 82 /* paint the color key */ 83 if(pPriv->autopaintColorKey && (pPriv->grabbedByV4L || 84 !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))) { 85 /* we always paint V4L's color key */ 86 if (!pPriv->grabbedByV4L) 87 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 88 { 89 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 90 } 91 } 92 93 //xf86DrvMsg(0, X_INFO, "SIZE_IN h %d w %d, POINT_IN x %d y %d, DS_DX %d DT_DY %d, POINT_OUT x %d y %d SIZE_OUT h %d w %d\n", height, width, x1 >> 94 //16,y1>>16, (src_w << 20) / drw_w, (src_h << 20) / drw_h, (dstBox->x1),(dstBox->y1), (dstBox->y2 - dstBox->y1), (dstBox->x2 - dstBox->x1)); 95 96 nvWriteVIDEO(pNv, NV_PVIDEO_BASE(buffer) , 0); 97 nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(buffer), 98 src->offset + offset); 99 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_IN(buffer) , (height << 16) | width); 100 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_IN(buffer) , 101 ((y1 << 4) & 0xffff0000) | (x1 >> 12)); 102 nvWriteVIDEO(pNv, NV_PVIDEO_DS_DX(buffer) , (src_w << 20) / drw_w); 103 nvWriteVIDEO(pNv, NV_PVIDEO_DT_DY(buffer) , (src_h << 20) / drw_h); 104 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_OUT(buffer), 105 (dstBox->y1 << 16) | dstBox->x1); 106 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_OUT(buffer) , 107 ((dstBox->y2 - dstBox->y1) << 16) | 108 (dstBox->x2 - dstBox->x1)); 109 110 dstPitch |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; /* use color key */ 111 if(id != FOURCC_UYVY) 112 dstPitch |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8; 113 if(pPriv->iturbt_709) 114 dstPitch |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709; 115 116 if( id == FOURCC_YV12 || id == FOURCC_I420 ) 117 dstPitch |= NV_PVIDEO_FORMAT_PLANAR; 118 119 /* Those are important only for planar formats (NV12) */ 120 if (uvoffset) { 121 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_BASE(buffer), 0); 122 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_OFFSET_BUFF(buffer), 123 src->offset + uvoffset); 124 } 125 126 nvWriteVIDEO(pNv, NV_PVIDEO_FORMAT(buffer), dstPitch); 127 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 0); 128 nvWriteVIDEO(pNv, NV_PVIDEO_BUFFER, buffer ? 0x10 : 0x1); 129#endif 130 131 pPriv->videoStatus = CLIENT_VIDEO_ON; 132} 133 134/** 135 * NV10SetOverlayPortAttribute 136 * sets the attribute "attribute" of port "data" to value "value" 137 * calls NVResetVideo(pScrn) to apply changes to hardware 138 * 139 * @param pScrenInfo 140 * @param attribute attribute to set 141 * @param value value to which attribute is to be set 142 * @param data port from which the attribute is to be set 143 * 144 * @return Success, if setting is successful 145 * BadValue/BadMatch, if value/attribute are invalid 146 * @see NVResetVideo(ScrnInfoPtr pScrn) 147 */ 148int 149NV10SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute, 150 INT32 value, pointer data) 151{ 152 NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 153 154 if (attribute == xvBrightness) { 155 if ((value < -512) || (value > 512)) 156 return BadValue; 157 pPriv->brightness = value; 158 } else 159 if (attribute == xvDoubleBuffer) { 160 if ((value < 0) || (value > 1)) 161 return BadValue; 162 pPriv->doubleBuffer = value; 163 } else 164 if (attribute == xvContrast) { 165 if ((value < 0) || (value > 8191)) 166 return BadValue; 167 pPriv->contrast = value; 168 } else 169 if (attribute == xvHue) { 170 value %= 360; 171 if (value < 0) 172 value += 360; 173 pPriv->hue = value; 174 } else 175 if (attribute == xvSaturation) { 176 if ((value < 0) || (value > 8191)) 177 return BadValue; 178 pPriv->saturation = value; 179 } else 180 if (attribute == xvColorKey) { 181 pPriv->colorKey = value; 182 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 183 } else 184 if (attribute == xvAutopaintColorKey) { 185 if ((value < 0) || (value > 1)) 186 return BadValue; 187 pPriv->autopaintColorKey = value; 188 } else 189 if (attribute == xvITURBT709) { 190 if ((value < 0) || (value > 1)) 191 return BadValue; 192 pPriv->iturbt_709 = value; 193 } else 194 if (attribute == xvSetDefaults) { 195 NVSetPortDefaults(pScrn, pPriv); 196 } else 197#ifdef NVOVL_SUPPORT 198 if ( attribute == xvOnCRTCNb) { 199 NVPtr pNv = NVPTR(pScrn); 200 201 if ((value < 0) || (value > 1)) 202 return BadValue; 203 pPriv->overlayCRTC = value; 204 NVWriteCRTC(pNv, value, NV_PCRTC_ENGINE_CTRL, 205 NVReadCRTC(pNv, value, NV_PCRTC_ENGINE_CTRL) | NV_CRTC_FSEL_OVERLAY); 206 NVWriteCRTC(pNv, !value, NV_PCRTC_ENGINE_CTRL, 207 NVReadCRTC(pNv, !value, NV_PCRTC_ENGINE_CTRL) & ~NV_CRTC_FSEL_OVERLAY); 208 } else 209#endif 210 return BadMatch; 211 212 NV10WriteOverlayParameters(pScrn); 213 214 return Success; 215} 216 217/** 218 * NV10GetOverlayPortAttribute 219 * 220 * @param pScrn unused 221 * @param attribute attribute to be read 222 * @param value value of attribute will be stored in this pointer 223 * @param data port from which attribute will be read 224 * @return Success, if queried attribute exists 225 */ 226int 227NV10GetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute, 228 INT32 *value, pointer data) 229{ 230 NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 231 232 if (attribute == xvBrightness) 233 *value = pPriv->brightness; 234 else if (attribute == xvDoubleBuffer) 235 *value = (pPriv->doubleBuffer) ? 1 : 0; 236 else if (attribute == xvContrast) 237 *value = pPriv->contrast; 238 else if (attribute == xvSaturation) 239 *value = pPriv->saturation; 240 else if (attribute == xvHue) 241 *value = pPriv->hue; 242 else if (attribute == xvColorKey) 243 *value = pPriv->colorKey; 244 else if (attribute == xvAutopaintColorKey) 245 *value = (pPriv->autopaintColorKey) ? 1 : 0; 246 else if (attribute == xvITURBT709) 247 *value = (pPriv->iturbt_709) ? 1 : 0; 248 else if (attribute == xvOnCRTCNb) 249 *value = (pPriv->overlayCRTC) ? 1 : 0; 250 else 251 return BadMatch; 252 253 return Success; 254} 255 256/** 257 * NV10StopOverlay 258 * Tell the hardware to stop the overlay 259 */ 260void 261NV10StopOverlay (ScrnInfoPtr pScrn) 262{ 263#ifdef NVOVL_SUPPORT 264 NVPtr pNv = NVPTR(pScrn); 265 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1); 266#endif 267} 268 269/** 270 * NV10WriteOverlayParameters 271 * Tell the hardware about parameters that are too expensive to be set 272 * on every frame 273 */ 274void 275NV10WriteOverlayParameters (ScrnInfoPtr pScrn) 276{ 277 NVPtr pNv = NVPTR(pScrn); 278 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 279 int satSine, satCosine; 280 double angle; 281 282 angle = (double)pPriv->hue * 3.1415927 / 180.0; 283 284 satSine = pPriv->saturation * sin(angle); 285 if (satSine < -1024) 286 satSine = -1024; 287 satCosine = pPriv->saturation * cos(angle); 288 if (satCosine < -1024) 289 satCosine = -1024; 290 291#ifdef NVOVL_SUPPORT 292 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(0), (pPriv->brightness << 16) | 293 pPriv->contrast); 294 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(1), (pPriv->brightness << 16) | 295 pPriv->contrast); 296 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(0), (satSine << 16) | 297 (satCosine & 0xffff)); 298 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(1), (satSine << 16) | 299 (satCosine & 0xffff)); 300 nvWriteVIDEO(pNv, NV_PVIDEO_COLOR_KEY, pPriv->colorKey); 301#endif 302} 303 304