~ubuntu-branches/ubuntu/oneiric/xserver-xorg-video-intel/oneiric

« back to all changes in this revision

Viewing changes to src/sna/sna_video_overlay.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers, Robert Hooker, Christopher James Halse Rogers
  • Date: 2011-08-09 10:10:02 UTC
  • mfrom: (0.1.21 experimental)
  • Revision ID: james.westby@ubuntu.com-20110809101002-pguc3kc6pzh1cp5h
Tags: 2:2.15.901-1ubuntu1
[ Robert Hooker ]
* Merge from debian-experimental, remaining changes:
  - 101_copy-fb.patch
    + Plymouth integration patch
  - 120_check_privates.patch
    + Check for null privates pointer on render_dest_picture.
  - debian/xserver-xorg-video-intel.preinst.in:
  - debian/xserver-xorg-video-intel.postinst.in:
    + Remove obsolete /etc/modprobe.d/i915-kms.conf file on upgrades.
      KMS is the kernel default.
* Dropped patches:
  - 121_fdo-28798-fix.patch (upstream)

[ Christopher James Halse Rogers ]
* Refresh 101_copy-fb.patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 
 
3
 Copyright 2000-2011 Intel Corporation.  All Rights Reserved.
 
4
 
 
5
 Permission is hereby granted, free of charge, to any person obtaining a
 
6
 copy of this software and associated documentation files (the
 
7
 "Software"), to deal in the Software without restriction, including
 
8
 without limitation the rights to use, copy, modify, merge, publish,
 
9
 distribute, sub license, and/or sell copies of the Software, and to
 
10
 permit persons to whom the Software is furnished to do so, subject to
 
11
 the following conditions:
 
12
 
 
13
 The above copyright notice and this permission notice (including the
 
14
 next paragraph) shall be included in all copies or substantial portions
 
15
 of the Software.
 
16
 
 
17
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
18
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
19
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 
20
 IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 
21
 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
22
 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 
23
 THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
24
 
 
25
 **************************************************************************/
 
26
 
 
27
#ifdef HAVE_CONFIG_H
 
28
#include "config.h"
 
29
#endif
 
30
 
 
31
#include "sna.h"
 
32
#include "sna_video.h"
 
33
 
 
34
#include <xf86xv.h>
 
35
#include <X11/extensions/Xv.h>
 
36
#include <fourcc.h>
 
37
#include <i915_drm.h>
 
38
 
 
39
#if DEBUG_VIDEO_OVERLAY
 
40
#undef DBG
 
41
#define DBG(x) ErrorF x
 
42
#endif
 
43
 
 
44
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
45
 
 
46
#define HAS_GAMMA(sna) ((sna)->kgem.gen >= 30)
 
47
 
 
48
static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe;
 
49
static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
 
50
static Atom xvSyncToVblank;
 
51
 
 
52
/* Limits for the overlay/textured video source sizes.  The documented hardware
 
53
 * limits are 2048x2048 or better for overlay and both of our textured video
 
54
 * implementations.  Additionally, on the 830 and 845, larger sizes resulted in
 
55
 * the card hanging, so we keep the limits lower there.
 
56
 */
 
57
#define IMAGE_MAX_WIDTH         2048
 
58
#define IMAGE_MAX_HEIGHT        2048
 
59
#define IMAGE_MAX_WIDTH_LEGACY  1024
 
60
#define IMAGE_MAX_HEIGHT_LEGACY 1088
 
61
 
 
62
/* client libraries expect an encoding */
 
63
static const XF86VideoEncodingRec DummyEncoding[1] = {
 
64
        {
 
65
         0,
 
66
         "XV_IMAGE",
 
67
         IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
 
68
         {1, 1}
 
69
         }
 
70
};
 
71
 
 
72
#define NUM_FORMATS 3
 
73
 
 
74
static XF86VideoFormatRec Formats[NUM_FORMATS] = {
 
75
        {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 
76
};
 
77
 
 
78
#define NUM_ATTRIBUTES 5
 
79
static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
 
80
        {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
 
81
        {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
 
82
        {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
 
83
        {XvSettable | XvGettable, 0, 1023, "XV_SATURATION"},
 
84
        {XvSettable | XvGettable, -1, 1, "XV_PIPE"}
 
85
};
 
86
 
 
87
#define GAMMA_ATTRIBUTES 6
 
88
static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
 
89
        {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
 
90
        {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"},
 
91
        {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"},
 
92
        {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"},
 
93
        {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"},
 
94
        {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
 
95
};
 
96
 
 
97
#define NUM_IMAGES 4
 
98
 
 
99
static XF86ImageRec Images[NUM_IMAGES] = {
 
100
        XVIMAGE_YUY2,
 
101
        XVIMAGE_YV12,
 
102
        XVIMAGE_I420,
 
103
        XVIMAGE_UYVY,
 
104
};
 
105
 
 
106
/* kernel modesetting overlay functions */
 
107
static Bool sna_has_overlay(struct sna *sna)
 
108
{
 
109
        struct drm_i915_getparam gp;
 
110
        int has_overlay = 0;
 
111
        int ret;
 
112
 
 
113
        gp.param = I915_PARAM_HAS_OVERLAY;
 
114
        gp.value = &has_overlay;
 
115
        ret = drmCommandWriteRead(sna->kgem.fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
 
116
 
 
117
        return !! has_overlay;
 
118
        (void)ret;
 
119
}
 
120
 
 
121
static Bool sna_video_overlay_update_attrs(struct sna *sna,
 
122
                                           struct sna_video *video)
 
123
{
 
124
        struct drm_intel_overlay_attrs attrs;
 
125
 
 
126
        DBG(("%s()\n", __FUNCTION__));
 
127
 
 
128
        attrs.flags = I915_OVERLAY_UPDATE_ATTRS;
 
129
        attrs.brightness = video->brightness;
 
130
        attrs.contrast = video->contrast;
 
131
        attrs.saturation = video->saturation;
 
132
        attrs.color_key = video->color_key;
 
133
        attrs.gamma0 = video->gamma0;
 
134
        attrs.gamma1 = video->gamma1;
 
135
        attrs.gamma2 = video->gamma2;
 
136
        attrs.gamma3 = video->gamma3;
 
137
        attrs.gamma4 = video->gamma4;
 
138
        attrs.gamma5 = video->gamma5;
 
139
 
 
140
        return drmCommandWriteRead(sna->kgem.fd, DRM_I915_OVERLAY_ATTRS,
 
141
                                  &attrs, sizeof(attrs)) == 0;
 
142
}
 
143
 
 
144
static void sna_video_overlay_off(struct sna *sna)
 
145
{
 
146
        struct drm_intel_overlay_put_image request;
 
147
        int ret;
 
148
 
 
149
        DBG(("%s()\n", __FUNCTION__));
 
150
 
 
151
        request.flags = 0;
 
152
 
 
153
        ret = drmCommandWrite(sna->kgem.fd, DRM_I915_OVERLAY_PUT_IMAGE,
 
154
                              &request, sizeof(request));
 
155
        (void)ret;
 
156
}
 
157
 
 
158
static void sna_video_overlay_stop(ScrnInfoPtr scrn,
 
159
                                   pointer data,
 
160
                                   Bool shutdown)
 
161
{
 
162
        struct sna *sna = to_sna(scrn);
 
163
        struct sna_video *video = data;
 
164
 
 
165
        DBG(("%s()\n", __FUNCTION__));
 
166
 
 
167
        REGION_EMPTY(scrn->pScreen, &video->clip);
 
168
 
 
169
        if (!shutdown)
 
170
                return;
 
171
 
 
172
        sna_video_overlay_off(sna);
 
173
        sna_video_free_buffers(sna, video);
 
174
}
 
175
 
 
176
static int
 
177
sna_video_overlay_set_port_attribute(ScrnInfoPtr scrn,
 
178
                                     Atom attribute, INT32 value, pointer data)
 
179
{
 
180
        struct sna *sna = to_sna(scrn);
 
181
        struct sna_video *video = data;
 
182
 
 
183
        if (attribute == xvBrightness) {
 
184
                if ((value < -128) || (value > 127))
 
185
                        return BadValue;
 
186
                DBG(("%s: BRIGHTNESS %d -> %d\n", __FUNCTION__,
 
187
                     video->contrast, (int)value));
 
188
                video->brightness = value;
 
189
        } else if (attribute == xvContrast) {
 
190
                if ((value < 0) || (value > 255))
 
191
                        return BadValue;
 
192
                DBG(("%s: CONTRAST %d -> %d\n", __FUNCTION__,
 
193
                     video->contrast, (int)value));
 
194
                video->contrast = value;
 
195
        } else if (attribute == xvSaturation) {
 
196
                if ((value < 0) || (value > 1023))
 
197
                        return BadValue;
 
198
                DBG(("%s: SATURATION %d -> %d\n", __FUNCTION__,
 
199
                     video->saturation, (int)value));
 
200
                video->saturation = value;
 
201
        } else if (attribute == xvPipe) {
 
202
                xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 
203
                if ((value < -1) || (value > xf86_config->num_crtc))
 
204
                        return BadValue;
 
205
                if (value < 0)
 
206
                        video->desired_crtc = NULL;
 
207
                else
 
208
                        video->desired_crtc = xf86_config->crtc[value];
 
209
        } else if (attribute == xvGamma0 && HAS_GAMMA(sna)) {
 
210
                video->gamma0 = value;
 
211
        } else if (attribute == xvGamma1 && HAS_GAMMA(sna)) {
 
212
                video->gamma1 = value;
 
213
        } else if (attribute == xvGamma2 && HAS_GAMMA(sna)) {
 
214
                video->gamma2 = value;
 
215
        } else if (attribute == xvGamma3 && HAS_GAMMA(sna)) {
 
216
                video->gamma3 = value;
 
217
        } else if (attribute == xvGamma4 && HAS_GAMMA(sna)) {
 
218
                video->gamma4 = value;
 
219
        } else if (attribute == xvGamma5 && HAS_GAMMA(sna)) {
 
220
                video->gamma5 = value;
 
221
        } else if (attribute == xvColorKey) {
 
222
                video->color_key = value;
 
223
                DBG(("COLORKEY\n"));
 
224
        } else
 
225
                return BadMatch;
 
226
 
 
227
        if ((attribute == xvGamma0 ||
 
228
             attribute == xvGamma1 ||
 
229
             attribute == xvGamma2 ||
 
230
             attribute == xvGamma3 ||
 
231
             attribute == xvGamma4 ||
 
232
             attribute == xvGamma5) && HAS_GAMMA(sna)) {
 
233
                DBG(("%s: GAMMA\n", __FUNCTION__));
 
234
        }
 
235
 
 
236
        if (!sna_video_overlay_update_attrs(sna, data))
 
237
                return BadValue;
 
238
 
 
239
        if (attribute == xvColorKey)
 
240
                REGION_EMPTY(scrn->pScreen, &video->clip);
 
241
 
 
242
        return Success;
 
243
}
 
244
 
 
245
static int
 
246
sna_video_overlay_get_port_attribute(ScrnInfoPtr scrn,
 
247
                                     Atom attribute, INT32 * value, pointer data)
 
248
{
 
249
        struct sna *sna = to_sna(scrn);
 
250
        struct sna_video *video = (struct sna_video *) data;
 
251
 
 
252
        if (attribute == xvBrightness) {
 
253
                *value = video->brightness;
 
254
        } else if (attribute == xvContrast) {
 
255
                *value = video->contrast;
 
256
        } else if (attribute == xvSaturation) {
 
257
                *value = video->saturation;
 
258
        } else if (attribute == xvPipe) {
 
259
                int c;
 
260
                xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 
261
                for (c = 0; c < xf86_config->num_crtc; c++)
 
262
                        if (xf86_config->crtc[c] == video->desired_crtc)
 
263
                                break;
 
264
                if (c == xf86_config->num_crtc)
 
265
                        c = -1;
 
266
                *value = c;
 
267
        } else if (attribute == xvGamma0 && HAS_GAMMA(sna)) {
 
268
                *value = video->gamma0;
 
269
        } else if (attribute == xvGamma1 && HAS_GAMMA(sna)) {
 
270
                *value = video->gamma1;
 
271
        } else if (attribute == xvGamma2 && HAS_GAMMA(sna)) {
 
272
                *value = video->gamma2;
 
273
        } else if (attribute == xvGamma3 && HAS_GAMMA(sna)) {
 
274
                *value = video->gamma3;
 
275
        } else if (attribute == xvGamma4 && HAS_GAMMA(sna)) {
 
276
                *value = video->gamma4;
 
277
        } else if (attribute == xvGamma5 && HAS_GAMMA(sna)) {
 
278
                *value = video->gamma5;
 
279
        } else if (attribute == xvColorKey) {
 
280
                *value = video->color_key;
 
281
        } else if (attribute == xvSyncToVblank) {
 
282
                *value = video->SyncToVblank;
 
283
        } else
 
284
                return BadMatch;
 
285
 
 
286
        return Success;
 
287
}
 
288
 
 
289
static void
 
290
sna_video_overlay_query_best_size(ScrnInfoPtr scrn,
 
291
                                  Bool motion,
 
292
                                  short vid_w, short vid_h,
 
293
                                  short drw_w, short drw_h,
 
294
                                  unsigned int *p_w, unsigned int *p_h, pointer data)
 
295
{
 
296
        if (vid_w > (drw_w << 1))
 
297
                drw_w = vid_w >> 1;
 
298
        if (vid_h > (drw_h << 1))
 
299
                drw_h = vid_h >> 1;
 
300
 
 
301
        *p_w = drw_w;
 
302
        *p_h = drw_h;
 
303
}
 
304
 
 
305
static void
 
306
update_dst_box_to_crtc_coords(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox)
 
307
{
 
308
        ScrnInfoPtr scrn = sna->scrn;
 
309
        int tmp;
 
310
 
 
311
        /* for overlay, we should take it from crtc's screen
 
312
         * coordinate to current crtc's display mode.
 
313
         * yeah, a bit confusing.
 
314
         */
 
315
        switch (crtc->rotation & 0xf) {
 
316
        case RR_Rotate_0:
 
317
                dstBox->x1 -= crtc->x;
 
318
                dstBox->x2 -= crtc->x;
 
319
                dstBox->y1 -= crtc->y;
 
320
                dstBox->y2 -= crtc->y;
 
321
                break;
 
322
        case RR_Rotate_90:
 
323
                tmp = dstBox->x1;
 
324
                dstBox->x1 = dstBox->y1 - crtc->x;
 
325
                dstBox->y1 = scrn->virtualX - tmp - crtc->y;
 
326
                tmp = dstBox->x2;
 
327
                dstBox->x2 = dstBox->y2 - crtc->x;
 
328
                dstBox->y2 = scrn->virtualX - tmp - crtc->y;
 
329
                tmp = dstBox->y1;
 
330
                dstBox->y1 = dstBox->y2;
 
331
                dstBox->y2 = tmp;
 
332
                break;
 
333
        case RR_Rotate_180:
 
334
                tmp = dstBox->x1;
 
335
                dstBox->x1 = scrn->virtualX - dstBox->x2 - crtc->x;
 
336
                dstBox->x2 = scrn->virtualX - tmp - crtc->x;
 
337
                tmp = dstBox->y1;
 
338
                dstBox->y1 = scrn->virtualY - dstBox->y2 - crtc->y;
 
339
                dstBox->y2 = scrn->virtualY - tmp - crtc->y;
 
340
                break;
 
341
        case RR_Rotate_270:
 
342
                tmp = dstBox->x1;
 
343
                dstBox->x1 = scrn->virtualY - dstBox->y1 - crtc->x;
 
344
                dstBox->y1 = tmp - crtc->y;
 
345
                tmp = dstBox->x2;
 
346
                dstBox->x2 = scrn->virtualY - dstBox->y2 - crtc->x;
 
347
                dstBox->y2 = tmp - crtc->y;
 
348
                tmp = dstBox->x1;
 
349
                dstBox->x1 = dstBox->x2;
 
350
                dstBox->x2 = tmp;
 
351
                break;
 
352
        }
 
353
 
 
354
        return;
 
355
}
 
356
 
 
357
static Bool
 
358
sna_video_overlay_show(struct sna *sna,
 
359
                       struct sna_video *video,
 
360
                       struct sna_video_frame *frame,
 
361
                       xf86CrtcPtr crtc,
 
362
                       BoxPtr dstBox,
 
363
                       short src_w, short src_h,
 
364
                       short drw_w, short drw_h)
 
365
{
 
366
        struct drm_intel_overlay_put_image request;
 
367
        bool planar = is_planar_fourcc(frame->id);
 
368
        float scale;
 
369
 
 
370
        DBG(("%s: src=(%dx%d), dst=(%dx%d)\n", __FUNCTION__,
 
371
             src_w, src_h, drw_w, drw_h));
 
372
 
 
373
        update_dst_box_to_crtc_coords(sna, crtc, dstBox);
 
374
        if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
 
375
                int tmp;
 
376
 
 
377
                tmp = frame->width;
 
378
                frame->width = frame->height;
 
379
                frame->height = tmp;
 
380
 
 
381
                tmp = drw_w;
 
382
                drw_w = drw_h;
 
383
                drw_h = tmp;
 
384
 
 
385
                tmp = src_w;
 
386
                src_w = src_h;
 
387
                src_h = tmp;
 
388
        }
 
389
 
 
390
        memset(&request, 0, sizeof(request));
 
391
        request.flags = I915_OVERLAY_ENABLE;
 
392
 
 
393
        request.bo_handle = frame->bo->handle;
 
394
        if (planar) {
 
395
                request.stride_Y = frame->pitch[1];
 
396
                request.stride_UV = frame->pitch[0];
 
397
        } else {
 
398
                request.stride_Y = frame->pitch[0];
 
399
                request.stride_UV = 0;
 
400
        }
 
401
        request.offset_Y = 0;
 
402
        request.offset_U = frame->UBufOffset;
 
403
        request.offset_V = frame->VBufOffset;
 
404
        DBG(("%s: handle=%d, stride_Y=%d, stride_UV=%d, off_Y: %i, off_U: %i, off_V: %i\n",
 
405
             __FUNCTION__,
 
406
             request.bo_handle, request.stride_Y, request.stride_UV,
 
407
             request.offset_Y, request.offset_U, request.offset_V));
 
408
 
 
409
        request.crtc_id = sna_crtc_id(crtc);
 
410
        request.dst_x = dstBox->x1;
 
411
        request.dst_y = dstBox->y1;
 
412
        request.dst_width = dstBox->x2 - dstBox->x1;
 
413
        request.dst_height = dstBox->y2 - dstBox->y1;
 
414
 
 
415
        DBG(("%s: crtc=%d, dst=(%d, %d)x(%d, %d)\n",
 
416
             __FUNCTION__, request.crtc_id,
 
417
             request.dst_x, request.dst_y,
 
418
             request.dst_width, request.dst_height));
 
419
 
 
420
        request.src_width = frame->width;
 
421
        request.src_height = frame->height;
 
422
        /* adjust src dimensions */
 
423
        if (request.dst_height > 1) {
 
424
                scale = ((float)request.dst_height - 1) / ((float)drw_h - 1);
 
425
                request.src_scan_height = src_h * scale;
 
426
        } else
 
427
                request.src_scan_height = 1;
 
428
 
 
429
        if (request.dst_width > 1) {
 
430
                scale = ((float)request.dst_width - 1) / ((float)drw_w - 1);
 
431
                request.src_scan_width = src_w * scale;
 
432
        } else
 
433
                request.src_scan_width = 1;
 
434
 
 
435
        DBG(("%s: src=(%d, %d) scan=(%d, %d)\n",
 
436
             __FUNCTION__,
 
437
             request.src_width, request.src_height,
 
438
             request.src_scan_width, request.src_scan_height));
 
439
 
 
440
        if (planar) {
 
441
                request.flags |= I915_OVERLAY_YUV_PLANAR | I915_OVERLAY_YUV420;
 
442
        } else {
 
443
                request.flags |= I915_OVERLAY_YUV_PACKED | I915_OVERLAY_YUV422;
 
444
                if (frame->id == FOURCC_UYVY)
 
445
                        request.flags |= I915_OVERLAY_Y_SWAP;
 
446
        }
 
447
 
 
448
        DBG(("%s: flags=%x\n", __FUNCTION__, request.flags));
 
449
 
 
450
        return drmCommandWrite(sna->kgem.fd, DRM_I915_OVERLAY_PUT_IMAGE,
 
451
                               &request, sizeof(request)) == 0;
 
452
}
 
453
 
 
454
static int
 
455
sna_video_overlay_put_image(ScrnInfoPtr scrn,
 
456
                            short src_x, short src_y,
 
457
                            short drw_x, short drw_y,
 
458
                            short src_w, short src_h,
 
459
                            short drw_w, short drw_h,
 
460
                            int id, unsigned char *buf,
 
461
                            short width, short height,
 
462
                            Bool sync, RegionPtr clip, pointer data,
 
463
                            DrawablePtr drawable)
 
464
{
 
465
        struct sna *sna = to_sna(scrn);
 
466
        struct sna_video *video = data;
 
467
        struct sna_video_frame frame;
 
468
        BoxRec dstBox;
 
469
        xf86CrtcPtr crtc;
 
470
        int top, left, npixels, nlines;
 
471
 
 
472
        DBG(("%s: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d), width %d, height %d\n",
 
473
             __FUNCTION__,
 
474
             src_x, src_y, src_w, src_h, drw_x,
 
475
             drw_y, drw_w, drw_h, width, height));
 
476
 
 
477
        /* If dst width and height are less than 1/8th the src size, the
 
478
         * src/dst scale factor becomes larger than 8 and doesn't fit in
 
479
         * the scale register. */
 
480
        if (src_w >= (drw_w * 8))
 
481
                drw_w = src_w / 7;
 
482
 
 
483
        if (src_h >= (drw_h * 8))
 
484
                drw_h = src_h / 7;
 
485
 
 
486
        if (!sna_video_clip_helper(scrn,
 
487
                                   video,
 
488
                                   &crtc,
 
489
                                   &dstBox,
 
490
                                   src_x, src_y, drw_x, drw_y,
 
491
                                   src_w, src_h, drw_w, drw_h,
 
492
                                   id,
 
493
                                   &top, &left, &npixels, &nlines, clip,
 
494
                                   width, height))
 
495
                return Success;
 
496
 
 
497
        if (!crtc) {
 
498
                /*
 
499
                 * If the video isn't visible on any CRTC, turn it off
 
500
                 */
 
501
                sna_video_overlay_off(sna);
 
502
                return Success;
 
503
        }
 
504
 
 
505
        sna_video_frame_init(sna, video, id, width, height, &frame);
 
506
 
 
507
        /* overlay can't handle rotation natively, store it for the copy func */
 
508
        video->rotation = crtc->rotation;
 
509
        if (!sna_video_copy_data(sna, video, &frame,
 
510
                                 top, left, npixels, nlines, buf)) {
 
511
                DBG(("%s: failed to copy video data\n", __FUNCTION__));
 
512
                return BadAlloc;
 
513
        }
 
514
 
 
515
        if (!sna_video_overlay_show
 
516
            (sna, video, &frame, crtc, &dstBox, src_w, src_h, drw_w, drw_h)) {
 
517
                DBG(("%s: failed to show video frame\n", __FUNCTION__));
 
518
                return BadAlloc;
 
519
        }
 
520
 
 
521
        sna_video_frame_fini(sna, video, &frame);
 
522
 
 
523
        /* update cliplist */
 
524
        if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) {
 
525
                REGION_COPY(scrn->pScreen, &video->clip, clip);
 
526
                xf86XVFillKeyHelperDrawable(drawable, video->color_key, clip);
 
527
        }
 
528
 
 
529
        return Success;
 
530
}
 
531
 
 
532
static int
 
533
sna_video_overlay_query_video_attributes(ScrnInfoPtr scrn,
 
534
                                         int id,
 
535
                                         unsigned short *w, unsigned short *h,
 
536
                                         int *pitches, int *offsets)
 
537
{
 
538
        struct sna *sna = to_sna(scrn);
 
539
        int size, tmp;
 
540
 
 
541
        DBG(("%s: w is %d, h is %d\n", __FUNCTION__, *w, *h));
 
542
 
 
543
        if (sna->kgem.gen < 21) {
 
544
                if (*w > IMAGE_MAX_WIDTH_LEGACY)
 
545
                        *w = IMAGE_MAX_WIDTH_LEGACY;
 
546
                if (*h > IMAGE_MAX_HEIGHT_LEGACY)
 
547
                        *h = IMAGE_MAX_HEIGHT_LEGACY;
 
548
        } else {
 
549
                if (*w > IMAGE_MAX_WIDTH)
 
550
                        *w = IMAGE_MAX_WIDTH;
 
551
                if (*h > IMAGE_MAX_HEIGHT)
 
552
                        *h = IMAGE_MAX_HEIGHT;
 
553
        }
 
554
 
 
555
        *w = (*w + 1) & ~1;
 
556
        if (offsets)
 
557
                offsets[0] = 0;
 
558
 
 
559
        switch (id) {
 
560
                /* IA44 is for XvMC only */
 
561
        case FOURCC_IA44:
 
562
        case FOURCC_AI44:
 
563
                if (pitches)
 
564
                        pitches[0] = *w;
 
565
                size = *w * *h;
 
566
                break;
 
567
        case FOURCC_YV12:
 
568
        case FOURCC_I420:
 
569
                *h = (*h + 1) & ~1;
 
570
                size = (*w + 3) & ~3;
 
571
                if (pitches)
 
572
                        pitches[0] = size;
 
573
                size *= *h;
 
574
                if (offsets)
 
575
                        offsets[1] = size;
 
576
                tmp = ((*w >> 1) + 3) & ~3;
 
577
                if (pitches)
 
578
                        pitches[1] = pitches[2] = tmp;
 
579
                tmp *= (*h >> 1);
 
580
                size += tmp;
 
581
                if (offsets)
 
582
                        offsets[2] = size;
 
583
                size += tmp;
 
584
#if 0
 
585
                if (pitches)
 
586
                        ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n",
 
587
                               pitches[0], pitches[1], pitches[2]);
 
588
                if (offsets)
 
589
                        ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1],
 
590
                               offsets[2]);
 
591
                if (offsets)
 
592
                        ErrorF("size is %d\n", size);
 
593
#endif
 
594
                break;
 
595
        case FOURCC_UYVY:
 
596
        case FOURCC_YUY2:
 
597
        default:
 
598
                size = *w << 1;
 
599
                if (pitches)
 
600
                        pitches[0] = size;
 
601
                size *= *h;
 
602
                break;
 
603
        }
 
604
 
 
605
        return size;
 
606
}
 
607
 
 
608
static int sna_video_overlay_color_key(struct sna *sna)
 
609
{
 
610
        ScrnInfoPtr scrn = sna->scrn;
 
611
        int color_key;
 
612
 
 
613
        if (xf86GetOptValInteger(sna->Options, OPTION_VIDEO_KEY,
 
614
                                 &color_key)) {
 
615
        } else if (xf86GetOptValInteger(sna->Options, OPTION_COLOR_KEY,
 
616
                                        &color_key)) {
 
617
        } else {
 
618
                color_key =
 
619
                    (1 << scrn->offset.red) |
 
620
                    (1 << scrn->offset.green) |
 
621
                    (((scrn->mask.blue >> scrn->offset.blue) - 1) << scrn->offset.blue);
 
622
        }
 
623
 
 
624
        return color_key & ((1 << scrn->depth) - 1);
 
625
}
 
626
 
 
627
XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
 
628
                                            ScreenPtr screen)
 
629
{
 
630
        XF86VideoAdaptorPtr adaptor;
 
631
        struct sna_video *video;
 
632
        XF86AttributePtr att;
 
633
 
 
634
        if (!sna_has_overlay(sna)) {
 
635
                xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
 
636
                           "Overlay video not supported on this hardware\n");
 
637
                return NULL;
 
638
        }
 
639
 
 
640
        DBG(("%s()\n", __FUNCTION__));
 
641
 
 
642
        if (!(adaptor = calloc(1,
 
643
                             sizeof(XF86VideoAdaptorRec) +
 
644
                             sizeof(struct sna_video) +
 
645
                             sizeof(DevUnion))))
 
646
                return NULL;
 
647
 
 
648
        adaptor->type = XvWindowMask | XvInputMask | XvImageMask;
 
649
        adaptor->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT */ ;
 
650
        adaptor->name = "Intel(R) Video Overlay";
 
651
        adaptor->nEncodings = 1;
 
652
        adaptor->pEncodings = xnfalloc(sizeof(DummyEncoding));
 
653
        memcpy(adaptor->pEncodings, DummyEncoding, sizeof(DummyEncoding));
 
654
        if (sna->kgem.gen < 21) {
 
655
                adaptor->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;
 
656
                adaptor->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;
 
657
        }
 
658
        adaptor->nFormats = NUM_FORMATS;
 
659
        adaptor->pFormats = Formats;
 
660
        adaptor->nPorts = 1;
 
661
        adaptor->pPortPrivates = (DevUnion *)&adaptor[1];
 
662
 
 
663
        video = (struct sna_video *)&adaptor->pPortPrivates[1];
 
664
 
 
665
        adaptor->pPortPrivates[0].ptr = video;
 
666
        adaptor->nAttributes = NUM_ATTRIBUTES;
 
667
        if (HAS_GAMMA(sna))
 
668
                adaptor->nAttributes += GAMMA_ATTRIBUTES;
 
669
        adaptor->pAttributes =
 
670
            xnfalloc(sizeof(XF86AttributeRec) * adaptor->nAttributes);
 
671
        /* Now copy the attributes */
 
672
        att = adaptor->pAttributes;
 
673
        memcpy(att, Attributes, sizeof(XF86AttributeRec) * NUM_ATTRIBUTES);
 
674
        att += NUM_ATTRIBUTES;
 
675
        if (HAS_GAMMA(sna)) {
 
676
                memcpy(att, GammaAttributes,
 
677
                       sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
 
678
                att += GAMMA_ATTRIBUTES;
 
679
        }
 
680
        adaptor->nImages = NUM_IMAGES;
 
681
        adaptor->pImages = Images;
 
682
        adaptor->PutVideo = NULL;
 
683
        adaptor->PutStill = NULL;
 
684
        adaptor->GetVideo = NULL;
 
685
        adaptor->GetStill = NULL;
 
686
        adaptor->StopVideo = sna_video_overlay_stop;
 
687
        adaptor->SetPortAttribute = sna_video_overlay_set_port_attribute;
 
688
        adaptor->GetPortAttribute = sna_video_overlay_get_port_attribute;
 
689
        adaptor->QueryBestSize = sna_video_overlay_query_best_size;
 
690
        adaptor->PutImage = sna_video_overlay_put_image;
 
691
        adaptor->QueryImageAttributes = sna_video_overlay_query_video_attributes;
 
692
 
 
693
        video->textured = FALSE;
 
694
        video->color_key = sna_video_overlay_color_key(sna);
 
695
        video->brightness = -19;        /* (255/219) * -16 */
 
696
        video->contrast = 75;   /* 255/219 * 64 */
 
697
        video->saturation = 146;        /* 128/112 * 128 */
 
698
        video->desired_crtc = NULL;
 
699
        video->gamma5 = 0xc0c0c0;
 
700
        video->gamma4 = 0x808080;
 
701
        video->gamma3 = 0x404040;
 
702
        video->gamma2 = 0x202020;
 
703
        video->gamma1 = 0x101010;
 
704
        video->gamma0 = 0x080808;
 
705
 
 
706
        video->rotation = RR_Rotate_0;
 
707
 
 
708
        /* gotta uninit this someplace */
 
709
        REGION_NULL(screen, &video->clip);
 
710
 
 
711
        xvColorKey = MAKE_ATOM("XV_COLORKEY");
 
712
        xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
 
713
        xvContrast = MAKE_ATOM("XV_CONTRAST");
 
714
        xvSaturation = MAKE_ATOM("XV_SATURATION");
 
715
 
 
716
        /* Allow the pipe to be switched from pipe A to B when in clone mode */
 
717
        xvPipe = MAKE_ATOM("XV_PIPE");
 
718
 
 
719
        if (HAS_GAMMA(sna)) {
 
720
                xvGamma0 = MAKE_ATOM("XV_GAMMA0");
 
721
                xvGamma1 = MAKE_ATOM("XV_GAMMA1");
 
722
                xvGamma2 = MAKE_ATOM("XV_GAMMA2");
 
723
                xvGamma3 = MAKE_ATOM("XV_GAMMA3");
 
724
                xvGamma4 = MAKE_ATOM("XV_GAMMA4");
 
725
                xvGamma5 = MAKE_ATOM("XV_GAMMA5");
 
726
        }
 
727
 
 
728
        sna_video_overlay_update_attrs(sna, video);
 
729
 
 
730
        return adaptor;
 
731
}