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