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