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 "intel_options.h" 35 36#include <xf86drm.h> 37#include <xf86xv.h> 38#include <xf86Crtc.h> 39#include <X11/extensions/Xv.h> 40#include <fourcc.h> 41#include <i915_drm.h> 42#include <errno.h> 43 44#define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) 45#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */ 46#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ 47#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ 48#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ 49 50#define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane) 51struct local_mode_set_plane { 52 uint32_t plane_id; 53 uint32_t crtc_id; 54 uint32_t fb_id; /* fb object contains surface format type */ 55 uint32_t flags; 56 57 /* Signed dest location allows it to be partially off screen */ 58 int32_t crtc_x, crtc_y; 59 uint32_t crtc_w, crtc_h; 60 61 /* Source values are 16.16 fixed point */ 62 uint32_t src_x, src_y; 63 uint32_t src_h, src_w; 64}; 65 66#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true) 67 68static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank; 69 70static XvFormatRec formats[] = { {15}, {16}, {24} }; 71static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_RGB888, XVMC_RGB565 }; 72static const XvAttributeRec attribs[] = { 73 { XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_COLORKEY" }, 74 { XvSettable | XvGettable, 0, 1, (char *)"XV_ALWAYS_ON_TOP" }, 75}; 76 77static int sna_video_sprite_stop(ddStopVideo_ARGS) 78{ 79 struct sna_video *video = port->devPriv.ptr; 80 struct local_mode_set_plane s; 81 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(video->sna->scrn); 82 int i; 83 84 for (i = 0; i < config->num_crtc; i++) { 85 xf86CrtcPtr crtc = config->crtc[i]; 86 int pipe; 87 88 if (sna_crtc_id(crtc) == 0) 89 break; 90 91 pipe = sna_crtc_to_pipe(crtc); 92 if (video->bo[pipe] == NULL) 93 continue; 94 95 memset(&s, 0, sizeof(s)); 96 s.plane_id = sna_crtc_to_sprite(crtc); 97 if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) 98 xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR, 99 "failed to disable plane\n"); 100 101 if (video->bo[pipe]) 102 kgem_bo_destroy(&video->sna->kgem, video->bo[pipe]); 103 video->bo[pipe] = NULL; 104 } 105 106 sna_window_set_port((WindowPtr)draw, NULL); 107 108 return Success; 109} 110 111static int sna_video_sprite_set_attr(ddSetPortAttribute_ARGS) 112{ 113 struct sna_video *video = port->devPriv.ptr; 114 115 if (attribute == xvColorKey) { 116 video->color_key_changed = ~0; 117 video->color_key = value; 118 RegionEmpty(&video->clip); 119 DBG(("COLORKEY = %ld\n", (long)value)); 120 } else if (attribute == xvSyncToVblank) { 121 DBG(("%s: SYNC_TO_VBLANK: %d -> %d\n", __FUNCTION__, 122 video->SyncToVblank, !!value)); 123 video->SyncToVblank = !!value; 124 } else if (attribute == xvAlwaysOnTop) { 125 DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__, 126 video->AlwaysOnTop, !!value)); 127 video->color_key_changed = ~0; 128 video->AlwaysOnTop = !!value; 129 } else 130 return BadMatch; 131 132 return Success; 133} 134 135static int sna_video_sprite_get_attr(ddGetPortAttribute_ARGS) 136{ 137 struct sna_video *video = port->devPriv.ptr; 138 139 if (attribute == xvColorKey) 140 *value = video->color_key; 141 else if (attribute == xvAlwaysOnTop) 142 *value = video->AlwaysOnTop; 143 else if (attribute == xvSyncToVblank) 144 *value = video->SyncToVblank; 145 else 146 return BadMatch; 147 148 return Success; 149} 150 151static int sna_video_sprite_best_size(ddQueryBestSize_ARGS) 152{ 153 struct sna_video *video = port->devPriv.ptr; 154 struct sna *sna = video->sna; 155 156 if (sna->kgem.gen >= 075) { 157 *p_w = vid_w; 158 *p_h = vid_h; 159 } else { 160 *p_w = drw_w; 161 *p_h = drw_h; 162 } 163 164 return Success; 165} 166 167static void 168update_dst_box_to_crtc_coords(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox) 169{ 170 ScrnInfoPtr scrn = sna->scrn; 171 int tmp; 172 173 switch (crtc->rotation & 0xf) { 174 case RR_Rotate_0: 175 dstBox->x1 -= crtc->x; 176 dstBox->x2 -= crtc->x; 177 dstBox->y1 -= crtc->y; 178 dstBox->y2 -= crtc->y; 179 break; 180 181 case RR_Rotate_90: 182 tmp = dstBox->x1; 183 dstBox->x1 = dstBox->y1 - crtc->x; 184 dstBox->y1 = scrn->virtualX - tmp - crtc->y; 185 tmp = dstBox->x2; 186 dstBox->x2 = dstBox->y2 - crtc->x; 187 dstBox->y2 = scrn->virtualX - tmp - crtc->y; 188 tmp = dstBox->y1; 189 dstBox->y1 = dstBox->y2; 190 dstBox->y2 = tmp; 191 break; 192 193 case RR_Rotate_180: 194 tmp = dstBox->x1; 195 dstBox->x1 = scrn->virtualX - dstBox->x2 - crtc->x; 196 dstBox->x2 = scrn->virtualX - tmp - crtc->x; 197 tmp = dstBox->y1; 198 dstBox->y1 = scrn->virtualY - dstBox->y2 - crtc->y; 199 dstBox->y2 = scrn->virtualY - tmp - crtc->y; 200 break; 201 202 case RR_Rotate_270: 203 tmp = dstBox->x1; 204 dstBox->x1 = scrn->virtualY - dstBox->y1 - crtc->x; 205 dstBox->y1 = tmp - crtc->y; 206 tmp = dstBox->x2; 207 dstBox->x2 = scrn->virtualY - dstBox->y2 - crtc->x; 208 dstBox->y2 = tmp - crtc->y; 209 tmp = dstBox->x1; 210 dstBox->x1 = dstBox->x2; 211 dstBox->x2 = tmp; 212 break; 213 } 214} 215 216static bool 217sna_video_sprite_show(struct sna *sna, 218 struct sna_video *video, 219 struct sna_video_frame *frame, 220 xf86CrtcPtr crtc, 221 BoxPtr dstBox) 222{ 223 struct local_mode_set_plane s; 224 int pipe = sna_crtc_to_pipe(crtc); 225 226 /* XXX handle video spanning multiple CRTC */ 227 228 VG_CLEAR(s); 229 s.plane_id = sna_crtc_to_sprite(crtc); 230 231#define DRM_I915_SET_SPRITE_COLORKEY 0x2b 232#define LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct local_intel_sprite_colorkey) 233#define LOCAL_IOCTL_MODE_ADDFB2 DRM_IOWR(0xb8, struct local_mode_fb_cmd2) 234 235 if (video->color_key_changed & (1 << pipe) && video->has_color_key) { 236 struct local_intel_sprite_colorkey { 237 uint32_t plane_id; 238 uint32_t min_value; 239 uint32_t channel_mask; 240 uint32_t max_value; 241 uint32_t flags; 242 } set; 243 244 DBG(("%s: updating color key: %x\n", 245 __FUNCTION__, video->color_key)); 246 247 set.plane_id = s.plane_id; 248 set.min_value = video->color_key; 249 set.max_value = video->color_key; /* not used for destkey */ 250 set.channel_mask = 0x7 << 24 | 0xff << 16 | 0xff << 8 | 0xff << 0; 251 set.flags = 0; 252 if (!video->AlwaysOnTop) 253 set.flags |= 1 << 1; /* COLORKEY_DESTINATION */ 254 255 if (drmIoctl(sna->kgem.fd, 256 LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY, 257 &set)) { 258 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, 259 "failed to update color key, disabling future updates\n"); 260 video->has_color_key = false; 261 } 262 263 video->color_key_changed &= ~(1 << pipe); 264 } 265 266 if (video->bo[pipe] == frame->bo) 267 return true; 268 269 update_dst_box_to_crtc_coords(sna, crtc, dstBox); 270 if (frame->rotation & (RR_Rotate_90 | RR_Rotate_270)) { 271 int tmp = frame->width; 272 frame->width = frame->height; 273 frame->height = tmp; 274 } 275 276 if (frame->bo->delta == 0) { 277 struct local_mode_fb_cmd2 { 278 uint32_t fb_id; 279 uint32_t width, height; 280 uint32_t pixel_format; 281 uint32_t flags; 282 283 uint32_t handles[4]; 284 uint32_t pitches[4]; /* pitch for each plane */ 285 uint32_t offsets[4]; /* offset of each plane */ 286 } f; 287 bool purged = true; 288 289 memset(&f, 0, sizeof(f)); 290 f.width = frame->width; 291 f.height = frame->height; 292 f.handles[0] = frame->bo->handle; 293 f.pitches[0] = frame->pitch[0]; 294 295 switch (frame->id) { 296 case FOURCC_RGB565: 297 f.pixel_format = DRM_FORMAT_RGB565; 298 purged = sna->scrn->depth != 16; 299 break; 300 case FOURCC_RGB888: 301 f.pixel_format = DRM_FORMAT_XRGB8888; 302 purged = sna->scrn->depth != 24; 303 break; 304 case FOURCC_UYVY: 305 f.pixel_format = DRM_FORMAT_UYVY; 306 break; 307 case FOURCC_YUY2: 308 default: 309 f.pixel_format = DRM_FORMAT_YUYV; 310 break; 311 } 312 313 DBG(("%s: creating new fb for handle=%d, width=%d, height=%d, stride=%d, format=%x\n", 314 __FUNCTION__, frame->bo->handle, frame->width, frame->height, 315 f.pitches[0], f.pixel_format)); 316 317 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_ADDFB2, &f)) { 318 ERR(("%s: ADDFB2 failed, errno=%d\n", __FUNCTION__, errno)); 319 xf86DrvMsg(sna->scrn->scrnIndex, 320 X_ERROR, "failed to add fb, unable to update video\n"); 321 return false; 322 } 323 324 frame->bo->delta = f.fb_id; 325 326 frame->bo->scanout = true; 327 /* Don't allow the scanout to be cached if not suitable for front */ 328 frame->bo->purged = purged; 329 } 330 331 assert(frame->bo->scanout); 332 assert(frame->bo->delta); 333 334 s.crtc_id = sna_crtc_id(crtc); 335 s.fb_id = frame->bo->delta; 336 s.flags = 0; 337 s.crtc_x = dstBox->x1; 338 s.crtc_y = dstBox->y1; 339 s.crtc_w = dstBox->x2 - dstBox->x1; 340 s.crtc_h = dstBox->y2 - dstBox->y1; 341 s.src_x = 0; 342 s.src_y = 0; 343 s.src_w = (frame->image.x2 - frame->image.x1) << 16; 344 s.src_h = (frame->image.y2 - frame->image.y1) << 16; 345 346 DBG(("%s: updating crtc=%d, plane=%d, handle=%d [fb %d], dst=(%d,%d)x(%d,%d), src=(%d,%d)x(%d,%d)\n", 347 __FUNCTION__, s.crtc_id, s.plane_id, frame->bo->handle, s.fb_id, 348 s.crtc_x, s.crtc_y, s.crtc_w, s.crtc_h, 349 s.src_x >> 16, s.src_y >> 16, s.src_w >> 16, s.src_h >> 16)); 350 351 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) { 352 DBG(("SET_PLANE failed: ret=%d\n", errno)); 353 memset(&s, 0, sizeof(s)); 354 s.plane_id = video->plane; 355 (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s); 356 if (video->bo[pipe]) { 357 kgem_bo_destroy(&sna->kgem, video->bo[pipe]); 358 video->bo[pipe] = NULL; 359 } 360 return false; 361 } 362 363 frame->bo->domain = DOMAIN_NONE; 364 365 if (video->bo[pipe]) 366 kgem_bo_destroy(&sna->kgem, video->bo[pipe]); 367 video->bo[pipe] = kgem_bo_reference(frame->bo); 368 return true; 369} 370 371static int sna_video_sprite_put_image(ddPutImage_ARGS) 372{ 373 struct sna_video *video = port->devPriv.ptr; 374 struct sna *sna = video->sna; 375 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 376 RegionRec clip; 377 int ret, i; 378 379 clip.extents.x1 = draw->x + drw_x; 380 clip.extents.y1 = draw->y + drw_y; 381 clip.extents.x2 = clip.extents.x1 + drw_w; 382 clip.extents.y2 = clip.extents.y1 + drw_h; 383 clip.data = NULL; 384 385 DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop)); 386 if (!video->AlwaysOnTop) 387 RegionIntersect(&clip, &clip, gc->pCompositeClip); 388 389 DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n", 390 __FUNCTION__, 391 src_x, src_y, src_w, src_h, 392 drw_x, drw_y, drw_w, drw_h, 393 format->id, width, height, sync)); 394 395 DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__, 396 region_num_rects(&clip), 397 clip.extents.x1, clip.extents.y1, 398 clip.extents.x2, clip.extents.y2)); 399 400 if (RegionNil(&clip)) { 401 ret = Success; 402 goto err; 403 } 404 405 for (i = 0; i < config->num_crtc; i++) { 406 xf86CrtcPtr crtc = config->crtc[i]; 407 struct sna_video_frame frame; 408 int pipe; 409 INT32 x1, x2, y1, y2; 410 BoxRec dst; 411 RegionRec reg; 412 Rotation rotation; 413 414 if (sna_crtc_id(crtc) == 0) 415 break; 416 417 pipe = sna_crtc_to_pipe(crtc); 418 419 sna_video_frame_init(video, format->id, width, height, &frame); 420 421 reg.extents = crtc->bounds; 422 reg.data = NULL; 423 RegionIntersect(®, ®, &clip); 424 if (RegionNil(®)) { 425off: 426 if (video->bo[pipe]) { 427 struct local_mode_set_plane s; 428 memset(&s, 0, sizeof(s)); 429 s.plane_id = sna_crtc_to_sprite(crtc); 430 if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) 431 xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR, 432 "failed to disable plane\n"); 433 video->bo[pipe] = NULL; 434 } 435 continue; 436 } 437 438 x1 = src_x; 439 x2 = src_x + src_w; 440 y1 = src_y; 441 y2 = src_y + src_h; 442 443 dst = clip.extents; 444 445 ret = xf86XVClipVideoHelper(&dst, &x1, &x2, &y1, &y2, 446 ®, frame.width, frame.height); 447 RegionUninit(®); 448 if (!ret) 449 goto off; 450 451 frame.src.x1 = x1 >> 16; 452 frame.src.y1 = y1 >> 16; 453 frame.src.x2 = (x2 + 0xffff) >> 16; 454 frame.src.y2 = (y2 + 0xffff) >> 16; 455 456 frame.image.x1 = frame.src.x1 & ~1; 457 frame.image.x2 = ALIGN(frame.src.x2, 2); 458 if (is_planar_fourcc(frame.id)) { 459 frame.image.y1 = frame.src.y1 & ~1; 460 frame.image.y2 = ALIGN(frame.src.y2, 2); 461 } else { 462 frame.image.y1 = frame.src.y1; 463 frame.image.y2 = frame.src.y2; 464 } 465 466 /* if sprite can't handle rotation natively, store it for the copy func */ 467 rotation = RR_Rotate_0; 468 if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) { 469 sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0); 470 rotation = crtc->rotation; 471 } 472 sna_video_frame_set_rotation(video, &frame, rotation); 473 474 if (xvmc_passthrough(format->id)) { 475 DBG(("%s: using passthough, name=%d\n", 476 __FUNCTION__, *(uint32_t *)buf)); 477 478 if (*(uint32_t*)buf == 0) 479 goto err; 480 481 frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf); 482 if (frame.bo == NULL) { 483 ret = BadAlloc; 484 goto err; 485 } 486 487 if (kgem_bo_size(frame.bo) < frame.size) { 488 DBG(("%s: bo size=%d, expected=%d\n", 489 __FUNCTION__, kgem_bo_size(frame.bo), frame.size)); 490 kgem_bo_destroy(&sna->kgem, frame.bo); 491 ret = BadAlloc; 492 goto err; 493 } 494 495 frame.image.x1 = 0; 496 frame.image.y1 = 0; 497 frame.image.x2 = frame.width; 498 frame.image.y2 = frame.height; 499 } else { 500 frame.bo = sna_video_buffer(video, &frame); 501 if (frame.bo == NULL) { 502 DBG(("%s: failed to allocate video bo\n", __FUNCTION__)); 503 ret = BadAlloc; 504 goto err; 505 } 506 507 if (!sna_video_copy_data(video, &frame, buf)) { 508 DBG(("%s: failed to copy video data\n", __FUNCTION__)); 509 ret = BadAlloc; 510 goto err; 511 } 512 } 513 514 ret = Success; 515 if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst)) { 516 DBG(("%s: failed to show video frame\n", __FUNCTION__)); 517 ret = BadAlloc; 518 } 519 520 frame.bo->domain = DOMAIN_NONE; 521 if (xvmc_passthrough(format->id)) 522 kgem_bo_destroy(&sna->kgem, frame.bo); 523 else 524 sna_video_buffer_fini(video); 525 526 if (ret != Success) 527 goto err; 528 } 529 530 if (!video->AlwaysOnTop && !RegionEqual(&video->clip, &clip) && 531 sna_blt_fill_boxes(sna, GXcopy, 532 __sna_pixmap_get_bo(sna->front), 533 sna->front->drawable.bitsPerPixel, 534 video->color_key, 535 region_rects(&clip), 536 region_num_rects(&clip))) 537 RegionCopy(&video->clip, &clip); 538 sna_window_set_port((WindowPtr)draw, port); 539 540 return Success; 541 542err: 543#if XORG_XV_VERSION < 2 544 (void)sna_video_sprite_stop(client, port, draw); 545#else 546 (void)sna_video_sprite_stop(port, draw); 547#endif 548 return ret; 549} 550 551static int sna_video_sprite_query(ddQueryImageAttributes_ARGS) 552{ 553 struct sna_video *video = port->devPriv.ptr; 554 struct sna_video_frame frame; 555 int size; 556 557 if (*w > video->sna->mode.max_crtc_width) 558 *w = video->sna->mode.max_crtc_width; 559 if (*h > video->sna->mode.max_crtc_height) 560 *h = video->sna->mode.max_crtc_height; 561 562 if (offsets) 563 offsets[0] = 0; 564 565 switch (format->id) { 566 case FOURCC_RGB888: 567 case FOURCC_RGB565: 568 if (pitches) { 569 sna_video_frame_init(video, format->id, *w, *h, &frame); 570 sna_video_frame_set_rotation(video, &frame, RR_Rotate_0); 571 pitches[0] = frame.pitch[0]; 572 } 573 size = 4; 574 break; 575 576 default: 577 *w = (*w + 1) & ~1; 578 *h = (*h + 1) & ~1; 579 580 size = *w << 1; 581 if (pitches) 582 pitches[0] = size; 583 size *= *h; 584 break; 585 } 586 587 return size; 588} 589 590static int sna_video_sprite_color_key(struct sna *sna) 591{ 592 ScrnInfoPtr scrn = sna->scrn; 593 int color_key; 594 595 if (xf86GetOptValInteger(sna->Options, OPTION_VIDEO_KEY, 596 &color_key)) { 597 } else if (xf86GetOptValInteger(sna->Options, OPTION_COLOR_KEY, 598 &color_key)) { 599 } else { 600 color_key = 601 (1 << scrn->offset.red) | 602 (1 << scrn->offset.green) | 603 (((scrn->mask.blue >> scrn->offset.blue) - 1) << scrn->offset.blue); 604 } 605 606 return color_key & ((1 << scrn->depth) - 1); 607} 608 609static bool sna_video_has_sprites(struct sna *sna) 610{ 611 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 612 int i; 613 614 DBG(("%s: num_crtc=%d\n", __FUNCTION__, sna->mode.num_real_crtc)); 615 616 if (sna->mode.num_real_crtc == 0) 617 return false; 618 619 for (i = 0; i < sna->mode.num_real_crtc; i++) { 620 if (!sna_crtc_to_sprite(config->crtc[i])) { 621 DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_to_pipe(config->crtc[i]))); 622 return false; 623 } 624 } 625 626 DBG(("%s: yes\n", __FUNCTION__)); 627 return true; 628} 629 630void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen) 631{ 632 XvAdaptorPtr adaptor; 633 struct sna_video *video; 634 XvPortPtr port; 635 636 if (!sna_video_has_sprites(sna)) 637 return; 638 639 adaptor = sna_xv_adaptor_alloc(sna); 640 if (!adaptor) 641 return; 642 643 video = calloc(1, sizeof(*video)); 644 port = calloc(1, sizeof(*port)); 645 if (video == NULL || port == NULL) { 646 free(video); 647 free(port); 648 sna->xv.num_adaptors--; 649 return; 650 } 651 652 adaptor->type = XvInputMask | XvImageMask; 653 adaptor->pScreen = screen; 654 adaptor->name = (char *)"Intel(R) Video Sprite"; 655 adaptor->nEncodings = 1; 656 adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec)); 657 adaptor->pEncodings[0].id = 0; 658 adaptor->pEncodings[0].pScreen = screen; 659 adaptor->pEncodings[0].name = (char *)"XV_IMAGE"; 660 adaptor->pEncodings[0].width = sna->mode.max_crtc_width; 661 adaptor->pEncodings[0].height = sna->mode.max_crtc_height; 662 adaptor->pEncodings[0].rate.numerator = 1; 663 adaptor->pEncodings[0].rate.denominator = 1; 664 adaptor->pFormats = formats; 665 adaptor->nFormats = sna_xv_fixup_formats(screen, formats, 666 ARRAY_SIZE(formats)); 667 adaptor->nAttributes = ARRAY_SIZE(attribs); 668 adaptor->pAttributes = (XvAttributeRec *)attribs; 669 adaptor->pImages = (XvImageRec *)images; 670 adaptor->nImages = 3; 671 if (sna->kgem.gen == 071) 672 adaptor->nImages = 4; 673 674#if XORG_XV_VERSION < 2 675 adaptor->ddAllocatePort = sna_xv_alloc_port; 676 adaptor->ddFreePort = sna_xv_free_port; 677#endif 678 adaptor->ddPutVideo = NULL; 679 adaptor->ddPutStill = NULL; 680 adaptor->ddGetVideo = NULL; 681 adaptor->ddGetStill = NULL; 682 adaptor->ddStopVideo = sna_video_sprite_stop; 683 adaptor->ddSetPortAttribute = sna_video_sprite_set_attr; 684 adaptor->ddGetPortAttribute = sna_video_sprite_get_attr; 685 adaptor->ddQueryBestSize = sna_video_sprite_best_size; 686 adaptor->ddPutImage = sna_video_sprite_put_image; 687 adaptor->ddQueryImageAttributes = sna_video_sprite_query; 688 689 adaptor->nPorts = 1; 690 adaptor->pPorts = port; 691 692 adaptor->base_id = port->id = FakeClientID(0); 693 AddResource(port->id, XvGetRTPort(), port); 694 port->pAdaptor = adaptor; 695 port->pNotify = NULL; 696 port->pDraw = NULL; 697 port->client = NULL; 698 port->grab.client = NULL; 699 port->time = currentTime; 700 port->devPriv.ptr = video; 701 702 video->sna = sna; 703 video->alignment = 64; 704 video->color_key = sna_video_sprite_color_key(sna); 705 video->color_key_changed = ~0; 706 video->has_color_key = true; 707 video->brightness = -19; /* (255/219) * -16 */ 708 video->contrast = 75; /* 255/219 * 64 */ 709 video->saturation = 146; /* 128/112 * 128 */ 710 video->desired_crtc = NULL; 711 video->gamma5 = 0xc0c0c0; 712 video->gamma4 = 0x808080; 713 video->gamma3 = 0x404040; 714 video->gamma2 = 0x202020; 715 video->gamma1 = 0x101010; 716 video->gamma0 = 0x080808; 717 RegionNull(&video->clip); 718 video->SyncToVblank = 1; 719 720 xvColorKey = MAKE_ATOM("XV_COLORKEY"); 721 xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP"); 722 xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); 723 724 DBG(("%s: '%s' initialized %d ports\n", __FUNCTION__, adaptor->name, adaptor->nPorts)); 725} 726