2 * Copyright 2007 Arthur Huillet
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
28 #include <X11/extensions/Xv.h>
31 #include "dixstruct.h"
34 #include "nv_include.h"
37 extern Atom xvBrightness, xvContrast, xvColorKey, xvSaturation,
38 xvHue, xvAutopaintColorKey, xvSetDefaults, xvDoubleBuffer,
39 xvITURBT709, xvSyncToVBlank, xvOnCRTCNb;
43 * program hardware to overlay image into front buffer
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
58 * @param drw_w width of the image to draw to screen
60 * @param clipBoxes ???
63 NV10PutOverlayImage(ScrnInfoPtr pScrn, int offset, int uvoffset, int id,
64 int dstPitch, BoxPtr dstBox,
65 int x1, int y1, int x2, int y2,
66 short width, short height,
67 short src_w, short src_h,
68 short drw_w, short drw_h,
71 NVPtr pNv = NVPTR(pScrn);
72 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
73 int buffer = pPriv->currentBuffer;
75 /* paint the color key */
76 if(pPriv->autopaintColorKey && (pPriv->grabbedByV4L ||
77 !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))) {
78 /* we always paint V4L's color key */
79 if (!pPriv->grabbedByV4L)
80 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
82 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
86 if(pNv->CurrentLayout.mode->Flags & V_DBLSCAN) {
92 //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 >>
93 //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 nvWriteVIDEO(pNv, NV_PVIDEO_BASE(buffer) , 0);
96 nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(buffer) , offset);
97 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_IN(buffer) , (height << 16) | width);
98 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_IN(buffer) ,
99 ((y1 << 4) & 0xffff0000) | (x1 >> 12));
100 nvWriteVIDEO(pNv, NV_PVIDEO_DS_DX(buffer) , (src_w << 20) / drw_w);
101 nvWriteVIDEO(pNv, NV_PVIDEO_DT_DY(buffer) , (src_h << 20) / drw_h);
102 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_OUT(buffer),
103 (dstBox->y1 << 16) | dstBox->x1);
104 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_OUT(buffer) ,
105 ((dstBox->y2 - dstBox->y1) << 16) |
106 (dstBox->x2 - dstBox->x1));
108 dstPitch |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; /* use color key */
109 if(id != FOURCC_UYVY)
110 dstPitch |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8;
111 if(pPriv->iturbt_709)
112 dstPitch |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
114 if( id == FOURCC_YV12 || id == FOURCC_I420 )
115 dstPitch |= NV_PVIDEO_FORMAT_PLANAR;
117 /* Those are important only for planar formats (NV12) */
120 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_BASE(buffer), 0);
121 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_OFFSET_BUFF(buffer), uvoffset);
124 nvWriteVIDEO(pNv, NV_PVIDEO_FORMAT(buffer), dstPitch);
125 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 0);
126 nvWriteVIDEO(pNv, NV_PVIDEO_BUFFER, buffer ? 0x10 : 0x1);
128 pPriv->videoStatus = CLIENT_VIDEO_ON;
132 * NV10SetOverlayPortAttribute
133 * sets the attribute "attribute" of port "data" to value "value"
134 * calls NVResetVideo(pScrn) to apply changes to hardware
137 * @param attribute attribute to set
138 * @param value value to which attribute is to be set
139 * @param data port from which the attribute is to be set
141 * @return Success, if setting is successful
142 * BadValue/BadMatch, if value/attribute are invalid
143 * @see NVResetVideo(ScrnInfoPtr pScrn)
146 NV10SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
147 INT32 value, pointer data)
149 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
150 NVPtr pNv = NVPTR(pScrn);
152 if (attribute == xvBrightness) {
153 if ((value < -512) || (value > 512))
155 pPriv->brightness = value;
157 if (attribute == xvDoubleBuffer) {
158 if ((value < 0) || (value > 1))
160 pPriv->doubleBuffer = value;
162 if (attribute == xvContrast) {
163 if ((value < 0) || (value > 8191))
165 pPriv->contrast = value;
167 if (attribute == xvHue) {
173 if (attribute == xvSaturation) {
174 if ((value < 0) || (value > 8191))
176 pPriv->saturation = value;
178 if (attribute == xvColorKey) {
179 pPriv->colorKey = value;
180 REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
182 if (attribute == xvAutopaintColorKey) {
183 if ((value < 0) || (value > 1))
185 pPriv->autopaintColorKey = value;
187 if (attribute == xvITURBT709) {
188 if ((value < 0) || (value > 1))
190 pPriv->iturbt_709 = value;
192 if (attribute == xvSetDefaults) {
193 NVSetPortDefaults(pScrn, pPriv);
195 if ( attribute == xvOnCRTCNb) {
196 if ((value < 0) || (value > 1))
198 pPriv->overlayCRTC = value;
199 NVWriteCRTC(pNv, value, NV_CRTC_FSEL, NVReadCRTC(pNv, value, NV_CRTC_FSEL) | NV_CRTC_FSEL_OVERLAY);
200 NVWriteCRTC(pNv, !value, NV_CRTC_FSEL, NVReadCRTC(pNv, !value, NV_CRTC_FSEL) & ~NV_CRTC_FSEL_OVERLAY);
204 NV10WriteOverlayParameters(pScrn);
210 * NV10GetOverlayPortAttribute
212 * @param pScrn unused
213 * @param attribute attribute to be read
214 * @param value value of attribute will be stored in this pointer
215 * @param data port from which attribute will be read
216 * @return Success, if queried attribute exists
219 NV10GetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
220 INT32 *value, pointer data)
222 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
224 if (attribute == xvBrightness)
225 *value = pPriv->brightness;
226 else if (attribute == xvDoubleBuffer)
227 *value = (pPriv->doubleBuffer) ? 1 : 0;
228 else if (attribute == xvContrast)
229 *value = pPriv->contrast;
230 else if (attribute == xvSaturation)
231 *value = pPriv->saturation;
232 else if (attribute == xvHue)
234 else if (attribute == xvColorKey)
235 *value = pPriv->colorKey;
236 else if (attribute == xvAutopaintColorKey)
237 *value = (pPriv->autopaintColorKey) ? 1 : 0;
238 else if (attribute == xvITURBT709)
239 *value = (pPriv->iturbt_709) ? 1 : 0;
240 else if (attribute == xvOnCRTCNb)
241 *value = (pPriv->overlayCRTC) ? 1 : 0;
250 * Tell the hardware to stop the overlay
253 NV10StopOverlay (ScrnInfoPtr pScrn)
255 NVPtr pNv = NVPTR(pScrn);
256 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
260 * NV10WriteOverlayParameters
261 * Tell the hardware about parameters that are too expensive to be set
265 NV10WriteOverlayParameters (ScrnInfoPtr pScrn)
267 NVPtr pNv = NVPTR(pScrn);
268 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
269 int satSine, satCosine;
272 angle = (double)pPriv->hue * 3.1415927 / 180.0;
274 satSine = pPriv->saturation * sin(angle);
277 satCosine = pPriv->saturation * cos(angle);
278 if (satCosine < -1024)
281 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(0), (pPriv->brightness << 16) |
283 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(1), (pPriv->brightness << 16) |
285 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(0), (satSine << 16) |
286 (satCosine & 0xffff));
287 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(1), (satSine << 16) |
288 (satCosine & 0xffff));
289 nvWriteVIDEO(pNv, NV_PVIDEO_COLOR_KEY, pPriv->colorKey);