st/xorg: implement basics of xv
[mesa.git] / src / gallium / state_trackers / xorg / xorg_xv.c
1 #include "xorg_tracker.h"
2
3 #include <xf86xv.h>
4 #include <X11/extensions/Xv.h>
5 #include <fourcc.h>
6
7 /*XXX get these from pipe's texture limits */
8 #define IMAGE_MAX_WIDTH 2048
9 #define IMAGE_MAX_HEIGHT 2048
10
11 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
12
13 static Atom xvBrightness, xvContrast;
14
15 #define NUM_TEXTURED_ATTRIBUTES 2
16 static XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = {
17 {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
18 {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
19 };
20
21 #define NUM_FORMATS 3
22 static XF86VideoFormatRec Formats[NUM_FORMATS] = {
23 {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
24 };
25
26 static XF86VideoEncodingRec DummyEncoding[1] = {
27 {
28 0,
29 "XV_IMAGE",
30 IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
31 {1, 1}
32 }
33 };
34
35 #define NUM_IMAGES 2
36 static XF86ImageRec Images[NUM_IMAGES] = {
37 XVIMAGE_UYVY,
38 XVIMAGE_YUY2,
39 };
40
41 struct xorg_xv_port_priv {
42 RegionRec clip;
43
44 int brightness;
45 int contrast;
46 };
47
48
49 static void
50 stop_video(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
51 {
52 struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
53
54 REGION_EMPTY(pScrn->pScreen, &priv->clip);
55 }
56
57 static int
58 set_port_attribute(ScrnInfoPtr pScrn,
59 Atom attribute, INT32 value, pointer data)
60 {
61 struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
62
63 if (attribute == xvBrightness) {
64 if ((value < -128) || (value > 127))
65 return BadValue;
66 priv->brightness = value;
67 } else if (attribute == xvContrast) {
68 if ((value < 0) || (value > 255))
69 return BadValue;
70 priv->contrast = value;
71 } else
72 return BadMatch;
73
74 return Success;
75 }
76
77 static int
78 get_port_attribute(ScrnInfoPtr pScrn,
79 Atom attribute, INT32 * value, pointer data)
80 {
81 struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
82
83 if (attribute == xvBrightness)
84 *value = priv->brightness;
85 else if (attribute == xvContrast)
86 *value = priv->contrast;
87 else
88 return BadMatch;
89
90 return Success;
91 }
92
93 static void
94 query_best_size(ScrnInfoPtr pScrn,
95 Bool motion,
96 short vid_w, short vid_h,
97 short drw_w, short drw_h,
98 unsigned int *p_w, unsigned int *p_h, pointer data)
99 {
100 if (vid_w > (drw_w << 1))
101 drw_w = vid_w >> 1;
102 if (vid_h > (drw_h << 1))
103 drw_h = vid_h >> 1;
104
105 *p_w = drw_w;
106 *p_h = drw_h;
107 }
108
109 static int
110 put_image(ScrnInfoPtr pScrn,
111 short src_x, short src_y,
112 short drw_x, short drw_y,
113 short src_w, short src_h,
114 short drw_w, short drw_h,
115 int id, unsigned char *buf,
116 short width, short height,
117 Bool sync, RegionPtr clipBoxes, pointer data,
118 DrawablePtr pDraw)
119 {
120 return 0;
121 }
122
123 static int
124 query_image_attributes(ScrnInfoPtr pScrn,
125 int id,
126 unsigned short *w, unsigned short *h,
127 int *pitches, int *offsets)
128 {
129 int size;
130
131 if (*w > IMAGE_MAX_WIDTH)
132 *w = IMAGE_MAX_WIDTH;
133 if (*h > IMAGE_MAX_HEIGHT)
134 *h = IMAGE_MAX_HEIGHT;
135
136 *w = (*w + 1) & ~1;
137 if (offsets)
138 offsets[0] = 0;
139
140 switch (id) {
141 case FOURCC_UYVY:
142 case FOURCC_YUY2:
143 default:
144 size = *w << 1;
145 if (pitches)
146 pitches[0] = size;
147 size *= *h;
148 break;
149 }
150
151 return size;
152 }
153
154 static struct xorg_xv_port_priv *
155 port_priv_create(ScreenPtr pScreen)
156 {
157 /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];*/
158 /*modesettingPtr ms = modesettingPTR(pScrn);*/
159 struct xorg_xv_port_priv *priv = NULL;
160
161 priv = calloc(1, sizeof(struct xorg_xv_port_priv));
162
163 if (!priv)
164 return NULL;
165
166 REGION_NULL(pScreen, &priv->clip);
167
168 return priv;
169 }
170
171 static XF86VideoAdaptorPtr
172 xorg_setup_textured_adapter(ScreenPtr pScreen)
173 {
174 /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];*/
175 /*modesettingPtr ms = modesettingPTR(pScrn);*/
176 XF86VideoAdaptorPtr adapt;
177 XF86AttributePtr attrs;
178 DevUnion *dev_unions;
179 int nports = 16, i;
180 int nattributes;
181
182 nattributes = NUM_TEXTURED_ATTRIBUTES;
183
184 adapt = calloc(1, sizeof(XF86VideoAdaptorRec));
185 dev_unions = calloc(nports, sizeof(DevUnion));
186 attrs = calloc(nattributes, sizeof(XF86AttributeRec));
187 if (adapt == NULL || dev_unions == NULL || attrs == NULL) {
188 free(adapt);
189 free(dev_unions);
190 free(attrs);
191 return NULL;
192 }
193
194 adapt->type = XvWindowMask | XvInputMask | XvImageMask;
195 adapt->flags = 0;
196 adapt->name = "Gallium3D Textured Video";
197 adapt->nEncodings = 1;
198 adapt->pEncodings = DummyEncoding;
199 adapt->nFormats = NUM_FORMATS;
200 adapt->pFormats = Formats;
201 adapt->nPorts = 0;
202 adapt->pPortPrivates = dev_unions;
203 adapt->nAttributes = nattributes;
204 adapt->pAttributes = attrs;
205 memcpy(attrs, TexturedAttributes, nattributes * sizeof(XF86AttributeRec));
206 adapt->nImages = NUM_IMAGES;
207 adapt->pImages = Images;
208 adapt->PutVideo = NULL;
209 adapt->PutStill = NULL;
210 adapt->GetVideo = NULL;
211 adapt->GetStill = NULL;
212 adapt->StopVideo = stop_video;
213 adapt->SetPortAttribute = set_port_attribute;
214 adapt->GetPortAttribute = get_port_attribute;
215 adapt->QueryBestSize = query_best_size;
216 adapt->PutImage = put_image;
217 adapt->QueryImageAttributes = query_image_attributes;
218
219 for (i = 0; i < nports; i++) {
220 struct xorg_xv_port_priv *priv =
221 port_priv_create(pScreen);
222
223 adapt->pPortPrivates[i].ptr = (pointer) (priv);
224 adapt->nPorts++;
225 }
226
227 return adapt;
228 }
229
230 void
231 xorg_init_video(ScreenPtr pScreen)
232 {
233 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
234 /*modesettingPtr ms = modesettingPTR(pScrn);*/
235 XF86VideoAdaptorPtr *adaptors, *new_adaptors = NULL;
236 XF86VideoAdaptorPtr textured_adapter;
237 int num_adaptors;
238
239 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
240 new_adaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
241 if (new_adaptors == NULL)
242 return;
243
244 memcpy(new_adaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
245 adaptors = new_adaptors;
246
247 /* Add the adaptors supported by our hardware. First, set up the atoms
248 * that will be used by both output adaptors.
249 */
250 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
251 xvContrast = MAKE_ATOM("XV_CONTRAST");
252
253 textured_adapter = xorg_setup_textured_adapter(pScreen);
254
255 debug_assert(textured_adapter);
256
257 if (textured_adapter) {
258 adaptors[num_adaptors++] = textured_adapter;
259 }
260
261 if (num_adaptors) {
262 xf86XVScreenInit(pScreen, adaptors, num_adaptors);
263 } else {
264 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
265 "Disabling Xv because no adaptors could be initialized.\n");
266 }
267
268 free(adaptors);
269 }