1428d7b3dSmrg/*************************************************************************** 2428d7b3dSmrg 3428d7b3dSmrg Copyright 2000-2011 Intel Corporation. All Rights Reserved. 4428d7b3dSmrg 5428d7b3dSmrg Permission is hereby granted, free of charge, to any person obtaining a 6428d7b3dSmrg copy of this software and associated documentation files (the 7428d7b3dSmrg "Software"), to deal in the Software without restriction, including 8428d7b3dSmrg without limitation the rights to use, copy, modify, merge, publish, 9428d7b3dSmrg distribute, sub license, and/or sell copies of the Software, and to 10428d7b3dSmrg permit persons to whom the Software is furnished to do so, subject to 11428d7b3dSmrg the following conditions: 12428d7b3dSmrg 13428d7b3dSmrg The above copyright notice and this permission notice (including the 14428d7b3dSmrg next paragraph) shall be included in all copies or substantial portions 15428d7b3dSmrg of the Software. 16428d7b3dSmrg 17428d7b3dSmrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18428d7b3dSmrg OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19428d7b3dSmrg MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20428d7b3dSmrg IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 21428d7b3dSmrg DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22428d7b3dSmrg OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23428d7b3dSmrg THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24428d7b3dSmrg 25428d7b3dSmrg **************************************************************************/ 26428d7b3dSmrg 27428d7b3dSmrg#ifdef HAVE_CONFIG_H 28428d7b3dSmrg#include "config.h" 29428d7b3dSmrg#endif 30428d7b3dSmrg 31428d7b3dSmrg#include "sna.h" 32428d7b3dSmrg#include "sna_video.h" 33428d7b3dSmrg 34428d7b3dSmrg#include <xf86drm.h> 35428d7b3dSmrg#include <xf86xv.h> 36428d7b3dSmrg#include <X11/extensions/Xv.h> 37428d7b3dSmrg#include <fourcc.h> 38428d7b3dSmrg#include <i915_drm.h> 39428d7b3dSmrg 40428d7b3dSmrg#include "intel_options.h" 41428d7b3dSmrg 42428d7b3dSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 43428d7b3dSmrg 44428d7b3dSmrg#define HAS_GAMMA(sna) ((sna)->kgem.gen >= 030) 45428d7b3dSmrg 46428d7b3dSmrgstatic Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvAlwaysOnTop; 47428d7b3dSmrgstatic Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5; 48428d7b3dSmrg 49428d7b3dSmrg/* Limits for the overlay/textured video source sizes. The documented hardware 50428d7b3dSmrg * limits are 2048x2048 or better for overlay and both of our textured video 51428d7b3dSmrg * implementations. Additionally, on the 830 and 845, larger sizes resulted in 52428d7b3dSmrg * the card hanging, so we keep the limits lower there. 53428d7b3dSmrg */ 54428d7b3dSmrg#define IMAGE_MAX_WIDTH 2048 55428d7b3dSmrg#define IMAGE_MAX_HEIGHT 2048 56428d7b3dSmrg#define IMAGE_MAX_WIDTH_LEGACY 1024 57428d7b3dSmrg#define IMAGE_MAX_HEIGHT_LEGACY 1088 58428d7b3dSmrg 59428d7b3dSmrgstatic XvFormatRec Formats[] = { {15}, {16}, {24} }; 60428d7b3dSmrg 61428d7b3dSmrgstatic const XvAttributeRec Attributes[] = { 62428d7b3dSmrg {XvSettable | XvGettable, 0, (1 << 24) - 1, (char *)"XV_COLORKEY"}, 63428d7b3dSmrg {XvSettable | XvGettable, 0, 1, (char *)"XV_ALWAYS_ON_TOP"}, 64428d7b3dSmrg {XvSettable | XvGettable, -128, 127, (char *)"XV_BRIGHTNESS"}, 65428d7b3dSmrg {XvSettable | XvGettable, 0, 255, (char *)"XV_CONTRAST"}, 66428d7b3dSmrg {XvSettable | XvGettable, 0, 1023, (char *)"XV_SATURATION"}, 67428d7b3dSmrg {XvSettable | XvGettable, -1, 1, (char *)"XV_PIPE"}, 68428d7b3dSmrg#define NUM_ATTRIBUTES 6 69428d7b3dSmrg 70428d7b3dSmrg {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA0"}, 71428d7b3dSmrg {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA1"}, 72428d7b3dSmrg {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA2"}, 73428d7b3dSmrg {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA3"}, 74428d7b3dSmrg {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA4"}, 75428d7b3dSmrg {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA5"} 76428d7b3dSmrg#define GAMMA_ATTRIBUTES 6 77428d7b3dSmrg}; 78428d7b3dSmrg 79428d7b3dSmrgstatic const XvImageRec Images[] = { 80428d7b3dSmrg XVIMAGE_YUY2, 81428d7b3dSmrg XVIMAGE_YV12, 82428d7b3dSmrg XVIMAGE_I420, 83428d7b3dSmrg XVIMAGE_UYVY, 84428d7b3dSmrg XVMC_YUV 85428d7b3dSmrg}; 86428d7b3dSmrg 87428d7b3dSmrg/* kernel modesetting overlay functions */ 88428d7b3dSmrgstatic bool sna_has_overlay(struct sna *sna) 89428d7b3dSmrg{ 90428d7b3dSmrg struct drm_i915_getparam gp; 91428d7b3dSmrg int has_overlay = 0; 92428d7b3dSmrg int ret; 93428d7b3dSmrg 94428d7b3dSmrg VG_CLEAR(gp); 95428d7b3dSmrg gp.param = I915_PARAM_HAS_OVERLAY; 96428d7b3dSmrg gp.value = &has_overlay; 97428d7b3dSmrg ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp); 98428d7b3dSmrg return ret == 0 && has_overlay; 99428d7b3dSmrg} 100428d7b3dSmrg 101428d7b3dSmrgstatic bool sna_video_overlay_update_attrs(struct sna_video *video) 102428d7b3dSmrg{ 103428d7b3dSmrg struct drm_intel_overlay_attrs attrs; 104428d7b3dSmrg 105428d7b3dSmrg DBG(("%s()\n", __FUNCTION__)); 106428d7b3dSmrg 107428d7b3dSmrg attrs.flags = I915_OVERLAY_UPDATE_ATTRS; 108428d7b3dSmrg attrs.brightness = video->brightness; 109428d7b3dSmrg attrs.contrast = video->contrast; 110428d7b3dSmrg attrs.saturation = video->saturation; 111428d7b3dSmrg attrs.color_key = video->color_key; 112428d7b3dSmrg attrs.gamma0 = video->gamma0; 113428d7b3dSmrg attrs.gamma1 = video->gamma1; 114428d7b3dSmrg attrs.gamma2 = video->gamma2; 115428d7b3dSmrg attrs.gamma3 = video->gamma3; 116428d7b3dSmrg attrs.gamma4 = video->gamma4; 117428d7b3dSmrg attrs.gamma5 = video->gamma5; 118428d7b3dSmrg 119428d7b3dSmrg if (video->AlwaysOnTop) 120428d7b3dSmrg attrs.flags |= 1<<2; 121428d7b3dSmrg 122428d7b3dSmrg return drmIoctl(video->sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_ATTRS, &attrs) == 0; 123428d7b3dSmrg} 124428d7b3dSmrg 125428d7b3dSmrgstatic int sna_video_overlay_stop(ddStopVideo_ARGS) 126428d7b3dSmrg{ 127428d7b3dSmrg struct sna_video *video = port->devPriv.ptr; 128428d7b3dSmrg struct sna *sna = video->sna; 129428d7b3dSmrg struct drm_intel_overlay_put_image request; 130428d7b3dSmrg 131428d7b3dSmrg DBG(("%s()\n", __FUNCTION__)); 132428d7b3dSmrg 133428d7b3dSmrg REGION_EMPTY(scrn->pScreen, &video->clip); 134428d7b3dSmrg 135428d7b3dSmrg request.flags = 0; 136428d7b3dSmrg (void)drmIoctl(sna->kgem.fd, 137428d7b3dSmrg DRM_IOCTL_I915_OVERLAY_PUT_IMAGE, 138428d7b3dSmrg &request); 139428d7b3dSmrg 140428d7b3dSmrg if (video->bo[0]) 141428d7b3dSmrg kgem_bo_destroy(&sna->kgem, video->bo[0]); 142428d7b3dSmrg video->bo[0] = NULL; 143428d7b3dSmrg 144428d7b3dSmrg sna_video_free_buffers(video); 145428d7b3dSmrg sna_window_set_port((WindowPtr)draw, NULL); 146428d7b3dSmrg return Success; 147428d7b3dSmrg} 148428d7b3dSmrg 149428d7b3dSmrgstatic int 150428d7b3dSmrgsna_video_overlay_set_attribute(ddSetPortAttribute_ARGS) 151428d7b3dSmrg{ 152428d7b3dSmrg struct sna_video *video = port->devPriv.ptr; 153428d7b3dSmrg struct sna *sna = video->sna; 154428d7b3dSmrg 155428d7b3dSmrg DBG(("%s: set(%lx) to %d\n", __FUNCTION__, (long)attribute, (int)value)); 156428d7b3dSmrg if (attribute == xvBrightness) { 157428d7b3dSmrg if ((value < -128) || (value > 127)) 158428d7b3dSmrg return BadValue; 159428d7b3dSmrg DBG(("%s: BRIGHTNESS %d -> %d\n", __FUNCTION__, 160428d7b3dSmrg video->contrast, (int)value)); 161428d7b3dSmrg video->brightness = value; 162428d7b3dSmrg } else if (attribute == xvContrast) { 163428d7b3dSmrg if ((value < 0) || (value > 255)) 164428d7b3dSmrg return BadValue; 165428d7b3dSmrg DBG(("%s: CONTRAST %d -> %d\n", __FUNCTION__, 166428d7b3dSmrg video->contrast, (int)value)); 167428d7b3dSmrg video->contrast = value; 168428d7b3dSmrg } else if (attribute == xvSaturation) { 169428d7b3dSmrg if ((value < 0) || (value > 1023)) 170428d7b3dSmrg return BadValue; 171428d7b3dSmrg DBG(("%s: SATURATION %d -> %d\n", __FUNCTION__, 172428d7b3dSmrg video->saturation, (int)value)); 173428d7b3dSmrg video->saturation = value; 174428d7b3dSmrg } else if (attribute == xvPipe) { 175428d7b3dSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn); 176428d7b3dSmrg if ((value < -1) || (value >= xf86_config->num_crtc)) 177428d7b3dSmrg return BadValue; 178428d7b3dSmrg if (value < 0) 179428d7b3dSmrg video->desired_crtc = NULL; 180428d7b3dSmrg else 181428d7b3dSmrg video->desired_crtc = xf86_config->crtc[value]; 182428d7b3dSmrg } else if (attribute == xvAlwaysOnTop) { 183428d7b3dSmrg DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__, 184428d7b3dSmrg video->AlwaysOnTop, !!value)); 185428d7b3dSmrg video->AlwaysOnTop = !!value; 186428d7b3dSmrg } else if (attribute == xvGamma0 && HAS_GAMMA(sna)) { 187428d7b3dSmrg video->gamma0 = value; 188428d7b3dSmrg } else if (attribute == xvGamma1 && HAS_GAMMA(sna)) { 189428d7b3dSmrg video->gamma1 = value; 190428d7b3dSmrg } else if (attribute == xvGamma2 && HAS_GAMMA(sna)) { 191428d7b3dSmrg video->gamma2 = value; 192428d7b3dSmrg } else if (attribute == xvGamma3 && HAS_GAMMA(sna)) { 193428d7b3dSmrg video->gamma3 = value; 194428d7b3dSmrg } else if (attribute == xvGamma4 && HAS_GAMMA(sna)) { 195428d7b3dSmrg video->gamma4 = value; 196428d7b3dSmrg } else if (attribute == xvGamma5 && HAS_GAMMA(sna)) { 197428d7b3dSmrg video->gamma5 = value; 198428d7b3dSmrg } else if (attribute == xvColorKey) { 199428d7b3dSmrg video->color_key = value; 200428d7b3dSmrg RegionEmpty(&video->clip); 201428d7b3dSmrg DBG(("COLORKEY\n")); 202428d7b3dSmrg } else 203428d7b3dSmrg return BadMatch; 204428d7b3dSmrg 205428d7b3dSmrg if ((attribute == xvGamma0 || 206428d7b3dSmrg attribute == xvGamma1 || 207428d7b3dSmrg attribute == xvGamma2 || 208428d7b3dSmrg attribute == xvGamma3 || 209428d7b3dSmrg attribute == xvGamma4 || 210428d7b3dSmrg attribute == xvGamma5) && HAS_GAMMA(sna)) { 211428d7b3dSmrg DBG(("%s: GAMMA\n", __FUNCTION__)); 212428d7b3dSmrg } 213428d7b3dSmrg 214428d7b3dSmrg if (!sna_video_overlay_update_attrs(video)) 215428d7b3dSmrg return BadValue; 216428d7b3dSmrg 217428d7b3dSmrg return Success; 218428d7b3dSmrg} 219428d7b3dSmrg 220428d7b3dSmrgstatic int 221428d7b3dSmrgsna_video_overlay_get_attribute(ddGetPortAttribute_ARGS) 222428d7b3dSmrg{ 223428d7b3dSmrg struct sna_video *video = port->devPriv.ptr; 224428d7b3dSmrg struct sna *sna = video->sna; 225428d7b3dSmrg 226428d7b3dSmrg if (attribute == xvBrightness) { 227428d7b3dSmrg *value = video->brightness; 228428d7b3dSmrg } else if (attribute == xvContrast) { 229428d7b3dSmrg *value = video->contrast; 230428d7b3dSmrg } else if (attribute == xvSaturation) { 231428d7b3dSmrg *value = video->saturation; 232428d7b3dSmrg } else if (attribute == xvPipe) { 233428d7b3dSmrg int c; 234428d7b3dSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn); 235428d7b3dSmrg for (c = 0; c < xf86_config->num_crtc; c++) 236428d7b3dSmrg if (xf86_config->crtc[c] == video->desired_crtc) 237428d7b3dSmrg break; 238428d7b3dSmrg if (c == xf86_config->num_crtc) 239428d7b3dSmrg c = -1; 240428d7b3dSmrg *value = c; 241428d7b3dSmrg } else if (attribute == xvAlwaysOnTop) { 242428d7b3dSmrg *value = video->AlwaysOnTop; 243428d7b3dSmrg } else if (attribute == xvGamma0 && HAS_GAMMA(sna)) { 244428d7b3dSmrg *value = video->gamma0; 245428d7b3dSmrg } else if (attribute == xvGamma1 && HAS_GAMMA(sna)) { 246428d7b3dSmrg *value = video->gamma1; 247428d7b3dSmrg } else if (attribute == xvGamma2 && HAS_GAMMA(sna)) { 248428d7b3dSmrg *value = video->gamma2; 249428d7b3dSmrg } else if (attribute == xvGamma3 && HAS_GAMMA(sna)) { 250428d7b3dSmrg *value = video->gamma3; 251428d7b3dSmrg } else if (attribute == xvGamma4 && HAS_GAMMA(sna)) { 252428d7b3dSmrg *value = video->gamma4; 253428d7b3dSmrg } else if (attribute == xvGamma5 && HAS_GAMMA(sna)) { 254428d7b3dSmrg *value = video->gamma5; 255428d7b3dSmrg } else if (attribute == xvColorKey) { 256428d7b3dSmrg *value = video->color_key; 257428d7b3dSmrg } else 258428d7b3dSmrg return BadMatch; 259428d7b3dSmrg 260428d7b3dSmrg return Success; 261428d7b3dSmrg} 262428d7b3dSmrg 263428d7b3dSmrgstatic int 264428d7b3dSmrgsna_video_overlay_best_size(ddQueryBestSize_ARGS) 265428d7b3dSmrg{ 266428d7b3dSmrg struct sna_video *video = port->devPriv.ptr; 267428d7b3dSmrg struct sna *sna = video->sna; 268428d7b3dSmrg short max_w, max_h; 269428d7b3dSmrg 270428d7b3dSmrg if (vid_w > (drw_w << 1) || vid_h > (drw_h << 1)){ 271428d7b3dSmrg drw_w = vid_w >> 1; 272428d7b3dSmrg drw_h = vid_h >> 1; 273428d7b3dSmrg } 274428d7b3dSmrg 275428d7b3dSmrg if (sna->kgem.gen < 021) { 276428d7b3dSmrg max_w = IMAGE_MAX_WIDTH_LEGACY; 277428d7b3dSmrg max_h = IMAGE_MAX_HEIGHT_LEGACY; 278428d7b3dSmrg } else { 279428d7b3dSmrg max_w = IMAGE_MAX_WIDTH; 280428d7b3dSmrg max_h = IMAGE_MAX_HEIGHT; 281428d7b3dSmrg } 282428d7b3dSmrg 283428d7b3dSmrg while (drw_w > max_w || drw_h > max_h) { 284428d7b3dSmrg drw_w >>= 1; 285428d7b3dSmrg drw_h >>= 1; 286428d7b3dSmrg } 287428d7b3dSmrg 288428d7b3dSmrg *p_w = drw_w; 289428d7b3dSmrg *p_h = drw_h; 290428d7b3dSmrg return Success; 291428d7b3dSmrg} 292428d7b3dSmrg 293428d7b3dSmrgstatic void 294428d7b3dSmrgupdate_dst_box_to_crtc_coords(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox) 295428d7b3dSmrg{ 296428d7b3dSmrg ScrnInfoPtr scrn = sna->scrn; 297428d7b3dSmrg int tmp; 298428d7b3dSmrg 299428d7b3dSmrg /* for overlay, we should take it from crtc's screen 300428d7b3dSmrg * coordinate to current crtc's display mode. 301428d7b3dSmrg * yeah, a bit confusing. 302428d7b3dSmrg */ 303428d7b3dSmrg switch (crtc->rotation & 0xf) { 304428d7b3dSmrg case RR_Rotate_0: 305428d7b3dSmrg dstBox->x1 -= crtc->x; 306428d7b3dSmrg dstBox->x2 -= crtc->x; 307428d7b3dSmrg dstBox->y1 -= crtc->y; 308428d7b3dSmrg dstBox->y2 -= crtc->y; 309428d7b3dSmrg break; 310428d7b3dSmrg case RR_Rotate_90: 311428d7b3dSmrg tmp = dstBox->x1; 312428d7b3dSmrg dstBox->x1 = dstBox->y1 - crtc->x; 313428d7b3dSmrg dstBox->y1 = scrn->virtualX - tmp - crtc->y; 314428d7b3dSmrg tmp = dstBox->x2; 315428d7b3dSmrg dstBox->x2 = dstBox->y2 - crtc->x; 316428d7b3dSmrg dstBox->y2 = scrn->virtualX - tmp - crtc->y; 317428d7b3dSmrg tmp = dstBox->y1; 318428d7b3dSmrg dstBox->y1 = dstBox->y2; 319428d7b3dSmrg dstBox->y2 = tmp; 320428d7b3dSmrg break; 321428d7b3dSmrg case RR_Rotate_180: 322428d7b3dSmrg tmp = dstBox->x1; 323428d7b3dSmrg dstBox->x1 = scrn->virtualX - dstBox->x2 - crtc->x; 324428d7b3dSmrg dstBox->x2 = scrn->virtualX - tmp - crtc->x; 325428d7b3dSmrg tmp = dstBox->y1; 326428d7b3dSmrg dstBox->y1 = scrn->virtualY - dstBox->y2 - crtc->y; 327428d7b3dSmrg dstBox->y2 = scrn->virtualY - tmp - crtc->y; 328428d7b3dSmrg break; 329428d7b3dSmrg case RR_Rotate_270: 330428d7b3dSmrg tmp = dstBox->x1; 331428d7b3dSmrg dstBox->x1 = scrn->virtualY - dstBox->y1 - crtc->x; 332428d7b3dSmrg dstBox->y1 = tmp - crtc->y; 333428d7b3dSmrg tmp = dstBox->x2; 334428d7b3dSmrg dstBox->x2 = scrn->virtualY - dstBox->y2 - crtc->x; 335428d7b3dSmrg dstBox->y2 = tmp - crtc->y; 336428d7b3dSmrg tmp = dstBox->x1; 337428d7b3dSmrg dstBox->x1 = dstBox->x2; 338428d7b3dSmrg dstBox->x2 = tmp; 339428d7b3dSmrg break; 340428d7b3dSmrg } 341428d7b3dSmrg 342428d7b3dSmrg return; 343428d7b3dSmrg} 344428d7b3dSmrg 345428d7b3dSmrgstatic bool 346428d7b3dSmrgsna_video_overlay_show(struct sna *sna, 347428d7b3dSmrg struct sna_video *video, 348428d7b3dSmrg struct sna_video_frame *frame, 349428d7b3dSmrg xf86CrtcPtr crtc, 350428d7b3dSmrg BoxPtr dstBox, 351428d7b3dSmrg short src_w, short src_h, 352428d7b3dSmrg short drw_w, short drw_h) 353428d7b3dSmrg{ 354428d7b3dSmrg struct drm_intel_overlay_put_image request; 355428d7b3dSmrg bool planar = is_planar_fourcc(frame->id); 356428d7b3dSmrg float scale; 357428d7b3dSmrg 358428d7b3dSmrg DBG(("%s: src=(%dx%d), dst=(%dx%d)\n", __FUNCTION__, 359428d7b3dSmrg src_w, src_h, drw_w, drw_h)); 360428d7b3dSmrg 361428d7b3dSmrg update_dst_box_to_crtc_coords(sna, crtc, dstBox); 362428d7b3dSmrg if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) { 363428d7b3dSmrg int tmp; 364428d7b3dSmrg 365428d7b3dSmrg tmp = frame->width; 366428d7b3dSmrg frame->width = frame->height; 367428d7b3dSmrg frame->height = tmp; 368428d7b3dSmrg 369428d7b3dSmrg tmp = drw_w; 370428d7b3dSmrg drw_w = drw_h; 371428d7b3dSmrg drw_h = tmp; 372428d7b3dSmrg 373428d7b3dSmrg tmp = src_w; 374428d7b3dSmrg src_w = src_h; 375428d7b3dSmrg src_h = tmp; 376428d7b3dSmrg } 377428d7b3dSmrg 378428d7b3dSmrg memset(&request, 0, sizeof(request)); 379428d7b3dSmrg request.flags = I915_OVERLAY_ENABLE; 380428d7b3dSmrg 381428d7b3dSmrg request.bo_handle = frame->bo->handle; 382428d7b3dSmrg if (planar) { 383428d7b3dSmrg request.stride_Y = frame->pitch[1]; 384428d7b3dSmrg request.stride_UV = frame->pitch[0]; 385428d7b3dSmrg } else { 386428d7b3dSmrg request.stride_Y = frame->pitch[0]; 387428d7b3dSmrg request.stride_UV = 0; 388428d7b3dSmrg } 389428d7b3dSmrg request.offset_Y = 0; 390428d7b3dSmrg request.offset_U = frame->UBufOffset; 391428d7b3dSmrg request.offset_V = frame->VBufOffset; 392428d7b3dSmrg DBG(("%s: handle=%d, stride_Y=%d, stride_UV=%d, off_Y: %i, off_U: %i, off_V: %i\n", 393428d7b3dSmrg __FUNCTION__, 394428d7b3dSmrg request.bo_handle, request.stride_Y, request.stride_UV, 395428d7b3dSmrg request.offset_Y, request.offset_U, request.offset_V)); 396428d7b3dSmrg 397428d7b3dSmrg request.crtc_id = sna_crtc_id(crtc); 398428d7b3dSmrg request.dst_x = dstBox->x1; 399428d7b3dSmrg request.dst_y = dstBox->y1; 400428d7b3dSmrg request.dst_width = dstBox->x2 - dstBox->x1; 401428d7b3dSmrg request.dst_height = dstBox->y2 - dstBox->y1; 402428d7b3dSmrg 403428d7b3dSmrg DBG(("%s: crtc=%d, dst=(%d, %d)x(%d, %d)\n", 404428d7b3dSmrg __FUNCTION__, request.crtc_id, 405428d7b3dSmrg request.dst_x, request.dst_y, 406428d7b3dSmrg request.dst_width, request.dst_height)); 407428d7b3dSmrg 408428d7b3dSmrg request.src_width = frame->width; 409428d7b3dSmrg request.src_height = frame->height; 410428d7b3dSmrg /* adjust src dimensions */ 411428d7b3dSmrg if (request.dst_height > 1) { 412428d7b3dSmrg scale = ((float)request.dst_height - 1) / ((float)drw_h - 1); 413428d7b3dSmrg request.src_scan_height = src_h * scale; 414428d7b3dSmrg } else 415428d7b3dSmrg request.src_scan_height = 1; 416428d7b3dSmrg 417428d7b3dSmrg if (request.dst_width > 1) { 418428d7b3dSmrg scale = ((float)request.dst_width - 1) / ((float)drw_w - 1); 419428d7b3dSmrg request.src_scan_width = src_w * scale; 420428d7b3dSmrg } else 421428d7b3dSmrg request.src_scan_width = 1; 422428d7b3dSmrg 423428d7b3dSmrg DBG(("%s: src=(%d, %d) scan=(%d, %d)\n", 424428d7b3dSmrg __FUNCTION__, 425428d7b3dSmrg request.src_width, request.src_height, 426428d7b3dSmrg request.src_scan_width, request.src_scan_height)); 427428d7b3dSmrg 428428d7b3dSmrg if (planar) { 429428d7b3dSmrg request.flags |= I915_OVERLAY_YUV_PLANAR | I915_OVERLAY_YUV420; 430428d7b3dSmrg } else { 431428d7b3dSmrg request.flags |= I915_OVERLAY_YUV_PACKED | I915_OVERLAY_YUV422; 432428d7b3dSmrg if (frame->id == FOURCC_UYVY) 433428d7b3dSmrg request.flags |= I915_OVERLAY_Y_SWAP; 434428d7b3dSmrg } 435428d7b3dSmrg 436428d7b3dSmrg DBG(("%s: flags=%x\n", __FUNCTION__, request.flags)); 437428d7b3dSmrg 438428d7b3dSmrg if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_PUT_IMAGE, &request)) { 439428d7b3dSmrg DBG(("%s: Putimage failed\n", __FUNCTION__)); 440428d7b3dSmrg return false; 441428d7b3dSmrg } 442428d7b3dSmrg 443428d7b3dSmrg if (video->bo[0] != frame->bo) { 444428d7b3dSmrg if (video->bo[0]) 445428d7b3dSmrg kgem_bo_destroy(&sna->kgem, video->bo[0]); 446428d7b3dSmrg video->bo[0] = kgem_bo_reference(frame->bo); 447428d7b3dSmrg } 448428d7b3dSmrg 449428d7b3dSmrg return true; 450428d7b3dSmrg} 451428d7b3dSmrg 452428d7b3dSmrgstatic int 453428d7b3dSmrgsna_video_overlay_put_image(ddPutImage_ARGS) 454428d7b3dSmrg{ 455428d7b3dSmrg struct sna_video *video = port->devPriv.ptr; 456428d7b3dSmrg struct sna *sna = video->sna; 457428d7b3dSmrg struct sna_video_frame frame; 458428d7b3dSmrg xf86CrtcPtr crtc; 459428d7b3dSmrg BoxRec dstBox; 460428d7b3dSmrg RegionRec clip; 461428d7b3dSmrg int ret; 462428d7b3dSmrg 463428d7b3dSmrg DBG(("%s: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d), width %d, height %d\n", 464428d7b3dSmrg __FUNCTION__, 465428d7b3dSmrg src_x, src_y, src_w, src_h, drw_x, 466428d7b3dSmrg drw_y, drw_w, drw_h, width, height)); 467428d7b3dSmrg 468428d7b3dSmrg /* If dst width and height are less than 1/8th the src size, the 469428d7b3dSmrg * src/dst scale factor becomes larger than 8 and doesn't fit in 470428d7b3dSmrg * the scale register. */ 471428d7b3dSmrg if (src_w >= (drw_w * 8)) 472428d7b3dSmrg drw_w = src_w / 7; 473428d7b3dSmrg 474428d7b3dSmrg if (src_h >= (drw_h * 8)) 475428d7b3dSmrg drw_h = src_h / 7; 476428d7b3dSmrg 477428d7b3dSmrg clip.extents.x1 = draw->x + drw_x; 478428d7b3dSmrg clip.extents.y1 = draw->y + drw_y; 479428d7b3dSmrg clip.extents.x2 = clip.extents.x1 + drw_w; 480428d7b3dSmrg clip.extents.y2 = clip.extents.y1 + drw_h; 481428d7b3dSmrg clip.data = NULL; 482428d7b3dSmrg 483428d7b3dSmrg DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop)); 484428d7b3dSmrg if (!video->AlwaysOnTop) 485428d7b3dSmrg RegionIntersect(&clip, &clip, gc->pCompositeClip); 486428d7b3dSmrg if (box_empty(&clip.extents)) 487428d7b3dSmrg goto invisible; 488428d7b3dSmrg 489428d7b3dSmrg DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n", 490428d7b3dSmrg __FUNCTION__, 491428d7b3dSmrg src_x, src_y, src_w, src_h, 492428d7b3dSmrg drw_x, drw_y, drw_w, drw_h, 493428d7b3dSmrg format->id, width, height, sync)); 494428d7b3dSmrg 495428d7b3dSmrg DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__, 496428d7b3dSmrg region_num_rects(&clip), 497428d7b3dSmrg clip.extents.x1, clip.extents.y1, 498428d7b3dSmrg clip.extents.x2, clip.extents.y2)); 499428d7b3dSmrg 500428d7b3dSmrg sna_video_frame_init(video, format->id, width, height, &frame); 501428d7b3dSmrg 502428d7b3dSmrg if (!sna_video_clip_helper(video, &frame, &crtc, &dstBox, 503428d7b3dSmrg src_x, src_y, draw->x + drw_x, draw->y + drw_y, 504428d7b3dSmrg src_w, src_h, drw_w, drw_h, 505428d7b3dSmrg &clip)) 506428d7b3dSmrg goto invisible; 507428d7b3dSmrg 508428d7b3dSmrg if (!crtc) 509428d7b3dSmrg goto invisible; 510428d7b3dSmrg 511428d7b3dSmrg /* overlay can't handle rotation natively, store it for the copy func */ 512428d7b3dSmrg sna_video_frame_set_rotation(video, &frame, crtc->rotation); 513428d7b3dSmrg 514428d7b3dSmrg if (xvmc_passthrough(format->id)) { 515428d7b3dSmrg DBG(("%s: using passthough, name=%d\n", 516428d7b3dSmrg __FUNCTION__, *(uint32_t *)buf)); 517428d7b3dSmrg 518428d7b3dSmrg if (*(uint32_t*)buf == 0) 519428d7b3dSmrg goto invisible; 520428d7b3dSmrg 521428d7b3dSmrg frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf); 522428d7b3dSmrg if (frame.bo == NULL) { 523428d7b3dSmrg DBG(("%s: failed to open bo\n", __FUNCTION__)); 524428d7b3dSmrg return BadAlloc; 525428d7b3dSmrg } 526428d7b3dSmrg 527428d7b3dSmrg if (kgem_bo_size(frame.bo) < frame.size) { 528428d7b3dSmrg DBG(("%s: bo size=%d, expected=%d\n", 529428d7b3dSmrg __FUNCTION__, kgem_bo_size(frame.bo), frame.size)); 530428d7b3dSmrg kgem_bo_destroy(&sna->kgem, frame.bo); 531428d7b3dSmrg return BadAlloc; 532428d7b3dSmrg } 533428d7b3dSmrg 534428d7b3dSmrg frame.image.x1 = 0; 535428d7b3dSmrg frame.image.y1 = 0; 536428d7b3dSmrg frame.image.x2 = frame.width; 537428d7b3dSmrg frame.image.y2 = frame.height; 538428d7b3dSmrg } else { 539428d7b3dSmrg frame.bo = sna_video_buffer(video, &frame); 540428d7b3dSmrg if (frame.bo == NULL) { 541428d7b3dSmrg DBG(("%s: failed to allocate video bo\n", __FUNCTION__)); 542428d7b3dSmrg return BadAlloc; 543428d7b3dSmrg } 544428d7b3dSmrg 545428d7b3dSmrg if (!sna_video_copy_data(video, &frame, buf)) { 546428d7b3dSmrg DBG(("%s: failed to copy video data\n", __FUNCTION__)); 547428d7b3dSmrg return BadAlloc; 548428d7b3dSmrg } 549428d7b3dSmrg } 550428d7b3dSmrg 551428d7b3dSmrg ret = Success; 552428d7b3dSmrg if (sna_video_overlay_show 553428d7b3dSmrg (sna, video, &frame, crtc, &dstBox, src_w, src_h, drw_w, drw_h)) { 554428d7b3dSmrg //xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip); 555428d7b3dSmrg if (!video->AlwaysOnTop && !RegionEqual(&video->clip, &clip) && 556428d7b3dSmrg sna_blt_fill_boxes(sna, GXcopy, 557428d7b3dSmrg __sna_pixmap_get_bo(sna->front), 558428d7b3dSmrg sna->front->drawable.bitsPerPixel, 559428d7b3dSmrg video->color_key, 560428d7b3dSmrg region_rects(&clip), 561428d7b3dSmrg region_num_rects(&clip))) 562428d7b3dSmrg RegionCopy(&video->clip, &clip); 563428d7b3dSmrg sna_window_set_port((WindowPtr)draw, port); 564428d7b3dSmrg } else { 565428d7b3dSmrg DBG(("%s: failed to show video frame\n", __FUNCTION__)); 566428d7b3dSmrg ret = BadAlloc; 567428d7b3dSmrg } 568428d7b3dSmrg 569428d7b3dSmrg frame.bo->domain = DOMAIN_NONE; 570428d7b3dSmrg if (xvmc_passthrough(format->id)) 571428d7b3dSmrg kgem_bo_destroy(&sna->kgem, frame.bo); 572428d7b3dSmrg else 573428d7b3dSmrg sna_video_buffer_fini(video); 574428d7b3dSmrg 575428d7b3dSmrg return ret; 576428d7b3dSmrg 577428d7b3dSmrginvisible: 578428d7b3dSmrg /* 579428d7b3dSmrg * If the video isn't visible on any CRTC, turn it off 580428d7b3dSmrg */ 581428d7b3dSmrg#if XORG_XV_VERSION < 2 582428d7b3dSmrg sna_video_overlay_stop(client, port, draw); 583428d7b3dSmrg#else 584428d7b3dSmrg sna_video_overlay_stop(port, draw); 585428d7b3dSmrg#endif 586428d7b3dSmrg return Success; 587428d7b3dSmrg} 588428d7b3dSmrg 589428d7b3dSmrgstatic int 590428d7b3dSmrgsna_video_overlay_query(ddQueryImageAttributes_ARGS) 591428d7b3dSmrg{ 592428d7b3dSmrg struct sna_video *video = port->devPriv.ptr; 593428d7b3dSmrg struct sna_video_frame frame; 594428d7b3dSmrg struct sna *sna = video->sna; 595428d7b3dSmrg int size, tmp; 596428d7b3dSmrg 597428d7b3dSmrg DBG(("%s: w is %d, h is %d\n", __FUNCTION__, *w, *h)); 598428d7b3dSmrg 599428d7b3dSmrg if (sna->kgem.gen < 021) { 600428d7b3dSmrg if (*w > IMAGE_MAX_WIDTH_LEGACY) 601428d7b3dSmrg *w = IMAGE_MAX_WIDTH_LEGACY; 602428d7b3dSmrg if (*h > IMAGE_MAX_HEIGHT_LEGACY) 603428d7b3dSmrg *h = IMAGE_MAX_HEIGHT_LEGACY; 604428d7b3dSmrg } else { 605428d7b3dSmrg if (*w > IMAGE_MAX_WIDTH) 606428d7b3dSmrg *w = IMAGE_MAX_WIDTH; 607428d7b3dSmrg if (*h > IMAGE_MAX_HEIGHT) 608428d7b3dSmrg *h = IMAGE_MAX_HEIGHT; 609428d7b3dSmrg } 610428d7b3dSmrg 611428d7b3dSmrg *w = (*w + 1) & ~1; 612428d7b3dSmrg if (offsets) 613428d7b3dSmrg offsets[0] = 0; 614428d7b3dSmrg 615428d7b3dSmrg switch (format->id) { 616428d7b3dSmrg case FOURCC_XVMC: 617428d7b3dSmrg *h = (*h + 1) & ~1; 618428d7b3dSmrg sna_video_frame_init(video, format->id, *w, *h, &frame); 619428d7b3dSmrg sna_video_frame_set_rotation(video, &frame, RR_Rotate_0); 620428d7b3dSmrg size = sizeof(uint32_t); 621428d7b3dSmrg if (pitches) { 622428d7b3dSmrg pitches[0] = frame.pitch[1]; 623428d7b3dSmrg pitches[1] = frame.pitch[0]; 624428d7b3dSmrg pitches[2] = frame.pitch[0]; 625428d7b3dSmrg } 626428d7b3dSmrg if (offsets) { 627428d7b3dSmrg offsets[1] = frame.UBufOffset; 628428d7b3dSmrg offsets[2] = frame.VBufOffset; 629428d7b3dSmrg } 630428d7b3dSmrg break; 631428d7b3dSmrg 632428d7b3dSmrg /* IA44 is for XvMC only */ 633428d7b3dSmrg case FOURCC_IA44: 634428d7b3dSmrg case FOURCC_AI44: 635428d7b3dSmrg if (pitches) 636428d7b3dSmrg pitches[0] = *w; 637428d7b3dSmrg size = *w * *h; 638428d7b3dSmrg break; 639428d7b3dSmrg case FOURCC_YV12: 640428d7b3dSmrg case FOURCC_I420: 641428d7b3dSmrg *h = (*h + 1) & ~1; 642428d7b3dSmrg size = (*w + 3) & ~3; 643428d7b3dSmrg if (pitches) 644428d7b3dSmrg pitches[0] = size; 645428d7b3dSmrg size *= *h; 646428d7b3dSmrg if (offsets) 647428d7b3dSmrg offsets[1] = size; 648428d7b3dSmrg tmp = ((*w >> 1) + 3) & ~3; 649428d7b3dSmrg if (pitches) 650428d7b3dSmrg pitches[1] = pitches[2] = tmp; 651428d7b3dSmrg tmp *= (*h >> 1); 652428d7b3dSmrg size += tmp; 653428d7b3dSmrg if (offsets) 654428d7b3dSmrg offsets[2] = size; 655428d7b3dSmrg size += tmp; 656428d7b3dSmrg#if 0 657428d7b3dSmrg if (pitches) 658428d7b3dSmrg ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n", 659428d7b3dSmrg pitches[0], pitches[1], pitches[2]); 660428d7b3dSmrg if (offsets) 661428d7b3dSmrg ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1], 662428d7b3dSmrg offsets[2]); 663428d7b3dSmrg if (offsets) 664428d7b3dSmrg ErrorF("size is %d\n", size); 665428d7b3dSmrg#endif 666428d7b3dSmrg break; 667428d7b3dSmrg case FOURCC_UYVY: 668428d7b3dSmrg case FOURCC_YUY2: 669428d7b3dSmrg default: 670428d7b3dSmrg size = *w << 1; 671428d7b3dSmrg if (pitches) 672428d7b3dSmrg pitches[0] = size; 673428d7b3dSmrg size *= *h; 674428d7b3dSmrg break; 675428d7b3dSmrg } 676428d7b3dSmrg 677428d7b3dSmrg return size; 678428d7b3dSmrg} 679428d7b3dSmrg 680428d7b3dSmrgstatic int sna_video_overlay_color_key(struct sna *sna) 681428d7b3dSmrg{ 682428d7b3dSmrg ScrnInfoPtr scrn = sna->scrn; 683428d7b3dSmrg int color_key; 684428d7b3dSmrg 685428d7b3dSmrg if (xf86GetOptValInteger(sna->Options, OPTION_VIDEO_KEY, 686428d7b3dSmrg &color_key)) { 687428d7b3dSmrg } else if (xf86GetOptValInteger(sna->Options, OPTION_COLOR_KEY, 688428d7b3dSmrg &color_key)) { 689428d7b3dSmrg } else { 690428d7b3dSmrg color_key = 691428d7b3dSmrg (1 << scrn->offset.red) | 692428d7b3dSmrg (1 << scrn->offset.green) | 693428d7b3dSmrg (((scrn->mask.blue >> scrn->offset.blue) - 1) << scrn->offset.blue); 694428d7b3dSmrg } 695428d7b3dSmrg 696428d7b3dSmrg return color_key & ((1 << scrn->depth) - 1); 697428d7b3dSmrg} 698428d7b3dSmrg 699428d7b3dSmrgvoid sna_video_overlay_setup(struct sna *sna, ScreenPtr screen) 700428d7b3dSmrg{ 701428d7b3dSmrg XvAdaptorPtr adaptor; 702428d7b3dSmrg struct sna_video *video; 703428d7b3dSmrg XvPortPtr port; 704428d7b3dSmrg 705428d7b3dSmrg if (sna->flags & SNA_IS_HOSTED) 706428d7b3dSmrg return; 707428d7b3dSmrg 708428d7b3dSmrg if (!sna_has_overlay(sna)) 709428d7b3dSmrg return; 710428d7b3dSmrg 711428d7b3dSmrg DBG(("%s()\n", __FUNCTION__)); 712428d7b3dSmrg 713428d7b3dSmrg adaptor = sna_xv_adaptor_alloc(sna); 714428d7b3dSmrg if (adaptor == NULL) 715428d7b3dSmrg return; 716428d7b3dSmrg 717428d7b3dSmrg video = calloc(1, sizeof(*video)); 718428d7b3dSmrg port = calloc(1, sizeof(*port)); 719428d7b3dSmrg if (video == NULL || port == NULL) { 720428d7b3dSmrg free(video); 721428d7b3dSmrg free(port); 722428d7b3dSmrg sna->xv.num_adaptors--; 723428d7b3dSmrg return; 724428d7b3dSmrg } 725428d7b3dSmrg 726428d7b3dSmrg adaptor->type = XvInputMask | XvImageMask; 727428d7b3dSmrg adaptor->pScreen = screen; 728428d7b3dSmrg adaptor->name = (char *)"Intel(R) Video Overlay"; 729428d7b3dSmrg adaptor->nEncodings = 1; 730428d7b3dSmrg adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec)); 731428d7b3dSmrg adaptor->pEncodings[0].id = 0; 732428d7b3dSmrg adaptor->pEncodings[0].pScreen = screen; 733428d7b3dSmrg adaptor->pEncodings[0].name = (char *)"XV_IMAGE"; 734428d7b3dSmrg adaptor->pEncodings[0].width = sna->kgem.gen < 021 ? IMAGE_MAX_WIDTH_LEGACY : IMAGE_MAX_WIDTH; 735428d7b3dSmrg adaptor->pEncodings[0].height = sna->kgem.gen < 021 ? IMAGE_MAX_HEIGHT_LEGACY : IMAGE_MAX_HEIGHT; 736428d7b3dSmrg adaptor->pEncodings[0].rate.numerator = 1; 737428d7b3dSmrg adaptor->pEncodings[0].rate.denominator = 1; 738428d7b3dSmrg adaptor->pFormats = Formats; 739428d7b3dSmrg adaptor->nFormats = sna_xv_fixup_formats(screen, Formats, 740428d7b3dSmrg ARRAY_SIZE(Formats)); 741428d7b3dSmrg adaptor->nAttributes = NUM_ATTRIBUTES; 742428d7b3dSmrg if (HAS_GAMMA(sna)) 743428d7b3dSmrg adaptor->nAttributes += GAMMA_ATTRIBUTES; 744428d7b3dSmrg adaptor->pAttributes = (XvAttributeRec *)Attributes; 745428d7b3dSmrg adaptor->nImages = ARRAY_SIZE(Images); 746428d7b3dSmrg adaptor->pImages = (XvImageRec *)Images; 747428d7b3dSmrg#if XORG_XV_VERSION < 2 748428d7b3dSmrg adaptor->ddAllocatePort = sna_xv_alloc_port; 749428d7b3dSmrg adaptor->ddFreePort = sna_xv_free_port; 750428d7b3dSmrg#endif 751428d7b3dSmrg adaptor->ddPutVideo = NULL; 752428d7b3dSmrg adaptor->ddPutStill = NULL; 753428d7b3dSmrg adaptor->ddGetVideo = NULL; 754428d7b3dSmrg adaptor->ddGetStill = NULL; 755428d7b3dSmrg adaptor->ddStopVideo = sna_video_overlay_stop; 756428d7b3dSmrg adaptor->ddSetPortAttribute = sna_video_overlay_set_attribute; 757428d7b3dSmrg adaptor->ddGetPortAttribute = sna_video_overlay_get_attribute; 758428d7b3dSmrg adaptor->ddQueryBestSize = sna_video_overlay_best_size; 759428d7b3dSmrg adaptor->ddPutImage = sna_video_overlay_put_image; 760428d7b3dSmrg adaptor->ddQueryImageAttributes = sna_video_overlay_query; 761428d7b3dSmrg 762428d7b3dSmrg adaptor->nPorts = 1; 763428d7b3dSmrg adaptor->pPorts = port; 764428d7b3dSmrg adaptor->base_id = port->id = FakeClientID(0); 765428d7b3dSmrg AddResource(port->id, XvGetRTPort(), port); 766428d7b3dSmrg 767428d7b3dSmrg port->pAdaptor = adaptor; 768428d7b3dSmrg port->pNotify = NULL; 769428d7b3dSmrg port->pDraw = NULL; 770428d7b3dSmrg port->client = NULL; 771428d7b3dSmrg port->grab.client = NULL; 772428d7b3dSmrg port->time = currentTime; 773428d7b3dSmrg port->devPriv.ptr = video; 774428d7b3dSmrg 775428d7b3dSmrg video->sna = sna; 776428d7b3dSmrg if (sna->kgem.gen >= 040) 777428d7b3dSmrg /* Actually the alignment is 64 bytes, too. But the 778428d7b3dSmrg * stride must be at least 512 bytes. Take the easy fix 779428d7b3dSmrg * and align on 512 bytes unconditionally. */ 780428d7b3dSmrg video->alignment = 512; 781428d7b3dSmrg else if (sna->kgem.gen < 021) 782428d7b3dSmrg /* Harsh, errata on these chipsets limit the stride 783428d7b3dSmrg * to be a multiple of 256 bytes. 784428d7b3dSmrg */ 785428d7b3dSmrg video->alignment = 256; 786428d7b3dSmrg else 787428d7b3dSmrg video->alignment = 64; 788428d7b3dSmrg video->color_key = sna_video_overlay_color_key(sna); 789428d7b3dSmrg video->brightness = -19; /* (255/219) * -16 */ 790428d7b3dSmrg video->contrast = 75; /* 255/219 * 64 */ 791428d7b3dSmrg video->saturation = 146; /* 128/112 * 128 */ 792428d7b3dSmrg video->desired_crtc = NULL; 793428d7b3dSmrg video->gamma5 = 0xc0c0c0; 794428d7b3dSmrg video->gamma4 = 0x808080; 795428d7b3dSmrg video->gamma3 = 0x404040; 796428d7b3dSmrg video->gamma2 = 0x202020; 797428d7b3dSmrg video->gamma1 = 0x101010; 798428d7b3dSmrg video->gamma0 = 0x080808; 799428d7b3dSmrg RegionNull(&video->clip); 800428d7b3dSmrg 801428d7b3dSmrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 802428d7b3dSmrg xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 803428d7b3dSmrg xvContrast = MAKE_ATOM("XV_CONTRAST"); 804428d7b3dSmrg xvSaturation = MAKE_ATOM("XV_SATURATION"); 805428d7b3dSmrg 806428d7b3dSmrg /* Allow the pipe to be switched from pipe A to B when in clone mode */ 807428d7b3dSmrg xvPipe = MAKE_ATOM("XV_PIPE"); 808428d7b3dSmrg xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP"); 809428d7b3dSmrg 810428d7b3dSmrg if (HAS_GAMMA(sna)) { 811428d7b3dSmrg xvGamma0 = MAKE_ATOM("XV_GAMMA0"); 812428d7b3dSmrg xvGamma1 = MAKE_ATOM("XV_GAMMA1"); 813428d7b3dSmrg xvGamma2 = MAKE_ATOM("XV_GAMMA2"); 814428d7b3dSmrg xvGamma3 = MAKE_ATOM("XV_GAMMA3"); 815428d7b3dSmrg xvGamma4 = MAKE_ATOM("XV_GAMMA4"); 816428d7b3dSmrg xvGamma5 = MAKE_ATOM("XV_GAMMA5"); 817428d7b3dSmrg } 818428d7b3dSmrg 819428d7b3dSmrg sna_video_overlay_update_attrs(video); 820428d7b3dSmrg 821428d7b3dSmrg DBG(("%s: '%s' initialized %d ports\n", __FUNCTION__, adaptor->name, adaptor->nPorts)); 822428d7b3dSmrg} 823