randr12: don't change virtualX/virtualY
[nouveau] / src / nv04_xv_ovl.c
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
37 extern Atom xvBrightness, xvColorKey, xvAutopaintColorKey, xvSetDefaults;
38
39 void
40 NV04PutOverlayImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int offset,
41                     int id, int dstPitch, BoxPtr dstBox, int x1, int y1,
42                     int x2, int y2, short width, short height,
43                     short src_w, short src_h, short drw_w, short drw_h,
44                     RegionPtr clipBoxes)
45 {                       
46         NVPtr         pNv    = NVPTR(pScrn);
47         NVPortPrivPtr pPriv  = GET_OVERLAY_PRIVATE(pNv);
48
49         /*This may not work with NV04 overlay according to rivatv source*/
50         if (!pNv->randr12_enable) {
51                 if (pScrn->currentMode->Flags & V_DBLSCAN) {
52                         dstBox->y1 <<= 1;
53                         dstBox->y2 <<= 1;
54                         drw_h <<= 1;
55                 }
56         } else {
57                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
58                 xf86CrtcPtr crtc = xf86_config->crtc[pPriv->overlayCRTC];
59                 if (crtc->mode.Flags & V_DBLSCAN) {
60                         dstBox->y1 <<= 1;
61                         dstBox->y2 <<= 1;
62                         drw_h <<= 1;
63                 }
64         }
65
66         /* paint the color key */
67         if(pPriv->autopaintColorKey && (pPriv->grabbedByV4L ||
68                 !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))) {
69                 /* we always paint V4L's color key */
70                 if (!pPriv->grabbedByV4L)
71                         REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
72                 {
73                 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
74                 } 
75         }         
76
77         nvWriteVIDEO(pNv, NV_PVIDEO_OE_STATE, 0);
78         nvWriteVIDEO(pNv, NV_PVIDEO_SU_STATE, 0);
79         nvWriteVIDEO(pNv, NV_PVIDEO_RM_STATE, 0);
80
81         nvWriteVIDEO(pNv, NV_PVIDEO_BUFF0_START_ADDRESS,
82                           src->offset + offset);
83         nvWriteVIDEO(pNv, NV_PVIDEO_BUFF0_START_ADDRESS + 4,
84                           src->offset + offset);
85         nvWriteVIDEO(pNv, NV_PVIDEO_BUFF0_PITCH_LENGTH, dstPitch);
86         nvWriteVIDEO(pNv, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4, dstPitch);
87         nvWriteVIDEO(pNv, NV_PVIDEO_BUFF0_OFFSET, 0);
88         nvWriteVIDEO(pNv, NV_PVIDEO_BUFF0_OFFSET + 4, 0);
89
90         nvWriteVIDEO(pNv, NV_PVIDEO_WINDOW_START, (dstBox->y1 << 16) | dstBox->x1);
91         nvWriteVIDEO(pNv, NV_PVIDEO_WINDOW_SIZE, ((dstBox->y2 - dstBox->y1) << 16) |
92                            (dstBox->x2 - dstBox->x1));
93         nvWriteVIDEO(pNv, NV_PVIDEO_STEP_SIZE, (uint32_t)(((src_h - 1) << 11) / (drw_h - 1)) << 16 | (uint32_t)(((src_w - 1) << 11) / (drw_w - 1)));
94
95         nvWriteVIDEO(pNv, NV_PVIDEO_RED_CSC_OFFSET, (0x69 - (pPriv->brightness * 62 / 512)));
96         nvWriteVIDEO(pNv, NV_PVIDEO_GREEN_CSC_OFFSET, (0x3e + (pPriv->brightness * 62 / 512)));
97         nvWriteVIDEO(pNv, NV_PVIDEO_BLUE_CSC_OFFSET, (0x89 - (pPriv->brightness * 62 / 512)));
98         nvWriteVIDEO(pNv, NV_PVIDEO_CSC_ADJUST, 0x0);
99
100         nvWriteVIDEO(pNv, NV_PVIDEO_CONTROL_Y, 0x001); /* (BLUR_ON, LINE_HALF) */
101         nvWriteVIDEO(pNv, NV_PVIDEO_CONTROL_X, 0x111); /* (WEIGHT_HEAVY, SHARPENING_ON, SMOOTHING_ON) */
102
103         nvWriteVIDEO(pNv, NV_PVIDEO_FIFO_BURST_LENGTH, 0x03);
104         nvWriteVIDEO(pNv, NV_PVIDEO_FIFO_THRES_SIZE, 0x38);
105
106         nvWriteVIDEO(pNv, NV_PVIDEO_KEY, pPriv->colorKey);
107
108         /*      0x1 Video on
109                 0x10 Use colorkey
110                 0x100 Format YUY2 */
111         nvWriteVIDEO(pNv, NV_PVIDEO_OVERLAY, 0x111);
112
113         nvWriteVIDEO(pNv, NV_PVIDEO_SU_STATE, (nvReadVIDEO(pNv, NV_PVIDEO_SU_STATE) ^ (1 << 16)));
114
115         pPriv->videoStatus = CLIENT_VIDEO_ON;
116 }
117
118 /**
119  * NV04SetOverlayPortAttribute
120  * sets the attribute "attribute" of port "data" to value "value"
121  * calls NVResetVideo(pScrn) to apply changes to hardware
122  *                      
123  * @param pScrenInfo
124  * @param attribute attribute to set
125  * @param value value to which attribute is to be set
126  * @param data port from which the attribute is to be set
127  * 
128  * @return Success, if setting is successful
129  * BadValue/BadMatch, if value/attribute are invalid
130  * @see NVResetVideo(ScrnInfoPtr pScrn)
131  */
132 int
133 NV04SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
134                           INT32 value, pointer data)
135 {
136         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
137
138         if (attribute == xvBrightness) {
139                 if ((value < -512) || (value > 512))
140                         return BadValue;
141                 pPriv->brightness = value;
142         } else
143         if (attribute == xvColorKey) {
144                 pPriv->colorKey = value;
145                 REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
146         } else
147         if (attribute == xvAutopaintColorKey) {
148                 if ((value < 0) || (value > 1))
149                         return BadValue;
150                 pPriv->autopaintColorKey = value;
151         } else
152         if (attribute == xvSetDefaults) {
153                 NVSetPortDefaults(pScrn, pPriv);
154         } else
155                 return BadMatch;
156
157         return Success;
158 }
159
160 /**
161  * NV04GetOverlayPortAttribute
162  * 
163  * @param pScrn unused
164  * @param attribute attribute to be read
165  * @param value value of attribute will be stored in this pointer
166  * @param data port from which attribute will be read
167  * @return Success, if queried attribute exists
168  */
169 int
170 NV04GetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
171                           INT32 *value, pointer data)
172 {
173         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
174
175         if (attribute == xvBrightness)
176                 *value = pPriv->brightness;
177         else if (attribute == xvColorKey)
178                 *value = pPriv->colorKey;
179         else if (attribute == xvAutopaintColorKey)
180                 *value = (pPriv->autopaintColorKey) ? 1 : 0;
181         else
182                 return BadMatch;
183
184         return Success;
185 }
186
187 /**
188  * NV04StopOverlay
189  * Tell the hardware to stop the overlay
190  */
191 void
192 NV04StopOverlay (ScrnInfoPtr pScrn)
193 {
194     NVPtr pNv = NVPTR(pScrn);
195
196     nvWriteVIDEO(pNv, NV_PVIDEO_OVERLAY, nvReadVIDEO(pNv, NV_PVIDEO_OVERLAY) &~ 0x1);
197     nvWriteVIDEO(pNv, NV_PVIDEO_OE_STATE, 0);
198     nvWriteVIDEO(pNv, NV_PVIDEO_SU_STATE, 0);
199     nvWriteVIDEO(pNv, NV_PVIDEO_RM_STATE, 0);
200 }
201