intel_video.c revision 13496ba1
103b705cfSriastradh/*************************************************************************** 203b705cfSriastradh 313496ba1Ssnj Copyright 2000 Intel Corporation. All Rights Reserved. 413496ba1Ssnj 513496ba1Ssnj Permission is hereby granted, free of charge, to any person obtaining a 613496ba1Ssnj copy of this software and associated documentation files (the 713496ba1Ssnj "Software"), to deal in the Software without restriction, including 813496ba1Ssnj without limitation the rights to use, copy, modify, merge, publish, 913496ba1Ssnj distribute, sub license, and/or sell copies of the Software, and to 1013496ba1Ssnj permit persons to whom the Software is furnished to do so, subject to 1113496ba1Ssnj the following conditions: 1213496ba1Ssnj 1313496ba1Ssnj The above copyright notice and this permission notice (including the 1413496ba1Ssnj next paragraph) shall be included in all copies or substantial portions 1513496ba1Ssnj of the Software. 1613496ba1Ssnj 1713496ba1Ssnj THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1813496ba1Ssnj OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1913496ba1Ssnj MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2013496ba1Ssnj IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 2113496ba1Ssnj DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2213496ba1Ssnj OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 2303b705cfSriastradh THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2403b705cfSriastradh 2503b705cfSriastradh **************************************************************************/ 2603b705cfSriastradh 2703b705cfSriastradh/* 2813496ba1Ssnj * i830_video.c: i830/i845 Xv driver. 2903b705cfSriastradh * 3003b705cfSriastradh * Copyright © 2002 by Alan Hourihane and David Dawes 3103b705cfSriastradh * 3213496ba1Ssnj * Authors: 3303b705cfSriastradh * Alan Hourihane <alanh@tungstengraphics.com> 3403b705cfSriastradh * David Dawes <dawes@xfree86.org> 3503b705cfSriastradh * 3603b705cfSriastradh * Derived from i810 Xv driver: 3703b705cfSriastradh * 3803b705cfSriastradh * Authors of i810 code: 3903b705cfSriastradh * Jonathan Bian <jonathan.bian@intel.com> 4003b705cfSriastradh * Offscreen Images: 4103b705cfSriastradh * Matt Sottek <matthew.j.sottek@intel.com> 4203b705cfSriastradh */ 4303b705cfSriastradh 4403b705cfSriastradh/* 4503b705cfSriastradh * XXX Could support more formats. 4603b705cfSriastradh */ 4703b705cfSriastradh 4803b705cfSriastradh#ifdef HAVE_CONFIG_H 4903b705cfSriastradh#include "config.h" 5003b705cfSriastradh#endif 5103b705cfSriastradh 5203b705cfSriastradh#include <inttypes.h> 5303b705cfSriastradh#include <math.h> 5403b705cfSriastradh#include <string.h> 5503b705cfSriastradh#include <assert.h> 5603b705cfSriastradh#include <errno.h> 5703b705cfSriastradh 5842542f5fSchristos#include "xorg-server.h" 5903b705cfSriastradh#include "xf86.h" 6003b705cfSriastradh#include "xf86_OSproc.h" 6103b705cfSriastradh#include "compiler.h" 6203b705cfSriastradh#include "xf86Pci.h" 6303b705cfSriastradh#include "xf86fbman.h" 6403b705cfSriastradh#include "xf86drm.h" 6503b705cfSriastradh#include "regionstr.h" 6603b705cfSriastradh#include "randrstr.h" 6703b705cfSriastradh#include "windowstr.h" 6803b705cfSriastradh#include "damage.h" 6903b705cfSriastradh#include "intel.h" 7003b705cfSriastradh#include "intel_video.h" 7103b705cfSriastradh#include "i830_reg.h" 7203b705cfSriastradh#include "xf86xv.h" 7303b705cfSriastradh#include <X11/extensions/Xv.h> 7403b705cfSriastradh#include "dixstruct.h" 7503b705cfSriastradh#include "fourcc.h" 7603b705cfSriastradh 7703b705cfSriastradh#ifdef INTEL_XVMC 7803b705cfSriastradh#define _INTEL_XVMC_SERVER_ 7903b705cfSriastradh#include "intel_xvmc.h" 8003b705cfSriastradh#endif 8113496ba1Ssnj#include "intel_uxa.h" 8213496ba1Ssnj#include "intel_video_overlay.h" 8303b705cfSriastradh 8413496ba1SsnjAtom intel_xv_Brightness, intel_xv_Contrast, intel_xv_Saturation, intel_xv_ColorKey, intel_xv_Pipe; 8513496ba1SsnjAtom intel_xv_Gamma0, intel_xv_Gamma1, intel_xv_Gamma2, intel_xv_Gamma3, intel_xv_Gamma4, intel_xv_Gamma5; 8613496ba1SsnjAtom intel_xv_SyncToVblank; 8703b705cfSriastradh 8803b705cfSriastradh/* client libraries expect an encoding */ 8913496ba1Ssnjconst XF86VideoEncodingRec intel_xv_dummy_encoding[1] = { 9003b705cfSriastradh { 9103b705cfSriastradh 0, 9203b705cfSriastradh "XV_IMAGE", 9303b705cfSriastradh IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, 9403b705cfSriastradh {1, 1} 9503b705cfSriastradh } 9603b705cfSriastradh}; 9703b705cfSriastradh 9813496ba1SsnjXF86VideoFormatRec intel_xv_formats[NUM_FORMATS] = { 9903b705cfSriastradh {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 10003b705cfSriastradh}; 10103b705cfSriastradh 10213496ba1SsnjXF86AttributeRec intel_xv_attributes[NUM_ATTRIBUTES] = { 10303b705cfSriastradh {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 10403b705cfSriastradh {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 10503b705cfSriastradh {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}, 10603b705cfSriastradh {XvSettable | XvGettable, 0, 1023, "XV_SATURATION"}, 10703b705cfSriastradh {XvSettable | XvGettable, -1, 1, "XV_PIPE"} 10803b705cfSriastradh}; 10903b705cfSriastradh 11003b705cfSriastradh#define GAMMA_ATTRIBUTES 6 11113496ba1SsnjXF86AttributeRec intel_xv_gamma_attributes[GAMMA_ATTRIBUTES] = { 11203b705cfSriastradh {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"}, 11303b705cfSriastradh {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"}, 11403b705cfSriastradh {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"}, 11503b705cfSriastradh {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"}, 11603b705cfSriastradh {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"}, 11703b705cfSriastradh {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"} 11803b705cfSriastradh}; 11903b705cfSriastradh 12003b705cfSriastradh#ifdef INTEL_XVMC 12103b705cfSriastradh#define NUM_IMAGES 5 12203b705cfSriastradh#define XVMC_IMAGE 1 12303b705cfSriastradh#else 12403b705cfSriastradh#define NUM_IMAGES 4 12503b705cfSriastradh#define XVMC_IMAGE 0 12603b705cfSriastradh#endif 12703b705cfSriastradh 12813496ba1SsnjXF86ImageRec intel_xv_images[NUM_IMAGES] = { 12903b705cfSriastradh XVIMAGE_YUY2, 13003b705cfSriastradh XVIMAGE_YV12, 13103b705cfSriastradh XVIMAGE_I420, 13203b705cfSriastradh XVIMAGE_UYVY, 13303b705cfSriastradh#ifdef INTEL_XVMC 13403b705cfSriastradh { 13503b705cfSriastradh /* 13603b705cfSriastradh * Below, a dummy picture type that is used in XvPutImage only to do 13703b705cfSriastradh * an overlay update. Introduced for the XvMC client lib. 13803b705cfSriastradh * Defined to have a zero data size. 13903b705cfSriastradh */ 14003b705cfSriastradh FOURCC_XVMC, 14103b705cfSriastradh XvYUV, 14203b705cfSriastradh LSBFirst, 14303b705cfSriastradh {'X', 'V', 'M', 'C', 14403b705cfSriastradh 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 14503b705cfSriastradh 0x38, 0x9B, 0x71}, 14603b705cfSriastradh 12, 14703b705cfSriastradh XvPlanar, 14803b705cfSriastradh 3, 14903b705cfSriastradh 0, 0, 0, 0, 15003b705cfSriastradh 8, 8, 8, 15103b705cfSriastradh 1, 2, 2, 15203b705cfSriastradh 1, 2, 2, 15303b705cfSriastradh {'Y', 'V', 'U', 15403b705cfSriastradh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15503b705cfSriastradh 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 15603b705cfSriastradh XvTopToBottom}, 15703b705cfSriastradh#endif 15803b705cfSriastradh}; 15903b705cfSriastradh 16013496ba1Ssnjvoid intel_video_init(ScreenPtr screen) 16103b705cfSriastradh{ 16203b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 16303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 16403b705cfSriastradh XF86VideoAdaptorPtr *adaptors = NULL, *newAdaptors = NULL; 16513496ba1Ssnj XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL; 16603b705cfSriastradh int num_adaptors = xf86XVListGenericAdaptors(scrn, &adaptors); 16713496ba1Ssnj 16803b705cfSriastradh /* Give our adaptor list enough space for the overlay and/or texture video 16903b705cfSriastradh * adaptors. 17003b705cfSriastradh */ 17103b705cfSriastradh newAdaptors = realloc(adaptors, 17242542f5fSchristos (num_adaptors + 3) * sizeof(XF86VideoAdaptorPtr)); 17313496ba1Ssnj 17403b705cfSriastradh if (newAdaptors == NULL) { 17503b705cfSriastradh free(adaptors); 17603b705cfSriastradh return; 17703b705cfSriastradh } 17803b705cfSriastradh adaptors = newAdaptors; 17903b705cfSriastradh 18003b705cfSriastradh /* Add the adaptors supported by our hardware. First, set up the atoms 18103b705cfSriastradh * that will be used by both output adaptors. 18203b705cfSriastradh */ 18313496ba1Ssnj intel_xv_Brightness = MAKE_ATOM("XV_BRIGHTNESS"); 18413496ba1Ssnj intel_xv_Contrast = MAKE_ATOM("XV_CONTRAST"); 18513496ba1Ssnj 18613496ba1Ssnj /* Set up textured video if we can do it at this depth and we are on 18713496ba1Ssnj * supported hardware. 18813496ba1Ssnj */ 18913496ba1Ssnj if (!intel->force_fallback && 19013496ba1Ssnj scrn->bitsPerPixel >= 16 && 19113496ba1Ssnj INTEL_INFO(intel)->gen >= 030 && 19213496ba1Ssnj INTEL_INFO(intel)->gen < 0100) { 19313496ba1Ssnj texturedAdaptor = intel_uxa_video_setup_image_textured(screen); 19413496ba1Ssnj if (texturedAdaptor != NULL) { 19513496ba1Ssnj xf86DrvMsg(scrn->scrnIndex, X_INFO, 19613496ba1Ssnj "Set up textured video\n"); 19713496ba1Ssnj } else { 19813496ba1Ssnj xf86DrvMsg(scrn->scrnIndex, X_ERROR, 19913496ba1Ssnj "Failed to set up textured video\n"); 20013496ba1Ssnj } 20113496ba1Ssnj } 20213496ba1Ssnj 20313496ba1Ssnj overlayAdaptor = intel_video_overlay_setup_image(screen); 20413496ba1Ssnj 20513496ba1Ssnj if (intel->use_overlay) { 20603b705cfSriastradh if (overlayAdaptor != NULL) { 20703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 20803b705cfSriastradh "Set up overlay video\n"); 20903b705cfSriastradh } else { 21003b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 21103b705cfSriastradh "Failed to set up overlay video\n"); 21203b705cfSriastradh } 21303b705cfSriastradh } 21403b705cfSriastradh 21503b705cfSriastradh if (overlayAdaptor && intel->XvPreferOverlay) 21603b705cfSriastradh adaptors[num_adaptors++] = overlayAdaptor; 21703b705cfSriastradh 21803b705cfSriastradh if (texturedAdaptor) 21903b705cfSriastradh adaptors[num_adaptors++] = texturedAdaptor; 22003b705cfSriastradh 22103b705cfSriastradh if (overlayAdaptor && !intel->XvPreferOverlay) 22203b705cfSriastradh adaptors[num_adaptors++] = overlayAdaptor; 22303b705cfSriastradh 22403b705cfSriastradh if (num_adaptors) { 22503b705cfSriastradh xf86XVScreenInit(screen, adaptors, num_adaptors); 22603b705cfSriastradh } else { 22703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_WARNING, 22803b705cfSriastradh "Disabling Xv because no adaptors could be initialized.\n"); 22903b705cfSriastradh intel->XvEnabled = FALSE; 23003b705cfSriastradh } 23103b705cfSriastradh 23203b705cfSriastradh#ifdef INTEL_XVMC 23313496ba1Ssnj if (texturedAdaptor) 23413496ba1Ssnj intel_xvmc_adaptor_init(screen); 23503b705cfSriastradh#endif 23603b705cfSriastradh 23713496ba1Ssnj free(adaptors); 23803b705cfSriastradh} 23903b705cfSriastradh 24013496ba1Ssnjvoid intel_free_video_buffers(intel_adaptor_private *adaptor_priv) 24103b705cfSriastradh{ 24203b705cfSriastradh int i; 24303b705cfSriastradh 24403b705cfSriastradh for (i = 0; i < 2; i++) { 24503b705cfSriastradh if (adaptor_priv->old_buf[i]) { 24603b705cfSriastradh drm_intel_bo_disable_reuse(adaptor_priv->old_buf[i]); 24703b705cfSriastradh drm_intel_bo_unreference(adaptor_priv->old_buf[i]); 24803b705cfSriastradh adaptor_priv->old_buf[i] = NULL; 24903b705cfSriastradh } 25003b705cfSriastradh } 25103b705cfSriastradh 25203b705cfSriastradh if (adaptor_priv->buf) { 25303b705cfSriastradh drm_intel_bo_unreference(adaptor_priv->buf); 25403b705cfSriastradh adaptor_priv->buf = NULL; 25503b705cfSriastradh } 25603b705cfSriastradh} 25703b705cfSriastradh 25813496ba1Ssnjint 25913496ba1Ssnjintel_video_get_port_attribute(ScrnInfoPtr scrn, 26013496ba1Ssnj Atom attribute, INT32 * value, pointer data) 26103b705cfSriastradh{ 26203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 26303b705cfSriastradh intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; 26403b705cfSriastradh 26513496ba1Ssnj if (attribute == intel_xv_Brightness) { 26603b705cfSriastradh *value = adaptor_priv->brightness; 26713496ba1Ssnj } else if (attribute == intel_xv_Contrast) { 26803b705cfSriastradh *value = adaptor_priv->contrast; 26913496ba1Ssnj } else if (attribute == intel_xv_Saturation) { 27003b705cfSriastradh *value = adaptor_priv->saturation; 27113496ba1Ssnj } else if (attribute == intel_xv_Pipe) { 27203b705cfSriastradh int c; 27303b705cfSriastradh xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 27403b705cfSriastradh for (c = 0; c < xf86_config->num_crtc; c++) 27503b705cfSriastradh if (xf86_config->crtc[c] == adaptor_priv->desired_crtc) 27603b705cfSriastradh break; 27703b705cfSriastradh if (c == xf86_config->num_crtc) 27803b705cfSriastradh c = -1; 27903b705cfSriastradh *value = c; 28013496ba1Ssnj } else if (attribute == intel_xv_Gamma0 && (INTEL_INFO(intel)->gen >= 030)) { 28103b705cfSriastradh *value = adaptor_priv->gamma0; 28213496ba1Ssnj } else if (attribute == intel_xv_Gamma1 && (INTEL_INFO(intel)->gen >= 030)) { 28303b705cfSriastradh *value = adaptor_priv->gamma1; 28413496ba1Ssnj } else if (attribute == intel_xv_Gamma2 && (INTEL_INFO(intel)->gen >= 030)) { 28503b705cfSriastradh *value = adaptor_priv->gamma2; 28613496ba1Ssnj } else if (attribute == intel_xv_Gamma3 && (INTEL_INFO(intel)->gen >= 030)) { 28703b705cfSriastradh *value = adaptor_priv->gamma3; 28813496ba1Ssnj } else if (attribute == intel_xv_Gamma4 && (INTEL_INFO(intel)->gen >= 030)) { 28903b705cfSriastradh *value = adaptor_priv->gamma4; 29013496ba1Ssnj } else if (attribute == intel_xv_Gamma5 && (INTEL_INFO(intel)->gen >= 030)) { 29103b705cfSriastradh *value = adaptor_priv->gamma5; 29213496ba1Ssnj } else if (attribute == intel_xv_ColorKey) { 29303b705cfSriastradh *value = adaptor_priv->colorKey; 29413496ba1Ssnj } else if (attribute == intel_xv_SyncToVblank) { 29503b705cfSriastradh *value = adaptor_priv->SyncToVblank; 29603b705cfSriastradh } else 29703b705cfSriastradh return BadMatch; 29803b705cfSriastradh 29903b705cfSriastradh return Success; 30003b705cfSriastradh} 30103b705cfSriastradh 30213496ba1Ssnjvoid 30313496ba1Ssnjintel_video_query_best_size(ScrnInfoPtr scrn, 30403b705cfSriastradh Bool motion, 30503b705cfSriastradh short vid_w, short vid_h, 30603b705cfSriastradh short drw_w, short drw_h, 30703b705cfSriastradh unsigned int *p_w, unsigned int *p_h, pointer data) 30803b705cfSriastradh{ 30903b705cfSriastradh if (vid_w > (drw_w << 1)) 31003b705cfSriastradh drw_w = vid_w >> 1; 31103b705cfSriastradh if (vid_h > (drw_h << 1)) 31203b705cfSriastradh drw_h = vid_h >> 1; 31303b705cfSriastradh 31403b705cfSriastradh *p_w = drw_w; 31503b705cfSriastradh *p_h = drw_h; 31603b705cfSriastradh} 31703b705cfSriastradh 31803b705cfSriastradhstatic Bool 31913496ba1Ssnjintel_video_copy_packed_data(intel_adaptor_private *adaptor_priv, 32013496ba1Ssnj unsigned char *buf, 32113496ba1Ssnj int srcPitch, int dstPitch, int top, int left, int h, int w) 32203b705cfSriastradh{ 32303b705cfSriastradh unsigned char *src, *dst, *dst_base; 32403b705cfSriastradh int i, j; 32503b705cfSriastradh unsigned char *s; 32603b705cfSriastradh 32703b705cfSriastradh#if 0 32813496ba1Ssnj ErrorF("intel_video_copy_packed_data: (%d,%d) (%d,%d)\n" 32903b705cfSriastradh "srcPitch: %d, dstPitch: %d\n", top, left, h, w, 33003b705cfSriastradh srcPitch, dstPitch); 33103b705cfSriastradh#endif 33203b705cfSriastradh 33303b705cfSriastradh src = buf + (top * srcPitch) + (left << 1); 33403b705cfSriastradh 33503b705cfSriastradh if (drm_intel_gem_bo_map_gtt(adaptor_priv->buf)) 33603b705cfSriastradh return FALSE; 33703b705cfSriastradh 33803b705cfSriastradh dst_base = adaptor_priv->buf->virtual; 33903b705cfSriastradh 34003b705cfSriastradh dst = dst_base + adaptor_priv->YBufOffset; 34103b705cfSriastradh 34203b705cfSriastradh switch (adaptor_priv->rotation) { 34303b705cfSriastradh case RR_Rotate_0: 34403b705cfSriastradh w <<= 1; 34503b705cfSriastradh for (i = 0; i < h; i++) { 34603b705cfSriastradh memcpy(dst, src, w); 34703b705cfSriastradh src += srcPitch; 34803b705cfSriastradh dst += dstPitch; 34903b705cfSriastradh } 35003b705cfSriastradh break; 35103b705cfSriastradh case RR_Rotate_90: 35203b705cfSriastradh h <<= 1; 35303b705cfSriastradh for (i = 0; i < h; i += 2) { 35403b705cfSriastradh s = src; 35503b705cfSriastradh for (j = 0; j < w; j++) { 35603b705cfSriastradh /* Copy Y */ 35703b705cfSriastradh dst[(i + 0) + ((w - j - 1) * dstPitch)] = *s++; 35803b705cfSriastradh (void)*s++; 35903b705cfSriastradh } 36003b705cfSriastradh src += srcPitch; 36103b705cfSriastradh } 36203b705cfSriastradh h >>= 1; 36303b705cfSriastradh src = buf + (top * srcPitch) + (left << 1); 36403b705cfSriastradh for (i = 0; i < h; i += 2) { 36503b705cfSriastradh for (j = 0; j < w; j += 2) { 36603b705cfSriastradh /* Copy U */ 36703b705cfSriastradh dst[((i * 2) + 1) + ((w - j - 1) * dstPitch)] = 36803b705cfSriastradh src[(j * 2) + 1 + (i * srcPitch)]; 36903b705cfSriastradh dst[((i * 2) + 1) + ((w - j - 2) * dstPitch)] = 37003b705cfSriastradh src[(j * 2) + 1 + ((i + 1) * srcPitch)]; 37103b705cfSriastradh /* Copy V */ 37203b705cfSriastradh dst[((i * 2) + 3) + ((w - j - 1) * dstPitch)] = 37303b705cfSriastradh src[(j * 2) + 3 + (i * srcPitch)]; 37403b705cfSriastradh dst[((i * 2) + 3) + ((w - j - 2) * dstPitch)] = 37503b705cfSriastradh src[(j * 2) + 3 + ((i + 1) * srcPitch)]; 37603b705cfSriastradh } 37703b705cfSriastradh } 37803b705cfSriastradh break; 37903b705cfSriastradh case RR_Rotate_180: 38003b705cfSriastradh w <<= 1; 38103b705cfSriastradh for (i = 0; i < h; i++) { 38203b705cfSriastradh s = src; 38303b705cfSriastradh for (j = 0; j < w; j += 4) { 38403b705cfSriastradh dst[(w - j - 4) + ((h - i - 1) * dstPitch)] = 38503b705cfSriastradh *s++; 38603b705cfSriastradh dst[(w - j - 3) + ((h - i - 1) * dstPitch)] = 38703b705cfSriastradh *s++; 38803b705cfSriastradh dst[(w - j - 2) + ((h - i - 1) * dstPitch)] = 38903b705cfSriastradh *s++; 39003b705cfSriastradh dst[(w - j - 1) + ((h - i - 1) * dstPitch)] = 39103b705cfSriastradh *s++; 39203b705cfSriastradh } 39303b705cfSriastradh src += srcPitch; 39403b705cfSriastradh } 39503b705cfSriastradh break; 39603b705cfSriastradh case RR_Rotate_270: 39703b705cfSriastradh h <<= 1; 39803b705cfSriastradh for (i = 0; i < h; i += 2) { 39903b705cfSriastradh s = src; 40003b705cfSriastradh for (j = 0; j < w; j++) { 40103b705cfSriastradh /* Copy Y */ 40203b705cfSriastradh dst[(h - i - 2) + (j * dstPitch)] = *s++; 40303b705cfSriastradh (void)*s++; 40403b705cfSriastradh } 40503b705cfSriastradh src += srcPitch; 40603b705cfSriastradh } 40703b705cfSriastradh h >>= 1; 40803b705cfSriastradh src = buf + (top * srcPitch) + (left << 1); 40903b705cfSriastradh for (i = 0; i < h; i += 2) { 41003b705cfSriastradh for (j = 0; j < w; j += 2) { 41103b705cfSriastradh /* Copy U */ 41203b705cfSriastradh dst[(((h - i) * 2) - 3) + (j * dstPitch)] = 41303b705cfSriastradh src[(j * 2) + 1 + (i * srcPitch)]; 41403b705cfSriastradh dst[(((h - i) * 2) - 3) + 41503b705cfSriastradh ((j + 1) * dstPitch)] = 41603b705cfSriastradh src[(j * 2) + 1 + ((i + 1) * srcPitch)]; 41703b705cfSriastradh /* Copy V */ 41803b705cfSriastradh dst[(((h - i) * 2) - 1) + (j * dstPitch)] = 41903b705cfSriastradh src[(j * 2) + 3 + (i * srcPitch)]; 42003b705cfSriastradh dst[(((h - i) * 2) - 1) + 42103b705cfSriastradh ((j + 1) * dstPitch)] = 42203b705cfSriastradh src[(j * 2) + 3 + ((i + 1) * srcPitch)]; 42303b705cfSriastradh } 42403b705cfSriastradh } 42503b705cfSriastradh break; 42603b705cfSriastradh } 42703b705cfSriastradh 42803b705cfSriastradh drm_intel_gem_bo_unmap_gtt(adaptor_priv->buf); 42903b705cfSriastradh return TRUE; 43003b705cfSriastradh} 43103b705cfSriastradh 43203b705cfSriastradhstatic void intel_memcpy_plane(unsigned char *dst, unsigned char *src, 43303b705cfSriastradh int height, int width, 43403b705cfSriastradh int dstPitch, int srcPitch, Rotation rotation) 43503b705cfSriastradh{ 43603b705cfSriastradh int i, j = 0; 43703b705cfSriastradh unsigned char *s; 43803b705cfSriastradh 43903b705cfSriastradh switch (rotation) { 44003b705cfSriastradh case RR_Rotate_0: 44103b705cfSriastradh /* optimise for the case of no clipping */ 44203b705cfSriastradh if (srcPitch == dstPitch && srcPitch == width) 44303b705cfSriastradh memcpy(dst, src, srcPitch * height); 44403b705cfSriastradh else 44503b705cfSriastradh for (i = 0; i < height; i++) { 44603b705cfSriastradh memcpy(dst, src, width); 44703b705cfSriastradh src += srcPitch; 44803b705cfSriastradh dst += dstPitch; 44903b705cfSriastradh } 45003b705cfSriastradh break; 45103b705cfSriastradh case RR_Rotate_90: 45203b705cfSriastradh for (i = 0; i < height; i++) { 45303b705cfSriastradh s = src; 45403b705cfSriastradh for (j = 0; j < width; j++) { 45503b705cfSriastradh dst[(i) + ((width - j - 1) * dstPitch)] = *s++; 45603b705cfSriastradh } 45703b705cfSriastradh src += srcPitch; 45803b705cfSriastradh } 45903b705cfSriastradh break; 46003b705cfSriastradh case RR_Rotate_180: 46103b705cfSriastradh for (i = 0; i < height; i++) { 46203b705cfSriastradh s = src; 46303b705cfSriastradh for (j = 0; j < width; j++) { 46403b705cfSriastradh dst[(width - j - 1) + 46503b705cfSriastradh ((height - i - 1) * dstPitch)] = *s++; 46603b705cfSriastradh } 46703b705cfSriastradh src += srcPitch; 46803b705cfSriastradh } 46903b705cfSriastradh break; 47003b705cfSriastradh case RR_Rotate_270: 47103b705cfSriastradh for (i = 0; i < height; i++) { 47203b705cfSriastradh s = src; 47303b705cfSriastradh for (j = 0; j < width; j++) { 47403b705cfSriastradh dst[(height - i - 1) + (j * dstPitch)] = *s++; 47503b705cfSriastradh } 47603b705cfSriastradh src += srcPitch; 47703b705cfSriastradh } 47803b705cfSriastradh break; 47903b705cfSriastradh } 48003b705cfSriastradh} 48103b705cfSriastradh 48203b705cfSriastradhstatic Bool 48313496ba1Ssnjintel_video_copy_planar_data(intel_adaptor_private *adaptor_priv, 48403b705cfSriastradh unsigned char *buf, int srcPitch, int srcPitch2, 48503b705cfSriastradh int dstPitch, int dstPitch2, 48603b705cfSriastradh int srcH, int top, int left, 48703b705cfSriastradh int h, int w, int id) 48803b705cfSriastradh{ 48903b705cfSriastradh unsigned char *src1, *src2, *src3, *dst_base, *dst1, *dst2, *dst3; 49003b705cfSriastradh 49103b705cfSriastradh#if 0 49213496ba1Ssnj ErrorF("intel_video_copy_planar_data: srcPitch %d, srcPitch %d, dstPitch %d\n" 49303b705cfSriastradh "nlines %d, npixels %d, top %d, left %d\n", 49403b705cfSriastradh srcPitch, srcPitch2, dstPitch, h, w, top, left); 49503b705cfSriastradh#endif 49603b705cfSriastradh 49703b705cfSriastradh /* Copy Y data */ 49803b705cfSriastradh src1 = buf + (top * srcPitch) + left; 49903b705cfSriastradh#if 0 50003b705cfSriastradh ErrorF("src1 is %p, offset is %ld\n", src1, 50103b705cfSriastradh (unsigned long)src1 - (unsigned long)buf); 50203b705cfSriastradh#endif 50303b705cfSriastradh 50403b705cfSriastradh if (drm_intel_gem_bo_map_gtt(adaptor_priv->buf)) 50503b705cfSriastradh return FALSE; 50603b705cfSriastradh 50703b705cfSriastradh dst_base = adaptor_priv->buf->virtual; 50803b705cfSriastradh 50903b705cfSriastradh dst1 = dst_base + adaptor_priv->YBufOffset; 51003b705cfSriastradh 51103b705cfSriastradh intel_memcpy_plane(dst1, src1, h, w, dstPitch2, srcPitch, 51203b705cfSriastradh adaptor_priv->rotation); 51303b705cfSriastradh 51403b705cfSriastradh /* Copy V data for YV12, or U data for I420 */ 51503b705cfSriastradh src2 = buf + /* start of YUV data */ 51603b705cfSriastradh (srcH * srcPitch) + /* move over Luma plane */ 51703b705cfSriastradh ((top >> 1) * srcPitch2) + /* move down from by top lines */ 51803b705cfSriastradh (left >> 1); /* move left by left pixels */ 51903b705cfSriastradh 52003b705cfSriastradh#if 0 52103b705cfSriastradh ErrorF("src2 is %p, offset is %ld\n", src2, 52203b705cfSriastradh (unsigned long)src2 - (unsigned long)buf); 52303b705cfSriastradh#endif 52403b705cfSriastradh if (id == FOURCC_I420) 52503b705cfSriastradh dst2 = dst_base + adaptor_priv->UBufOffset; 52603b705cfSriastradh else 52703b705cfSriastradh dst2 = dst_base + adaptor_priv->VBufOffset; 52803b705cfSriastradh 52903b705cfSriastradh intel_memcpy_plane(dst2, src2, h / 2, w / 2, 53003b705cfSriastradh dstPitch, srcPitch2, adaptor_priv->rotation); 53103b705cfSriastradh 53203b705cfSriastradh /* Copy U data for YV12, or V data for I420 */ 53303b705cfSriastradh src3 = buf + /* start of YUV data */ 53403b705cfSriastradh (srcH * srcPitch) + /* move over Luma plane */ 53503b705cfSriastradh ((srcH >> 1) * srcPitch2) + /* move over Chroma plane */ 53603b705cfSriastradh ((top >> 1) * srcPitch2) + /* move down from by top lines */ 53703b705cfSriastradh (left >> 1); /* move left by left pixels */ 53803b705cfSriastradh#if 0 53903b705cfSriastradh ErrorF("src3 is %p, offset is %ld\n", src3, 54003b705cfSriastradh (unsigned long)src3 - (unsigned long)buf); 54103b705cfSriastradh#endif 54203b705cfSriastradh if (id == FOURCC_I420) 54303b705cfSriastradh dst3 = dst_base + adaptor_priv->VBufOffset; 54403b705cfSriastradh else 54503b705cfSriastradh dst3 = dst_base + adaptor_priv->UBufOffset; 54603b705cfSriastradh 54703b705cfSriastradh intel_memcpy_plane(dst3, src3, h / 2, w / 2, 54803b705cfSriastradh dstPitch, srcPitch2, adaptor_priv->rotation); 54903b705cfSriastradh 55003b705cfSriastradh drm_intel_gem_bo_unmap_gtt(adaptor_priv->buf); 55103b705cfSriastradh return TRUE; 55203b705cfSriastradh} 55303b705cfSriastradh 55413496ba1Ssnjvoid 55503b705cfSriastradhintel_setup_dst_params(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, short width, 55603b705cfSriastradh short height, int *dstPitch, int *dstPitch2, int *size, 55703b705cfSriastradh int id) 55803b705cfSriastradh{ 55903b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 56003b705cfSriastradh int pitchAlign; 56103b705cfSriastradh 56203b705cfSriastradh /* Only needs to be DWORD-aligned for textured on i915, but overlay has 56303b705cfSriastradh * stricter requirements. 56403b705cfSriastradh */ 56503b705cfSriastradh if (adaptor_priv->textured) { 56603b705cfSriastradh pitchAlign = 4; 56703b705cfSriastradh } else { 56803b705cfSriastradh if (INTEL_INFO(intel)->gen >= 040) 56903b705cfSriastradh /* Actually the alignment is 64 bytes, too. But the 57003b705cfSriastradh * stride must be at least 512 bytes. Take the easy fix 57103b705cfSriastradh * and align on 512 bytes unconditionally. */ 57203b705cfSriastradh pitchAlign = 512; 57303b705cfSriastradh else if (IS_I830(intel) || IS_845G(intel)) 57403b705cfSriastradh /* Harsh, errata on these chipsets limit the stride to be 57503b705cfSriastradh * a multiple of 256 bytes. 57603b705cfSriastradh */ 57703b705cfSriastradh pitchAlign = 256; 57803b705cfSriastradh else 57903b705cfSriastradh pitchAlign = 64; 58003b705cfSriastradh } 58103b705cfSriastradh 58203b705cfSriastradh#if INTEL_XVMC 58303b705cfSriastradh /* for i915 xvmc, hw requires 1kb aligned surfaces */ 58403b705cfSriastradh if ((id == FOURCC_XVMC) && IS_GEN3(intel)) 58503b705cfSriastradh pitchAlign = 1024; 58603b705cfSriastradh#endif 58703b705cfSriastradh 58803b705cfSriastradh /* Determine the desired destination pitch (representing the chroma's pitch, 58903b705cfSriastradh * in the planar case. 59003b705cfSriastradh */ 59103b705cfSriastradh if (is_planar_fourcc(id)) { 59203b705cfSriastradh if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { 59303b705cfSriastradh *dstPitch = ALIGN((height / 2), pitchAlign); 59403b705cfSriastradh *dstPitch2 = ALIGN(height, pitchAlign); 59503b705cfSriastradh *size = *dstPitch * width * 3; 59603b705cfSriastradh } else { 59703b705cfSriastradh *dstPitch = ALIGN((width / 2), pitchAlign); 59803b705cfSriastradh *dstPitch2 = ALIGN(width, pitchAlign); 59903b705cfSriastradh *size = *dstPitch * height * 3; 60003b705cfSriastradh } 60103b705cfSriastradh } else { 60203b705cfSriastradh if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { 60303b705cfSriastradh *dstPitch = ALIGN((height << 1), pitchAlign); 60403b705cfSriastradh *size = *dstPitch * width; 60503b705cfSriastradh } else { 60603b705cfSriastradh *dstPitch = ALIGN((width << 1), pitchAlign); 60703b705cfSriastradh *size = *dstPitch * height; 60803b705cfSriastradh } 60903b705cfSriastradh *dstPitch2 = 0; 61003b705cfSriastradh } 61103b705cfSriastradh#if 0 61203b705cfSriastradh ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, *dstPitch, 61303b705cfSriastradh size); 61403b705cfSriastradh#endif 61503b705cfSriastradh 61603b705cfSriastradh adaptor_priv->YBufOffset = 0; 61703b705cfSriastradh 61803b705cfSriastradh if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { 61903b705cfSriastradh adaptor_priv->UBufOffset = 62003b705cfSriastradh adaptor_priv->YBufOffset + (*dstPitch2 * width); 62103b705cfSriastradh adaptor_priv->VBufOffset = 62203b705cfSriastradh adaptor_priv->UBufOffset + (*dstPitch * width / 2); 62303b705cfSriastradh } else { 62403b705cfSriastradh adaptor_priv->UBufOffset = 62503b705cfSriastradh adaptor_priv->YBufOffset + (*dstPitch2 * height); 62603b705cfSriastradh adaptor_priv->VBufOffset = 62703b705cfSriastradh adaptor_priv->UBufOffset + (*dstPitch * height / 2); 62803b705cfSriastradh } 62903b705cfSriastradh} 63003b705cfSriastradh 63103b705cfSriastradhstatic Bool 63213496ba1Ssnjintel_setup_video_buffer(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, 63313496ba1Ssnj int alloc_size, int id, unsigned char *buf) 63413496ba1Ssnj{ 63513496ba1Ssnj intel_screen_private *intel = intel_get_screen_private(scrn); 63613496ba1Ssnj 63713496ba1Ssnj /* Free the current buffer if we're going to have to reallocate */ 63813496ba1Ssnj if (adaptor_priv->buf && adaptor_priv->buf->size < alloc_size) 63913496ba1Ssnj intel_free_video_buffers(adaptor_priv); 64013496ba1Ssnj 64113496ba1Ssnj if (adaptor_priv->buf == NULL) { 64213496ba1Ssnj adaptor_priv->buf = drm_intel_bo_alloc(intel->bufmgr, "xv buffer", 64313496ba1Ssnj alloc_size, 4096); 64413496ba1Ssnj if (adaptor_priv->buf == NULL) 64513496ba1Ssnj return FALSE; 64613496ba1Ssnj 64713496ba1Ssnj adaptor_priv->reusable = TRUE; 64813496ba1Ssnj } 64913496ba1Ssnj 65013496ba1Ssnj return TRUE; 65113496ba1Ssnj} 65213496ba1Ssnj 65313496ba1SsnjBool 65413496ba1Ssnjintel_video_copy_data(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, 65513496ba1Ssnj short width, short height, int *dstPitch, int *dstPitch2, 65613496ba1Ssnj int top, int left, int npixels, int nlines, 65713496ba1Ssnj int id, unsigned char *buf) 65803b705cfSriastradh{ 65903b705cfSriastradh int srcPitch = 0, srcPitch2 = 0; 66003b705cfSriastradh int size; 66103b705cfSriastradh 66203b705cfSriastradh if (is_planar_fourcc(id)) { 66303b705cfSriastradh srcPitch = ALIGN(width, 0x4); 66403b705cfSriastradh srcPitch2 = ALIGN((width >> 1), 0x4); 66503b705cfSriastradh } else { 66603b705cfSriastradh srcPitch = width << 1; 66703b705cfSriastradh } 66803b705cfSriastradh 66903b705cfSriastradh intel_setup_dst_params(scrn, adaptor_priv, width, height, dstPitch, 67003b705cfSriastradh dstPitch2, &size, id); 67103b705cfSriastradh 67203b705cfSriastradh if (!intel_setup_video_buffer(scrn, adaptor_priv, size, id, buf)) 67303b705cfSriastradh return FALSE; 67403b705cfSriastradh 67503b705cfSriastradh /* copy data */ 67603b705cfSriastradh if (is_planar_fourcc(id)) { 67713496ba1Ssnj return intel_video_copy_planar_data(adaptor_priv, buf, srcPitch, srcPitch2, 67803b705cfSriastradh *dstPitch, *dstPitch2, 67903b705cfSriastradh height, top, left, nlines, 68003b705cfSriastradh npixels, id); 68103b705cfSriastradh } else { 68213496ba1Ssnj return intel_video_copy_packed_data(adaptor_priv, buf, srcPitch, *dstPitch, top, left, 68303b705cfSriastradh nlines, npixels); 68403b705cfSriastradh } 68503b705cfSriastradh} 68603b705cfSriastradh 68713496ba1Ssnjint is_planar_fourcc(int id) 68803b705cfSriastradh{ 68913496ba1Ssnj switch (id) { 69013496ba1Ssnj case FOURCC_YV12: 69113496ba1Ssnj case FOURCC_I420: 69213496ba1Ssnj#ifdef INTEL_XVMC 69313496ba1Ssnj case FOURCC_XVMC: 69403b705cfSriastradh#endif 69513496ba1Ssnj return 1; 69613496ba1Ssnj case FOURCC_UYVY: 69713496ba1Ssnj case FOURCC_YUY2: 69813496ba1Ssnj return 0; 69913496ba1Ssnj default: 70013496ba1Ssnj ErrorF("Unknown format 0x%x\n", id); 70113496ba1Ssnj return 0; 70203b705cfSriastradh } 70303b705cfSriastradh} 70403b705cfSriastradh 70513496ba1SsnjBool 70613496ba1Ssnjintel_clip_video_helper(ScrnInfoPtr scrn, 70713496ba1Ssnj intel_adaptor_private *adaptor_priv, 70813496ba1Ssnj xf86CrtcPtr * crtc_ret, 70913496ba1Ssnj BoxPtr dst, 71013496ba1Ssnj short src_x, short src_y, 71113496ba1Ssnj short drw_x, short drw_y, 71213496ba1Ssnj short src_w, short src_h, 71313496ba1Ssnj short drw_w, short drw_h, 71413496ba1Ssnj int id, 71513496ba1Ssnj int *top, int* left, int* npixels, int *nlines, 71613496ba1Ssnj RegionPtr reg, INT32 width, INT32 height) 71703b705cfSriastradh{ 71813496ba1Ssnj Bool ret; 71913496ba1Ssnj RegionRec crtc_region_local; 72013496ba1Ssnj RegionPtr crtc_region = reg; 72113496ba1Ssnj BoxRec crtc_box; 72213496ba1Ssnj INT32 x1, x2, y1, y2; 72303b705cfSriastradh xf86CrtcPtr crtc; 72403b705cfSriastradh 72513496ba1Ssnj x1 = src_x; 72613496ba1Ssnj x2 = src_x + src_w; 72713496ba1Ssnj y1 = src_y; 72813496ba1Ssnj y2 = src_y + src_h; 72903b705cfSriastradh 73013496ba1Ssnj dst->x1 = drw_x; 73113496ba1Ssnj dst->x2 = drw_x + drw_w; 73213496ba1Ssnj dst->y1 = drw_y; 73313496ba1Ssnj dst->y2 = drw_y + drw_h; 73413496ba1Ssnj 73513496ba1Ssnj /* 73613496ba1Ssnj * For overlay video, compute the relevant CRTC and 73713496ba1Ssnj * clip video to that 73813496ba1Ssnj */ 73913496ba1Ssnj crtc = intel_covering_crtc(scrn, dst, adaptor_priv->desired_crtc, 74013496ba1Ssnj &crtc_box); 74103b705cfSriastradh 74213496ba1Ssnj /* For textured video, we don't actually want to clip at all. */ 74313496ba1Ssnj if (crtc && !adaptor_priv->textured) { 74413496ba1Ssnj REGION_INIT(screen, &crtc_region_local, &crtc_box, 1); 74513496ba1Ssnj crtc_region = &crtc_region_local; 74613496ba1Ssnj REGION_INTERSECT(screen, crtc_region, crtc_region, 74713496ba1Ssnj reg); 74803b705cfSriastradh } 74913496ba1Ssnj *crtc_ret = crtc; 75003b705cfSriastradh 75113496ba1Ssnj ret = xf86XVClipVideoHelper(dst, &x1, &x2, &y1, &y2, 75213496ba1Ssnj crtc_region, width, height); 75313496ba1Ssnj if (crtc_region != reg) 75413496ba1Ssnj REGION_UNINIT(screen, &crtc_region_local); 75503b705cfSriastradh 75613496ba1Ssnj *top = y1 >> 16; 75713496ba1Ssnj *left = (x1 >> 16) & ~1; 75813496ba1Ssnj *npixels = ALIGN(((x2 + 0xffff) >> 16), 2) - *left; 75913496ba1Ssnj if (is_planar_fourcc(id)) { 76013496ba1Ssnj *top &= ~1; 76113496ba1Ssnj *nlines = ALIGN(((y2 + 0xffff) >> 16), 2) - *top; 76213496ba1Ssnj } else 76313496ba1Ssnj *nlines = ((y2 + 0xffff) >> 16) - *top; 76413496ba1Ssnj 76513496ba1Ssnj return ret; 76603b705cfSriastradh} 76703b705cfSriastradh 76813496ba1Ssnjint 76913496ba1Ssnjintel_video_query_image_attributes(ScrnInfoPtr scrn, 77013496ba1Ssnj int id, 77113496ba1Ssnj unsigned short *w, unsigned short *h, 77213496ba1Ssnj int *pitches, int *offsets) 77303b705cfSriastradh{ 77403b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 77503b705cfSriastradh int size, tmp; 77603b705cfSriastradh 77703b705cfSriastradh#if 0 77813496ba1Ssnj ErrorF("intel_video_query_image_attributes: w is %d, h is %d\n", *w, *h); 77903b705cfSriastradh#endif 78003b705cfSriastradh 78103b705cfSriastradh if (IS_845G(intel) || IS_I830(intel)) { 78203b705cfSriastradh if (*w > IMAGE_MAX_WIDTH_LEGACY) 78303b705cfSriastradh *w = IMAGE_MAX_WIDTH_LEGACY; 78403b705cfSriastradh if (*h > IMAGE_MAX_HEIGHT_LEGACY) 78503b705cfSriastradh *h = IMAGE_MAX_HEIGHT_LEGACY; 78603b705cfSriastradh } else { 78703b705cfSriastradh if (*w > IMAGE_MAX_WIDTH) 78803b705cfSriastradh *w = IMAGE_MAX_WIDTH; 78903b705cfSriastradh if (*h > IMAGE_MAX_HEIGHT) 79003b705cfSriastradh *h = IMAGE_MAX_HEIGHT; 79103b705cfSriastradh } 79203b705cfSriastradh 79303b705cfSriastradh *w = (*w + 1) & ~1; 79403b705cfSriastradh if (offsets) 79503b705cfSriastradh offsets[0] = 0; 79603b705cfSriastradh 79703b705cfSriastradh switch (id) { 79803b705cfSriastradh /* IA44 is for XvMC only */ 79903b705cfSriastradh case FOURCC_IA44: 80003b705cfSriastradh case FOURCC_AI44: 80103b705cfSriastradh if (pitches) 80203b705cfSriastradh pitches[0] = *w; 80303b705cfSriastradh size = *w * *h; 80403b705cfSriastradh break; 80503b705cfSriastradh case FOURCC_YV12: 80603b705cfSriastradh case FOURCC_I420: 80703b705cfSriastradh *h = (*h + 1) & ~1; 80803b705cfSriastradh size = (*w + 3) & ~3; 80903b705cfSriastradh if (pitches) 81003b705cfSriastradh pitches[0] = size; 81103b705cfSriastradh size *= *h; 81203b705cfSriastradh if (offsets) 81303b705cfSriastradh offsets[1] = size; 81403b705cfSriastradh tmp = ((*w >> 1) + 3) & ~3; 81503b705cfSriastradh if (pitches) 81603b705cfSriastradh pitches[1] = pitches[2] = tmp; 81703b705cfSriastradh tmp *= (*h >> 1); 81803b705cfSriastradh size += tmp; 81903b705cfSriastradh if (offsets) 82003b705cfSriastradh offsets[2] = size; 82103b705cfSriastradh size += tmp; 82203b705cfSriastradh#if 0 82303b705cfSriastradh if (pitches) 82403b705cfSriastradh ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n", 82503b705cfSriastradh pitches[0], pitches[1], pitches[2]); 82603b705cfSriastradh if (offsets) 82703b705cfSriastradh ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1], 82803b705cfSriastradh offsets[2]); 82903b705cfSriastradh if (offsets) 83003b705cfSriastradh ErrorF("size is %d\n", size); 83103b705cfSriastradh#endif 83203b705cfSriastradh break; 83303b705cfSriastradh#ifdef INTEL_XVMC 83403b705cfSriastradh case FOURCC_XVMC: 83503b705cfSriastradh *h = (*h + 1) & ~1; 83603b705cfSriastradh size = sizeof(struct intel_xvmc_command); 83703b705cfSriastradh if (pitches) 83803b705cfSriastradh pitches[0] = size; 83903b705cfSriastradh break; 84003b705cfSriastradh#endif 84103b705cfSriastradh case FOURCC_UYVY: 84203b705cfSriastradh case FOURCC_YUY2: 84303b705cfSriastradh default: 84403b705cfSriastradh size = *w << 1; 84503b705cfSriastradh if (pitches) 84603b705cfSriastradh pitches[0] = size; 84703b705cfSriastradh size *= *h; 84803b705cfSriastradh break; 84903b705cfSriastradh } 85003b705cfSriastradh 85103b705cfSriastradh return size; 85203b705cfSriastradh} 85303b705cfSriastradh 85413496ba1Ssnjvoid intel_video_stop_video(ScrnInfoPtr scrn, pointer data, Bool shutdown) 85513496ba1Ssnj{ 85613496ba1Ssnj intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; 85713496ba1Ssnj 85813496ba1Ssnj if (adaptor_priv->textured) 85913496ba1Ssnj return; 86013496ba1Ssnj 86113496ba1Ssnj REGION_EMPTY(scrn->pScreen, &adaptor_priv->clip); 86213496ba1Ssnj 86313496ba1Ssnj if (shutdown) { 86413496ba1Ssnj if (adaptor_priv->videoStatus & CLIENT_VIDEO_ON) 86513496ba1Ssnj intel_video_overlay_off(intel_get_screen_private(scrn)); 86613496ba1Ssnj 86713496ba1Ssnj intel_free_video_buffers(adaptor_priv); 86813496ba1Ssnj adaptor_priv->videoStatus = 0; 86913496ba1Ssnj } else { 87013496ba1Ssnj if (adaptor_priv->videoStatus & CLIENT_VIDEO_ON) { 87113496ba1Ssnj adaptor_priv->videoStatus |= OFF_TIMER; 87213496ba1Ssnj adaptor_priv->offTime = currentTime.milliseconds + OFF_DELAY; 87313496ba1Ssnj } 87413496ba1Ssnj } 87513496ba1Ssnj 87613496ba1Ssnj} 87713496ba1Ssnj 87803b705cfSriastradhvoid 87903b705cfSriastradhintel_video_block_handler(intel_screen_private *intel) 88003b705cfSriastradh{ 88103b705cfSriastradh intel_adaptor_private *adaptor_priv; 88203b705cfSriastradh 88303b705cfSriastradh /* no overlay */ 88403b705cfSriastradh if (intel->adaptor == NULL) 88503b705cfSriastradh return; 88603b705cfSriastradh 88703b705cfSriastradh adaptor_priv = intel_get_adaptor_private(intel); 88803b705cfSriastradh if (adaptor_priv->videoStatus & OFF_TIMER) { 88903b705cfSriastradh Time now = currentTime.milliseconds; 89003b705cfSriastradh if (adaptor_priv->offTime < now) { 89103b705cfSriastradh /* Turn off the overlay */ 89213496ba1Ssnj intel_video_overlay_off(intel); 89303b705cfSriastradh intel_free_video_buffers(adaptor_priv); 89403b705cfSriastradh adaptor_priv->videoStatus = 0; 89503b705cfSriastradh } 89603b705cfSriastradh } 89703b705cfSriastradh} 898