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 extern Atom xvHue, xvAutopaintColorKey, xvSetDefaults, xvDoubleBuffer;
39 extern Atom 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,
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)
69 NVPtr pNv = NVPTR(pScrn);
70 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
71 int buffer = pPriv->currentBuffer;
73 if (!pNv->randr12_enable) {
74 if (pScrn->currentMode->Flags & V_DBLSCAN) {
80 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
81 xf86CrtcPtr crtc = xf86_config->crtc[pPriv->overlayCRTC];
82 if (crtc->mode.Flags & V_DBLSCAN) {
89 /* paint the color key */
90 if(pPriv->autopaintColorKey && (pPriv->grabbedByV4L ||
91 !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))) {
92 /* we always paint V4L's color key */
93 if (!pPriv->grabbedByV4L)
94 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
96 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
100 //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 >>
101 //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));
103 nvWriteVIDEO(pNv, NV_PVIDEO_BASE(buffer) , 0);
104 nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(buffer),
105 src->offset + offset);
106 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_IN(buffer) , (height << 16) | width);
107 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_IN(buffer) ,
108 ((y1 << 4) & 0xffff0000) | (x1 >> 12));
109 nvWriteVIDEO(pNv, NV_PVIDEO_DS_DX(buffer) , (src_w << 20) / drw_w);
110 nvWriteVIDEO(pNv, NV_PVIDEO_DT_DY(buffer) , (src_h << 20) / drw_h);
111 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_OUT(buffer),
112 (dstBox->y1 << 16) | dstBox->x1);
113 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_OUT(buffer) ,
114 ((dstBox->y2 - dstBox->y1) << 16) |
115 (dstBox->x2 - dstBox->x1));
117 dstPitch |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; /* use color key */
118 if(id != FOURCC_UYVY)
119 dstPitch |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8;
120 if(pPriv->iturbt_709)
121 dstPitch |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
123 if( id == FOURCC_YV12 || id == FOURCC_I420 )
124 dstPitch |= NV_PVIDEO_FORMAT_PLANAR;
126 /* Those are important only for planar formats (NV12) */
128 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_BASE(buffer), 0);
129 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_OFFSET_BUFF(buffer),
130 src->offset + uvoffset);
133 nvWriteVIDEO(pNv, NV_PVIDEO_FORMAT(buffer), dstPitch);
134 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 0);
135 nvWriteVIDEO(pNv, NV_PVIDEO_BUFFER, buffer ? 0x10 : 0x1);
137 pPriv->videoStatus = CLIENT_VIDEO_ON;
141 * NV10SetOverlayPortAttribute
142 * sets the attribute "attribute" of port "data" to value "value"
143 * calls NVResetVideo(pScrn) to apply changes to hardware
146 * @param attribute attribute to set
147 * @param value value to which attribute is to be set
148 * @param data port from which the attribute is to be set
150 * @return Success, if setting is successful
151 * BadValue/BadMatch, if value/attribute are invalid
152 * @see NVResetVideo(ScrnInfoPtr pScrn)
155 NV10SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
156 INT32 value, pointer data)
158 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
159 NVPtr pNv = NVPTR(pScrn);
161 if (attribute == xvBrightness) {
162 if ((value < -512) || (value > 512))
164 pPriv->brightness = value;
166 if (attribute == xvDoubleBuffer) {
167 if ((value < 0) || (value > 1))
169 pPriv->doubleBuffer = value;
171 if (attribute == xvContrast) {
172 if ((value < 0) || (value > 8191))
174 pPriv->contrast = value;
176 if (attribute == xvHue) {
182 if (attribute == xvSaturation) {
183 if ((value < 0) || (value > 8191))
185 pPriv->saturation = value;
187 if (attribute == xvColorKey) {
188 pPriv->colorKey = value;
189 REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
191 if (attribute == xvAutopaintColorKey) {
192 if ((value < 0) || (value > 1))
194 pPriv->autopaintColorKey = value;
196 if (attribute == xvITURBT709) {
197 if ((value < 0) || (value > 1))
199 pPriv->iturbt_709 = value;
201 if (attribute == xvSetDefaults) {
202 NVSetPortDefaults(pScrn, pPriv);
204 if ( attribute == xvOnCRTCNb) {
205 if ((value < 0) || (value > 1))
207 pPriv->overlayCRTC = value;
208 NVWriteCRTC(pNv, value, NV_CRTC_FSEL, NVReadCRTC(pNv, value, NV_CRTC_FSEL) | NV_CRTC_FSEL_OVERLAY);
209 NVWriteCRTC(pNv, !value, NV_CRTC_FSEL, NVReadCRTC(pNv, !value, NV_CRTC_FSEL) & ~NV_CRTC_FSEL_OVERLAY);
213 NV10WriteOverlayParameters(pScrn);
219 * NV10GetOverlayPortAttribute
221 * @param pScrn unused
222 * @param attribute attribute to be read
223 * @param value value of attribute will be stored in this pointer
224 * @param data port from which attribute will be read
225 * @return Success, if queried attribute exists
228 NV10GetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
229 INT32 *value, pointer data)
231 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
233 if (attribute == xvBrightness)
234 *value = pPriv->brightness;
235 else if (attribute == xvDoubleBuffer)
236 *value = (pPriv->doubleBuffer) ? 1 : 0;
237 else if (attribute == xvContrast)
238 *value = pPriv->contrast;
239 else if (attribute == xvSaturation)
240 *value = pPriv->saturation;
241 else if (attribute == xvHue)
243 else if (attribute == xvColorKey)
244 *value = pPriv->colorKey;
245 else if (attribute == xvAutopaintColorKey)
246 *value = (pPriv->autopaintColorKey) ? 1 : 0;
247 else if (attribute == xvITURBT709)
248 *value = (pPriv->iturbt_709) ? 1 : 0;
249 else if (attribute == xvOnCRTCNb)
250 *value = (pPriv->overlayCRTC) ? 1 : 0;
259 * Tell the hardware to stop the overlay
262 NV10StopOverlay (ScrnInfoPtr pScrn)
264 NVPtr pNv = NVPTR(pScrn);
265 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
269 * NV10WriteOverlayParameters
270 * Tell the hardware about parameters that are too expensive to be set
274 NV10WriteOverlayParameters (ScrnInfoPtr pScrn)
276 NVPtr pNv = NVPTR(pScrn);
277 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
278 int satSine, satCosine;
281 angle = (double)pPriv->hue * 3.1415927 / 180.0;
283 satSine = pPriv->saturation * sin(angle);
286 satCosine = pPriv->saturation * cos(angle);
287 if (satCosine < -1024)
290 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(0), (pPriv->brightness << 16) |
292 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(1), (pPriv->brightness << 16) |
294 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(0), (satSine << 16) |
295 (satCosine & 0xffff));
296 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(1), (satSine << 16) |
297 (satCosine & 0xffff));
298 nvWriteVIDEO(pNv, NV_PVIDEO_COLOR_KEY, pPriv->colorKey);