diff options
Diffstat (limited to 'src/amd_lx_video.c')
-rw-r--r-- | src/amd_lx_video.c | 2076 |
1 files changed, 793 insertions, 1283 deletions
diff --git a/src/amd_lx_video.c b/src/amd_lx_video.c index a0836b0..13129c0 100644 --- a/src/amd_lx_video.c +++ b/src/amd_lx_video.c @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. +/* Copyright (c) 2007 Advanced Micro Devices, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. @@ -16,232 +15,82 @@ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. */ -/* - * File Contents: This file consists of main Xfree video supported routines. - * - * Project: Geode Xfree Frame buffer device driver. - * - */ - -/* - * Fixes & Extensions to support Y800 greyscale modes - * Alan Hourihane <alanh@fairlite.demon.co.uk> - */ +/* TODO: + Add rotation + Add back in double buffering? + +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifndef AMD_V4L2_VIDEO +#include <stdlib.h> +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "regionstr.h" +#include "dixstruct.h" #include "amd.h" -#include "Xv.h" -#include "xaa.h" -#include "xaalocal.h" -#include "dixstruct.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> #include "fourcc.h" #include "amd_fourcc.h" -#if DEBUGLVL>0 -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0) -#include "xf86_ansic.h" -extern FILE *zdfp; -#else -#define DBLOG(n,s...) do {} while(0) -#endif - -#define OFF_DELAY 200 /* milliseconds */ -#define FREE_DELAY 60000 - -#define OFF_TIMER 0x01 -#define FREE_TIMER 0x02 +#define OFF_DELAY 200 +#define FREE_DELAY 60000 +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 #define CLIENT_VIDEO_ON 0x04 - #define TIMER_MASK (OFF_TIMER | FREE_TIMER) -#define XV_PROFILE 0 -#define REINIT 1 - -#ifndef XvExtension -void -LXInitVideo(ScreenPtr pScrn) -{ -} - -void -LXResetVideo(ScrnInfoPtr pScrni) -{ -} - -void -LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni) -{ -} -#else - -#define DBUF 1 -void LXInitVideo(ScreenPtr pScrn); -void LXResetVideo(ScrnInfoPtr pScrni); -static XF86VideoAdaptorPtr LXSetupImageVideo(ScreenPtr); -static void LXInitOffscreenImages(ScreenPtr); -static void LXStopVideo(ScrnInfoPtr, pointer, Bool); -static int LXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); -static int LXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); -static void LXQueryBestSize(ScrnInfoPtr, Bool, - short, short, short, short, unsigned int *, unsigned int *, pointer); -static int LXPutImage(ScrnInfoPtr, short, short, short, short, short, short, - short, short, int, unsigned char *, short, short, Bool, - RegionPtr, pointer); -static int LXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, - unsigned short *, int *, int *); - -static void LXBlockHandler(int, pointer, pointer, pointer); -void LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni); - -extern void LXAccelSync(ScrnInfoPtr pScrni); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) +#define ARRAY_SIZE(a) (sizeof((a)) / (sizeof(*(a)))) -static Atom xvColorKey, xvColorKeyMode, xvFilter; - -#if DBUF -static Atom xvDoubleBuffer; -#endif - -/*---------------------------------------------------------------------------- - * LXInitVideo - * - * Description: This is the initialization routine. It creates a new video - * adapter and calls LXSetupImageVideo to initialize it by - * filling XF86VideoAdaptorREc. Then it lists the existing - * adaptors and adds the new one to it. Finally the list of - * XF86VideoAdaptorPtr pointers are passed to the - * xf86XVScreenInit(). - * - * Parameters. - * ScreenPtr - * pScrn :Screen handler pointer having screen information. - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -void -LXInitVideo(ScreenPtr pScrn) -{ - GeodeRec *pGeode; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - - DBLOG(1, "LXInitVideo()\n"); - - pGeode = GEODEPTR(pScrni); - - if (!pGeode->NoAccel) { - XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; - XF86VideoAdaptorPtr newAdaptor = NULL; - - int num_adaptors; - - newAdaptor = LXSetupImageVideo(pScrn); - LXInitOffscreenImages(pScrn); - - num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); - - if (newAdaptor) { - if (!num_adaptors) { - num_adaptors = 1; - adaptors = &newAdaptor; - } else { - newAdaptors = /* need to free this someplace */ - xalloc((num_adaptors + - 1) * sizeof(XF86VideoAdaptorPtr *)); - if (newAdaptors) { - memcpy(newAdaptors, adaptors, num_adaptors * - sizeof(XF86VideoAdaptorPtr)); - newAdaptors[num_adaptors] = newAdaptor; - adaptors = newAdaptors; - num_adaptors++; - } - } - } - - if (num_adaptors) - xf86XVScreenInit(pScrn, adaptors, num_adaptors); - - if (newAdaptors) - xfree(newAdaptors); - } -} - -/* client libraries expect an encoding */ static XF86VideoEncodingRec DummyEncoding[1] = { - { - 0, - "XV_IMAGE", - 1024, 1024, - {1, 1} - } + { 0, "XV_IMAGE", 1024, 1024, {1, 1} } }; -#define NUM_FORMATS 4 - -static XF86VideoFormatRec Formats[NUM_FORMATS] = { - {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +static XF86VideoFormatRec Formats[] = { + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} }; -#if DBUF -#define NUM_ATTRIBUTES 4 -#else -#define NUM_ATTRIBUTES 3 -#endif - -static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { -#if DBUF - {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, -#endif - {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, - {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, - {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} +static XF86AttributeRec Attributes[] = { + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, + {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} }; static XF86ImageRec Images[] = { - XVIMAGE_UYVY, - XVIMAGE_YUY2, - XVIMAGE_Y2YU, - XVIMAGE_YVYU, - XVIMAGE_Y800, - XVIMAGE_I420, - XVIMAGE_YV12 + XVIMAGE_UYVY, + XVIMAGE_YUY2, + XVIMAGE_Y2YU, + XVIMAGE_YVYU, + XVIMAGE_Y800, + XVIMAGE_I420, + XVIMAGE_YV12, + XVIMAGE_RGB565 }; -#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0])); - typedef struct { - FBAreaPtr area; - FBLinearPtr linear; + void *area; + int offset; RegionRec clip; CARD32 filter; CARD32 colorKey; @@ -249,1116 +98,797 @@ typedef struct CARD32 videoStatus; Time offTime; Time freeTime; -#if DBUF - Bool doubleBuffer; - int currentBuffer; -#endif -} -GeodePortPrivRec, *GeodePortPrivPtr; +} GeodePortPrivRec, *GeodePortPrivPtr; #define GET_PORT_PRIVATE(pScrni) \ (GeodePortPrivRec *)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr) -/*---------------------------------------------------------------------------- - * LXSetColorKey - * - * Description :This function reads the color key for the pallete and - * sets the video color key register. - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen pointer having screen information. - * pPriv :Video port private data - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static INT32 -LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) +static void +LXCopyFromSys(GeodeRec *pGeode, unsigned char *src, unsigned int dst, + int dstPitch, int srcPitch, int h, int w) { - int red, green, blue; - unsigned long key; - - switch (pScrni->depth) { - case 8: - vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key); - red = ((key >> 16) & 0xFF); - green = ((key >> 8) & 0xFF); - blue = (key & 0xFF); - break; - case 16: - red = (pPriv->colorKey & pScrni->mask.red) >> - pScrni->offset.red << (8 - pScrni->weight.red); - green = (pPriv->colorKey & pScrni->mask.green) >> - pScrni->offset.green << (8 - pScrni->weight.green); - blue = (pPriv->colorKey & pScrni->mask.blue) >> - pScrni->offset.blue << (8 - pScrni->weight.blue); - break; - default: - /* for > 16 bpp we send in the mask in xf86SetWeight. This - * function is providing the offset by 1 more. So we take - * this as a special case and subtract 1 for > 16 - */ - red = (pPriv->colorKey & pScrni->mask.red) >> - (pScrni->offset.red - 1) << (8 - pScrni->weight.red); - green = (pPriv->colorKey & pScrni->mask.green) >> - (pScrni->offset.green - 1) << (8 - pScrni->weight.green); - blue = (pPriv->colorKey & pScrni->mask.blue) >> - (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); - break; - } - - DBLOG(1, "LXSetColorkey() %08x %d\n", blue | (green << 8) | (red << 16), - pPriv->colorKeyMode); - if (pPriv->colorKeyMode != 0) - df_set_video_color_key((blue | (green << 8) | (red << 16)), - 0xFFFFFF, 1); - else - df_set_video_color_key(0, 0, 1); - REGION_EMPTY(pScrni->pScreen, &pPriv->clip); - - return 0; + gp_declare_blt(0); + gp_set_bpp(16); + + gp_set_raster_operation(0xCC); + gp_set_strides(dstPitch, srcPitch); + gp_set_solid_pattern(0); + + gp_color_bitmap_to_screen_blt(dst, 0, w, h, src, srcPitch); } -/*---------------------------------------------------------------------------- - * LXResetVideo - * - * Description : This function resets the video - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen pointer having screen information. - * - * Returns :None - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ - -void -LXResetVideo(ScrnInfoPtr pScrni) +static void +LXVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(1, "LXResetVideo()\n"); - - if (!pGeode->NoAccel) { - GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; - - LXAccelSync(pScrni); - df_set_video_palette(NULL); - LXSetColorkey(pScrni, pPriv); - } + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + + GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); + + if (area == pPriv->area) + pPriv->area = NULL; } -/*---------------------------------------------------------------------------- - * LXSetupImageVideo - * - * Description : This function allocates space for a Videoadaptor and initializes - * the XF86VideoAdaptorPtr record. - * - * Parameters. - * ScreenPtr - * pScrn :Screen handler pointer having screen information. - * - * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static XF86VideoAdaptorPtr -LXSetupImageVideo(ScreenPtr pScrn) +static unsigned int +LXAllocateVidMem(ScrnInfoPtr pScrni, void **memp, int size) { - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - XF86VideoAdaptorPtr adapt; - GeodePortPrivRec *pPriv; - - DBLOG(1, "LXSetupImageVideo()\n"); - - if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + - sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) - return NULL; - - adapt->type = XvWindowMask | XvInputMask | XvImageMask; - adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - adapt->name = "Advanced Micro Devices"; - adapt->nEncodings = 1; - adapt->pEncodings = DummyEncoding; - adapt->nFormats = NUM_FORMATS; - adapt->pFormats = Formats; - adapt->nPorts = 1; - adapt->pPortPrivates = (DevUnion *) (&adapt[1]); - pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); - adapt->pPortPrivates[0].ptr = (pointer) (pPriv); - adapt->pAttributes = Attributes; - adapt->nImages = NUM_IMAGES; - adapt->nAttributes = NUM_ATTRIBUTES; - adapt->pImages = Images; - adapt->PutVideo = NULL; - adapt->PutStill = NULL; - adapt->GetVideo = NULL; - adapt->GetStill = NULL; - adapt->StopVideo = LXStopVideo; - adapt->SetPortAttribute = LXSetPortAttribute; - adapt->GetPortAttribute = LXGetPortAttribute; - adapt->QueryBestSize = LXQueryBestSize; - adapt->PutImage = LXPutImage; - adapt->QueryImageAttributes = LXQueryImageAttributes; - - pPriv->filter = 0; - pPriv->colorKey = pGeode->videoKey; - pPriv->colorKeyMode = 0; - pPriv->videoStatus = 0; -#if DBUF - pPriv->doubleBuffer = TRUE; - pPriv->currentBuffer = 0; /* init to first buffer */ -#endif - - /* gotta uninit this someplace */ -#if defined(REGION_NULL) - REGION_NULL(pScrn, &pPriv->clip); -#else - REGION_INIT(pScrn, &pPriv->clip, NullBox, 0); -#endif - - pGeode->adaptor = adapt; - - pGeode->BlockHandler = pScrn->BlockHandler; - pScrn->BlockHandler = LXBlockHandler; - - xvColorKey = MAKE_ATOM("XV_COLORKEY"); - xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); - xvFilter = MAKE_ATOM("XV_FILTER"); -#if DBUF - xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); -#endif - - LXResetVideo(pScrni); - - return adapt; + ExaOffscreenArea *area = *memp; + + if (area != NULL) { + if (area->size >= size) + return area->offset; + + exaOffscreenFree(pScrni->pScreen, area); + } + + area = exaOffscreenAlloc(pScrni->pScreen, size, 16, TRUE, + LXVideoSave, NULL); + + *memp = area; + return (area == NULL) ? 0 : area->offset; } -/*---------------------------------------------------------------------------- - * LXStopVideo - * - * Description :This function is used to stop input and output video - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * exit :Flag indicating whether the offscreen areas used for video - * to be deallocated or not. - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ static void -LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) +LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(1, "LXStopVideo()\n"); - - REGION_EMPTY(pScrni->pScreen, &pPriv->clip); - - LXAccelSync(pScrni); - if (exit) { - if (pPriv->videoStatus & CLIENT_VIDEO_ON) { - df_set_video_enable(0, 0); - } - if (pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } - pPriv->videoStatus = 0; - pGeode->OverlayON = FALSE; - } else { - if (pPriv->videoStatus & CLIENT_VIDEO_ON) { - pPriv->videoStatus |= OFF_TIMER; - pPriv->offTime = currentTime.milliseconds + OFF_DELAY; - } - } + int red, green, blue; + unsigned long key; + + switch (pScrni->depth) { + case 8: + vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key); + red = ((key >> 16) & 0xFF); + green = ((key >> 8) & 0xFF); + blue = (key & 0xFF); + break; + case 16: + red = (pPriv->colorKey & pScrni->mask.red) >> + pScrni->offset.red << (8 - pScrni->weight.red); + green = (pPriv->colorKey & pScrni->mask.green) >> + pScrni->offset.green << (8 - pScrni->weight.green); + blue = (pPriv->colorKey & pScrni->mask.blue) >> + pScrni->offset.blue << (8 - pScrni->weight.blue); + break; + default: + /* for > 16 bpp we send in the mask in xf86SetWeight. This + * function is providing the offset by 1 more. So we take + * this as a special case and subtract 1 for > 16 + */ + + red = (pPriv->colorKey & pScrni->mask.red) >> + (pScrni->offset.red - 1) << (8 - pScrni->weight.red); + green = (pPriv->colorKey & pScrni->mask.green) >> + (pScrni->offset.green - 1) << (8 - pScrni->weight.green); + blue = (pPriv->colorKey & pScrni->mask.blue) >> + (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); + break; + } + + df_set_video_color_key((blue | (green << 8) | (red << 16)), + 0xFFFFFF, (pPriv->colorKeyMode == 0)); + + REGION_EMPTY(pScrni->pScreen, &pPriv->clip); } -/*---------------------------------------------------------------------------- - * LXSetPortAttribute - * - * Description :This function is used to set the attributes of a port like colorkeymode, - * double buffer support and filter. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * attribute :The port attribute to be set - * value :Value of the attribute to be set. - * - * Returns :Sucess if the attribute is supported, else BadMatch - * - * Comments :none - * -*---------------------------------------------------------------------------- +/* A structure full of the scratch information that originates in the copy routines, + but is needed for the video display - maybe we should figure out a way to attach + this to structures? I hate to put it in pGeode since it will increase the size of + the structure, and possibly cause us cache issues. */ -static int -LXSetPortAttribute(ScrnInfoPtr pScrni, - Atom attribute, INT32 value, pointer data) -{ - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - DBLOG(1, "LXSetPortAttribute(%d,%#x)\n", attribute, value); +struct { + unsigned int dstOffset; + unsigned int dstPitch; + unsigned int UVPitch; + unsigned int UDstOffset; + unsigned int VDstOffset; +} videoScratch; - LXAccelSync(pScrni); - if (attribute == xvColorKey) { - pPriv->colorKey = value; - LXSetColorkey(pScrni, pPriv); - } -#if DBUF - else if (attribute == xvDoubleBuffer) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->doubleBuffer = value; - } -#endif - else if (attribute == xvColorKeyMode) { - pPriv->colorKeyMode = value; - LXSetColorkey(pScrni, pPriv); - } else if (attribute == xvFilter) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->filter = value; - } else - return BadMatch; +/* Copy planar YUV data */ - return Success; +static Bool +LXCopyPlanar(ScrnInfoPtr pScrni, int id, unsigned char *buf, + short x1, short y1, short x2, short y2, + int width, int height, pointer data) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + unsigned int YSrcPitch, YDstPitch; + unsigned int UVSrcPitch, UVDstPitch; + unsigned int YSrcOffset, YDstOffset; + unsigned int USrcOffset, UDstOffset; + unsigned int VSrcOffset, VDstOffset; + + unsigned int size, lines, top, left, pixels; + + YSrcPitch = (width + 3) & ~3; + YDstPitch = (width + 31) & ~31; + + UVSrcPitch = ((width >> 1) + 3) & ~3; + UVDstPitch = ((width >> 1) + 15) & ~15; + + if (id != FOURCC_I420) { + VSrcOffset = YSrcPitch * height; + USrcOffset = VSrcOffset + (UVSrcPitch * (height >> 1)); + + VDstOffset = YDstPitch * height; + UDstOffset = VDstOffset + (UVDstPitch * (height >> 1)); + } + else { + USrcOffset = YSrcPitch * height; + VSrcOffset = USrcOffset + (UVSrcPitch * (height >> 1)); + + UDstOffset = YDstPitch * height; + VDstOffset = UDstOffset + (UVDstPitch * (height >> 1)); + } + + size = YDstPitch * height; + size += UVDstPitch * height; + + pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, size); + + if (pPriv->offset == 0) { + ErrorF("Error allocating an offscreen region.\n"); + return FALSE; + } + + /* The top of the source region we want to copy */ + top = y1 & ~1; + + /* The left hand side of the source region, aligned on a word */ + left = x1 & ~1; + + /* Number of bytes to copy, also word aligned */ + pixels = ((x2 + 1) & ~1) - left; + + /* Calculate the source offset */ + YSrcOffset = (top * YSrcPitch) + left; + USrcOffset += ((top >> 1) * UVSrcPitch) + (left >> 1); + VSrcOffset += ((top >> 1) * UVSrcPitch) + (left >> 1); + + /* Calculate the destination offset */ + YDstOffset = (top * YDstPitch) + left; + UDstOffset += ((top >> 1) * UVDstPitch) + (left >> 1); + VDstOffset += ((top >> 1) * UVDstPitch) + (left >> 1); + + lines = ((y2 + 1) & ~1) - top; + + /* Copy Y */ + + LXCopyFromSys(pGeode, buf + YSrcOffset, pPriv->offset + YDstOffset, + YDstPitch, YSrcPitch, lines, pixels); + + /* Copy U + V at the same time */ + + LXCopyFromSys(pGeode, buf + USrcOffset, pPriv->offset + UDstOffset, + UVDstPitch, UVSrcPitch, lines, pixels >> 1); + + /* Copy V */ + + //LXCopyFromSys(pGeode, buf + VSrcOffset, pPriv->offset + VDstOffset, + //UVDstPitch, UVSrcPitch, lines >> 1, pixels >> 1); + + videoScratch.dstOffset = pPriv->offset + YDstOffset; + videoScratch.dstPitch = YDstPitch; + videoScratch.UVPitch = UVDstPitch; + videoScratch.UDstOffset = pPriv->offset + UDstOffset; + videoScratch.VDstOffset = pPriv->offset + VDstOffset; + + return TRUE; } -/*---------------------------------------------------------------------------- - * LXGetPortAttribute - * - * Description :This function is used to get the attributes of a port like hue, - * saturation,brightness or contrast. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * attribute :The port attribute to be read - * value :Pointer to the value of the attribute to be read. - * - * Returns :Sucess if the attribute is supported, else BadMatch - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static int -LXGetPortAttribute(ScrnInfoPtr pScrni, - Atom attribute, INT32 * value, pointer data) +static Bool +LXCopyPacked(ScrnInfoPtr pScrni, int id, unsigned char *buf, + short x1, short y1, short x2, short y2, + int width, int height, pointer data) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - - DBLOG(1, "LXGetPortAttribute(%d)\n", attribute); - - if (attribute == xvColorKey) { - *value = pPriv->colorKey; - } -#if DBUF - else if (attribute == xvDoubleBuffer) { - *value = (pPriv->doubleBuffer) ? 1 : 0; - } -#endif - else if (attribute == xvColorKeyMode) { - *value = pPriv->colorKeyMode; - } else if (attribute == xvFilter) { - *value = pPriv->filter; - } else - return BadMatch; - - return Success; + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + GeodeRec *pGeode = GEODEPTR(pScrni); + unsigned int dstPitch, srcPitch; + unsigned int srcOffset, dstOffset; + unsigned int lines, top, left, pixels; + + dstPitch = ((width << 1) + 3) & ~3; + srcPitch = (width << 1); + + lines = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; + + pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, height * dstPitch); + + if (pPriv->offset == 0) { + ErrorF("Error while allocating an offscreen region.\n"); + return FALSE; + } + + /* The top of the source region we want to copy */ + top = y1; + + /* The left hand side of the source region, aligned on a word */ + left = x1 & ~1; + + /* Number of bytes to copy, also word aligned */ + pixels = ((x2 + 1) & ~1) - left; + + /* Adjust the incoming buffer */ + srcOffset = (top * srcPitch) + left; + + /* Calculate the destination offset */ + dstOffset = pPriv->offset + (top * dstPitch) + left; + + /* Make the copy happen */ + + if (id == FOURCC_Y800) { + + /* Use the shared (unaccelerated) greyscale copy - you could probably + accelerate it using a 2 pass blit and patterns, but it doesn't really + seem worth it + */ + + GeodeCopyGreyscale(buf + srcOffset, pGeode->FBBase + dstOffset, srcPitch, dstPitch, + height, pixels >> 1); + } + else + LXCopyFromSys(pGeode, buf + srcOffset, dstOffset, dstPitch, srcPitch, height, pixels); + + videoScratch.dstOffset = dstOffset; + videoScratch.dstPitch = dstPitch; + + return TRUE; } -/*---------------------------------------------------------------------------- - * LXQueryBestSize - * - * Description : - * This function provides a way to query what the destination dimensions - * would end up being if they were to request that an area vid_w by vid_h - * from the video stream be scaled to rectangle of drw_w by drw_h on - * the screen. - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * vid_w,vid_h :Width and height of the video data. - * drw_w,drw_h :Width and height of the scaled rectangle. - * p_w,p_h :Width and height of the destination rectangle. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static void -LXQueryBestSize(ScrnInfoPtr pScrni, Bool motion, short vid_w, short vid_h, - short drw_w, short drw_h, unsigned int *p_w, - unsigned int *p_h, pointer data) +void +LXDisplayVideo(ScrnInfoPtr pScrni, int id, short width, short height, + BoxPtr dstBox, short srcW, short srcH, short drawW, short drawH) { - *p_w = drw_w; - *p_h = drw_h; - - if (*p_w > 16384) - *p_w = 16384; - - DBLOG(1, "LXQueryBestSize(%d, src %dx%d scl %dx%d dst %dx%d)\n", motion, - vid_w, vid_h, drw_w, drw_h, *p_w, *p_h); + long ystart, xend, yend; + unsigned long lines = 0; + unsigned long yExtra, uvExtra = 0; + DF_VIDEO_POSITION vidPos; + DF_VIDEO_SOURCE_PARAMS vSrcParams; + + gp_wait_until_idle(); + + switch(id) { + case FOURCC_UYVY: + vSrcParams.video_format = DF_VIDFMT_UYVY; + break; + + case FOURCC_Y800: + case FOURCC_YV12: + case FOURCC_I420: + vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; + break; + case FOURCC_YUY2: + vSrcParams.video_format = DF_VIDFMT_YUYV; + break; + case FOURCC_Y2YU: + vSrcParams.video_format = DF_VIDFMT_Y2YU; + break; + case FOURCC_YVYU: + vSrcParams.video_format = DF_VIDFMT_YVYU; + break; + case FOURCC_RGB565: + vSrcParams.video_format = DF_VIDFMT_RGB; + break; + } + + vSrcParams.width = width; + vSrcParams.height = height; + vSrcParams.y_pitch = videoScratch.dstPitch; + vSrcParams.uv_pitch = videoScratch.UVPitch; + + /* Set up scaling */ + df_set_video_filter_coefficients(NULL, 1); + + if ((drawW >= srcW) && (drawH >= srcH)) + df_set_video_scale(width, height, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + else if (drawW < srcW) + df_set_video_scale(drawW, height, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + else if (drawH < srcH) + df_set_video_scale(width, drawH, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + + /* Figure out clipping */ + + xend = dstBox->x2; + yend = dstBox->y2; + + if (dstBox->y1 < 0) { + if (srcH < drawH) + lines = ((-dstBox->y1) * srcH) / drawH; + else + lines = (-dstBox->y1); + + ystart = 0; + drawH += dstBox->y1; + } + else { + ystart = dstBox->y1; + lines = 0; + } + + yExtra = lines * videoScratch.dstPitch; + uvExtra = (lines >> 1) * videoScratch.UVPitch; + + memset(&vidPos, 0, sizeof(vidPos)); + + vidPos.x = dstBox->x1; + vidPos.y = ystart; + vidPos.width = xend - dstBox->x1; + vidPos.height = yend - ystart; + + df_set_video_position(&vidPos); + + vSrcParams.y_offset = videoScratch.dstOffset + yExtra; + + switch(id) { + case FOURCC_Y800: + case FOURCC_I420: + case FOURCC_YV12: + vSrcParams.u_offset = videoScratch.UDstOffset + uvExtra; + vSrcParams.v_offset = videoScratch.VDstOffset + uvExtra; + break; + + default: + vSrcParams.u_offset = vSrcParams.v_offset = 0; + break; + } + + vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING; + df_configure_video_source(&vSrcParams, &vSrcParams); + df_set_video_enable(1, 0); } -static void -LXCopyGreyscale(unsigned char *src, unsigned char *dst, int srcp, int dstp, - int h, int w) +static int +LXPutImage(ScrnInfoPtr pScrni, + short srcX, short srcY, short drawX, short drawY, + short srcW, short srcH, short drawW, short drawH, + int id, unsigned char *buf, + short width, short height, Bool sync, RegionPtr clipBoxes, + pointer data, DrawablePtr pDraw) { - int i; - unsigned char *src2 = src; - unsigned char *dst2 = dst; - unsigned char *dst3; - unsigned char *src3; - - dstp <<= 1; - - while (h--) { - dst3 = dst2; - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - dst2 += dstp; - src2 += srcp; + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + INT32 x1,x2,y1,y2; + BoxRec dstBox; + + if (srcW <= 0 || srcH <= 0) { + ErrorF("Nothing to draw!\n"); + return Success; + } + + if (drawW <= 0 || drawH <=0) { + ErrorF("Nothing to show!\n"); + return Success; + } + + if (drawW > 16384) + drawW = 16384; + + x1 = srcX; + x2 = srcX + srcW; + y1 = srcY; + y2 = srcY + srcH; + + dstBox.x1 = drawX; + dstBox.x2 = drawX + drawW; + dstBox.y1 = drawY; + dstBox.y2 = drawY + drawH; + + dstBox.x1 -= pScrni->frameX0; + dstBox.x2 -= pScrni->frameX0; + dstBox.y1 -= pScrni->frameY0; + dstBox.y2 -= pScrni->frameY0; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + LXCopyPlanar(pScrni, id, buf, x1, y1, x2, y2, width, height, data); + break; + + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + case FOURCC_RGB565: + LXCopyPacked(pScrni, id, buf, x1, y1, x2, y2, width, height, data); + break; + } + + if (!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); + + if (pPriv->colorKeyMode == 0) { + xf86XVFillKeyHelper(pScrni->pScreen, pPriv->colorKey, clipBoxes); } + + LXDisplayVideo(pScrni, id, width, height, &dstBox, + srcW, srcH, drawW, drawH); + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + pGeode->OverlayON = TRUE; + + return Success; } -/*---------------------------------------------------------------------------- - * LXCopyData420 - * - * Description : Copies data from src to destination - * - * Parameters. - * src : pointer to the source data - * dst : pointer to destination data - * srcp : pitch of the srcdata - * dstp : pitch of the destination data - * h & w : height and width of source data - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ - static void -LXCopyData420(unsigned char *src, unsigned char *dst, int srcp, int dstp, - int h, int w) +LXQueryBestSize(ScrnInfoPtr pScrni, Bool motion, + short vidW, short vidH, short drawW, short drawH, + unsigned int *retW, unsigned int *retH, pointer data) { - while (h--) { - memcpy(dst, src, w); - src += srcp; - dst += dstp; - } + *retW = drawW > 16384 ? 16384 : drawW; + *retH = drawH; } - -/*---------------------------------------------------------------------------- - * LXCopyData422 - * - * Description : Copies data from src to destination - * - * Parameters. - * src : pointer to the source data - * dst : pointer to destination data - * srcp : pitch of the srcdata - * dstp : pitch of the destination data - * h & w : height and width of source data - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ - -static void -LXCopyData422(unsigned char *src, unsigned char *dst, - int srcp, int dstp, int h, int w) + +static Atom xvColorKey, xvColorKeyMode, xvFilter; + +static int +LXGetPortAttribute(ScrnInfoPtr pScrni, + Atom attribute, INT32 * value, pointer data) { - w <<= 1; - while (h--) { - memcpy(dst, src, w); - src += srcp; - dst += dstp; - } + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + if (attribute == xvColorKey) + *value = pPriv->colorKey; + else if (attribute == xvColorKeyMode) + *value = pPriv->colorKeyMode; + else if (attribute == xvFilter) + *value = pPriv->filter; + else + return BadMatch; + + return Success; } -static FBAreaPtr -LXAllocateMemory(ScrnInfoPtr pScrni, FBAreaPtr area, int numlines) +static int +LXSetPortAttribute(ScrnInfoPtr pScrni, + Atom attribute, INT32 value, pointer data) { - ScreenPtr pScrn = screenInfo.screens[pScrni->scrnIndex]; - FBAreaPtr new_area; + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + gp_wait_until_idle(); + + if (attribute == xvColorKey) { + pPriv->colorKey = value; + LXSetColorkey(pScrni, pPriv); + } + else if (attribute == xvColorKeyMode) { + pPriv->colorKeyMode = value; + LXSetColorkey(pScrni, pPriv); + } + else if (attribute == xvFilter) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->filter = value; + } + else + return BadMatch; + + return Success; +} - if (area) { - if ((area->box.y2 - area->box.y1) >= numlines) - return area; +void +LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) +{ + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (xf86ResizeOffscreenArea(area, pScrni->displayWidth, numlines)) - return area; + REGION_EMPTY(pScrni->pScreen, &pPriv->clip); + gp_wait_until_idle(); - xf86FreeOffscreenArea(area); + if (exit) { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + df_set_video_enable(0,0); + df_set_video_palette(NULL); } - new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth, - numlines, 0, NULL, NULL, NULL); - - if (!new_area) { - int max_w, max_h; - - xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0, - FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); + if (pPriv->area) + exaOffscreenFree(pScrni->pScreen, pPriv->area); - if ((max_w < pScrni->displayWidth) || (max_h < numlines)) - return NULL; + pPriv->videoStatus = 0; - xf86PurgeUnlockedOffscreenAreas(pScrn); - new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth, - numlines, 0, NULL, NULL, NULL); + /* Eh? */ + pGeode->OverlayON = FALSE; + } + else { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; } - - return new_area; + } } - -static BoxRec dstBox; -static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; -static INT32 Bx1, Bx2, By1, By2; -static int top, left, npixels, nlines; -static int offset, s1offset = 0, s2offset = 0, s3offset = 0; -static unsigned char *dst_start; -static int d2offset = 0, d3offset = 0; - -static DF_VIDEO_SOURCE_PARAMS vSrcParams; - + void -LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, short drw_h, - int id, int offset, ScrnInfoPtr pScrni) +LXResetVideo(ScrnInfoPtr pScrni) { - long ystart, xend, yend; - unsigned long lines = 0; - unsigned long y_extra, uv_extra = 0; - DF_VIDEO_POSITION vidPos; - - DBLOG(1, "LXSetVideoPosition(%d,%d %dx%d, src %dx%d, dst %dx%d, id %d, " - "ofs %d)\n", x, y, width, height, src_w, src_h, drw_w, drw_h, - id, offset); - - xend = x + drw_w; - yend = y + drw_h; - - /* TOP CLIPPING */ - - if (y < 0) { - if (src_h < drw_h) - lines = (-y) * src_h / drw_h; - else - lines = (-y); - ystart = 0; - drw_h += y; - y_extra = lines * dstPitch; - uv_extra = (lines >> 1) * (dstPitch2); - } else { - ystart = y; - lines = 0; - y_extra = 0; - } - - memset(&vidPos, 0, sizeof(vidPos)); - vidPos.x = x; - vidPos.y = ystart; - vidPos.width = xend - x; - vidPos.height = yend - ystart; - - DBLOG(1, "video_pos %d,%d %dx%d\n", vidPos.x, vidPos.y, vidPos.width, - vidPos.height); - df_set_video_position(&vidPos); - - vSrcParams.y_offset = offset + y_extra; - if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { - vSrcParams.u_offset = offset + d3offset + uv_extra; - vSrcParams.v_offset = offset + d2offset + uv_extra; - } else { - vSrcParams.u_offset = vSrcParams.v_offset = 0; - } - vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING; - - DBLOG(1, "video_format %#x yofs %#x uofs %#x vofs %#x yp %d uvp %d wh " - "%dx%d flg %#x\n", vSrcParams.video_format, vSrcParams.y_offset, - vSrcParams.u_offset, vSrcParams.v_offset, vSrcParams.y_pitch, - vSrcParams.uv_pitch, vSrcParams.width, vSrcParams.height, - vSrcParams.flags); + GeodeRec *pGeode = GEODEPTR(pScrni); - df_configure_video_source(&vSrcParams, &vSrcParams); -} + if (!pGeode->NoAccel) { + GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; -/*---------------------------------------------------------------------------- - * LXDisplayVideo - * - * Description : This function sets up the video registers for playing video - * It sets up the video format,width, height & position of the - * video window ,video offsets( y,u,v) and video pitches(y,u,v) - * Parameters. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ + gp_wait_until_idle(); + df_set_video_palette(NULL); -static void -LXDisplayVideo(ScrnInfoPtr pScrni, int id, int offset, short width, - short height, int pitch, int x1, int y1, int x2, int y2, - BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h) -{ - DBLOG(1, "LXDisplayVideo(id %d, ofs %d, %dx%d, p %d, %d,%d, %d,%d, src " - "%dx%d dst %dx%d)\n", id, offset, width, height, pitch, x1, y1, - x2, y2, src_w, src_h, drw_w, drw_h); - - LXAccelSync(pScrni); - - switch (id) { - case FOURCC_UYVY: - vSrcParams.video_format = DF_VIDFMT_UYVY; - break; - case FOURCC_Y800: - case FOURCC_YV12: - case FOURCC_I420: - vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; - break; - case FOURCC_YUY2: - vSrcParams.video_format = DF_VIDFMT_YUYV; - break; - case FOURCC_Y2YU: - vSrcParams.video_format = DF_VIDFMT_Y2YU; - break; - case FOURCC_YVYU: - vSrcParams.video_format = DF_VIDFMT_YVYU; - break; + LXSetColorkey(pScrni, pPriv); } - - vSrcParams.width = width; - vSrcParams.height = height; - vSrcParams.y_pitch = dstPitch; - vSrcParams.uv_pitch = dstPitch2; - - df_set_video_filter_coefficients(NULL, 1); - if ((drw_w >= src_w) && (drw_h >= src_h)) - df_set_video_scale(width, height, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - else if (drw_w < src_w) - df_set_video_scale(drw_w, height, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - else if (drw_h < src_h) - df_set_video_scale(width, drw_h, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - - LXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, - src_h, drw_w, drw_h, id, offset, pScrni); - - df_set_video_enable(1, 0); } -#if REINIT -static Bool -RegionsEqual(RegionPtr A, RegionPtr B) +static void +LXVidBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) { - int *dataA, *dataB; - int num; - - num = REGION_NUM_RECTS(A); - if (num != REGION_NUM_RECTS(B)) { - return FALSE; - } - - if ((A->extents.x1 != B->extents.x1) || - (A->extents.x2 != B->extents.x2) || - (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) - return FALSE; + ScreenPtr pScrn = screenInfo.screens[i]; + ScrnInfoPtr pScrni = xf86Screens[i]; + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); - dataA = (int *)REGION_RECTS(A); - dataB = (int *)REGION_RECTS(B); + pScrn->BlockHandler = pGeode->BlockHandler; + (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScrn->BlockHandler = LXVidBlockHandler; - while (num--) { - if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) - return FALSE; - dataA += 2; - dataB += 2; + if (pPriv->videoStatus & TIMER_MASK) { + Time now = currentTime.milliseconds; + + if (pPriv->videoStatus & OFF_TIMER) { + gp_wait_until_idle(); + + if (pPriv->offTime < now) { + df_set_video_enable(0, 0); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = now + FREE_DELAY; + } + } + else { + if (pPriv->freeTime < now) { + if (pPriv->area) { + exaOffscreenFree(pScrni->pScreen, pPriv->area); + pPriv->area = NULL; + } + + pPriv->videoStatus = 0; + } + } } - - return TRUE; } -#endif - -/*---------------------------------------------------------------------------- - * LXPutImage : - * This function writes a single frame of video into a drawable. - * The position and size of the source rectangle is specified by src_x,src_y, - * src_w and src_h. This data is stored in a system memory buffer at buf. - * The position and size of the destination rectangle is specified by drw_x, - * drw_y,drw_w,drw_h.The data is in the format indicated by the image - * descriptor and represents a source of size width by height. If sync is - * TRUE the driver should not return from this function until it is through - * reading the data from buf. Returning when sync is TRUE indicates that - * it is safe for the data at buf to be replaced,freed, or modified. - * - * Description : - * Parameters. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int -LXPutImage(ScrnInfoPtr pScrni, short src_x, short src_y, short drw_x, - short drw_y, short src_w, short src_h, short drw_w, short drw_h, - int id, unsigned char *buf, short width, short height, Bool sync, - RegionPtr clipBoxes, pointer data) +static XF86VideoAdaptorPtr +LXSetupImageVideo(ScreenPtr pScrn) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - GeodeRec *pGeode = GEODEPTR(pScrni); - int new_h; - -#if REINIT - BOOL ReInitVideo = FALSE; - static BOOL DoReinitAgain = 0; -#endif - -#if XV_PROFILE - long oldtime, newtime; - - UpdateCurrentTime(); - oldtime = currentTime.milliseconds; -#endif - DBLOG(1, "LXPutImage(src %d,%d %dx%d dst %d,%d %dx%d, id %d %dx%d sync " - "%d)\n", src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, - id, width, height, sync); - -#if REINIT - /* update cliplist */ - if (!RegionsEqual(&pPriv->clip, clipBoxes)) { - ReInitVideo = TRUE; - } - - if (DoReinitAgain) - ReInitVideo = TRUE; - - if (ReInitVideo) { - DBLOG(1, "Regional Not Equal - Init\n"); -#endif - DoReinitAgain = ~DoReinitAgain; - if (drw_w > 16384) - drw_w = 16384; - - /* Clip */ - Bx1 = src_x; - Bx2 = src_x + src_w; - By1 = src_y; - By2 = src_y + src_h; - - if ((Bx1 >= Bx2) || (By1 >= By2)) - return Success; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - - dstBox.x1 -= pScrni->frameX0; - dstBox.x2 -= pScrni->frameX0; - dstBox.y1 -= pScrni->frameY0; - dstBox.y2 -= pScrni->frameY0; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - srcPitch = (width + 3) & ~3; /* of luma */ - dstPitch = (width + 31) & ~31; - - s2offset = srcPitch * height; - d2offset = dstPitch * height; - - srcPitch2 = ((width >> 1) + 3) & ~3; - dstPitch2 = ((width >> 1) + 15) & ~15; - - s3offset = (srcPitch2 * (height >> 1)) + s2offset; - d3offset = (dstPitch2 * (height >> 1)) + d2offset; - - new_h = dstPitch * height; /* Y */ - new_h += (dstPitch2 * height); /* U+V */ - new_h += pGeode->Pitch - 1; - new_h /= pGeode->Pitch; - break; - - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - dstPitch = ((width << 1) + 3) & ~3; - srcPitch = (width << 1); - new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; - break; - } - -#if DBUF - if (pPriv->doubleBuffer) - new_h <<= 1; -#endif - - if (!(pPriv->area = LXAllocateMemory(pScrni, pPriv->area, new_h))) - return BadAlloc; - - /* copy data */ - top = By1; - left = Bx1 & ~1; - npixels = ((Bx2 + 1) & ~1) - left; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420:{ - int tmp; - - top &= ~1; - offset = (pPriv->area->box.y1 * pGeode->Pitch) + - (top * dstPitch); - -#if DBUF - if (pPriv->doubleBuffer && pPriv->currentBuffer) - offset += (new_h >> 1) * pGeode->Pitch; -#endif - - dst_start = pGeode->FBBase + offset + left; - tmp = ((top >> 1) * srcPitch2) + (left >> 1); - s2offset += tmp; - s3offset += tmp; - if (id == FOURCC_I420) { - tmp = s2offset; - s2offset = s3offset; - s3offset = tmp; - } - nlines = ((By2 + 1) & ~1) - top; - } - break; - - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - left <<= 1; - buf += (top * srcPitch) + left; - nlines = By2 - top; - offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch); -#if DBUF - if (pPriv->doubleBuffer && pPriv->currentBuffer) - offset += (new_h >> 1) * pGeode->Pitch; -#endif + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + XF86VideoAdaptorPtr adapt; + GeodePortPrivRec *pPriv; + + adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(GeodePortPrivRec) + sizeof(DevUnion)); + + if (adapt == NULL) { + ErrorF("Couldn't create the rec\n"); + return NULL; + } + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + + adapt->name = "AMD Geode LX"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = ARRAY_SIZE(Formats); + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion *) (&adapt[1]); + pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer) (pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = ARRAY_SIZE(Images); + adapt->nAttributes = ARRAY_SIZE(Attributes); + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo= LXStopVideo; + adapt->SetPortAttribute = LXSetPortAttribute; + adapt->GetPortAttribute = LXGetPortAttribute; + adapt->QueryBestSize = LXQueryBestSize; + adapt->PutImage =LXPutImage; + + /* Use the common function */ + adapt->QueryImageAttributes = GeodeQueryImageAttributes; + + pPriv->filter = 0; + pPriv->colorKey = pGeode->videoKey; + pPriv->colorKeyMode = 0; + pPriv->videoStatus = 0; + + REGION_NULL(pScrn, &pPriv->clip); + + pGeode->adaptor = adapt; + + pGeode->BlockHandler = pScrn->BlockHandler; + pScrn->BlockHandler = LXVidBlockHandler; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); + xvFilter = MAKE_ATOM("XV_FILTER"); + + LXResetVideo(pScrni); + + return adapt; +} - dst_start = pGeode->FBBase + offset + left; - break; - } - s1offset = (top * srcPitch) + left; - -#if REINIT - /* update cliplist */ - REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); - if (pPriv->colorKeyMode == 0) { - /* draw these */ - XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, - REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); - } - LXDisplayVideo(pScrni, id, offset, width, height, dstPitch, - Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); - } -#endif +/* Offscreen surface allocation */ - switch (id) { - case FOURCC_Y800: - LXCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); - break; - case FOURCC_YV12: - case FOURCC_I420: - LXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, - npixels); - LXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, - dstPitch2, nlines >> 1, npixels >> 1); - LXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, - dstPitch2, nlines >> 1, npixels >> 1); - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - LXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); - break; - } -#if !REINIT - /* update cliplist */ - REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); - if (pPriv->colorKeyMode == 0) { - /* draw these */ - XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, - REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); - } - LXDisplayVideo(pScrni, id, offset, width, height, dstPitch, - Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); -#endif +struct OffscreenPrivRec +{ + void * area; + int offset; + Bool isOn; +}; -#if XV_PROFILE - UpdateCurrentTime(); - newtime = currentTime.milliseconds; - DBLOG(1, "PI %d\n", newtime - oldtime); -#endif +static int +LXDisplaySurface(XF86SurfacePtr surface, + short srcX, short srcY, short drawX, short drawY, + short srcW, short srcH, short drawW, short drawH, + RegionPtr clipBoxes) +{ + struct OffscreenPrivRec *pPriv = + (struct OffscreenPrivRec *) surface->devPrivate.ptr; -#if DBUF - pPriv->currentBuffer ^= 1; -#endif + ScrnInfoPtr pScrni = surface->pScrn; + GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); + + BoxRec dstBox; - pPriv->videoStatus = CLIENT_VIDEO_ON; - pGeode->OverlayON = TRUE; + dstBox.x1 = drawX; + dstBox.x2 = drawX + drawW; + dstBox.y1 = drawY; + dstBox.y2 = drawY + drawH; + if ((drawW <= 0) | (drawH <=0)) return Success; -} -/*---------------------------------------------------------------------------- - * LXQueryImageAttributes - * - * Description :This function is called to let the driver specify how data - * for a particular image of size width by height should be - * stored. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * id :Id for the video format - * width :width of the image (can be modified by the driver) - * height :height of the image (can be modified by the driver) - * Returns : Size of the memory required for storing this image - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int -LXQueryImageAttributes(ScrnInfoPtr pScrni, int id, unsigned short *w, - unsigned short *h, int *pitches, int *offsets) -{ - int size; - int tmp; - - if (*w > 1024) - *w = 1024; - if (*h > 1024) - *h = 1024; - - *w = (*w + 1) & ~1; - if (offsets) - offsets[0] = 0; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - *h = (*h + 1) & ~1; - size = (*w + 3) & ~3; - if (pitches) - pitches[0] = size; - size *= *h; - if (offsets) - offsets[1] = size; - tmp = ((*w >> 1) + 3) & ~3; - if (pitches) - pitches[1] = pitches[2] = tmp; - tmp *= (*h >> 1); - size += tmp; - if (offsets) - offsets[2] = size; - size += tmp; - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - size = *w << 1; - if (pitches) - pitches[0] = size; - size *= *h; - break; - } + /* Is this still valid? */ - DBLOG(1, "LXQueryImageAttributes(%d)= %d, %dx%d %d/%d/%d %d/%d/%d\n", - id, size, *w, *h, pitches[0], pitches[1], pitches[2], offsets[0], - offsets[1], offsets[2]); + dstBox.x1 -= pScrni->frameX0; + dstBox.x2 -= pScrni->frameX0; + dstBox.y1 -= pScrni->frameY0; + dstBox.y2 -= pScrni->frameY0; - return size; -} - -static void -LXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) -{ - ScreenPtr pScrn = screenInfo.screens[i]; - ScrnInfoPtr pScrni = xf86Screens[i]; - GeodeRec *pGeode = GEODEPTR(pScrni); - GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); + xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); - pScrn->BlockHandler = pGeode->BlockHandler; - (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask); - pScrn->BlockHandler = LXBlockHandler; + videoScratch.dstOffset = surface->offsets[0]; + videoScratch.dstPitch = surface->pitches[0]; - if (pPriv->videoStatus & TIMER_MASK) { - DBLOG(1, "LXBlockHandler(%d)\n", i); - LXAccelSync(pScrni); - UpdateCurrentTime(); - if (pPriv->videoStatus & OFF_TIMER) { - if (pPriv->offTime < currentTime.milliseconds) { - df_set_video_enable(0, 0); - pPriv->videoStatus = FREE_TIMER; - pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - } else { /* FREE_TIMER */ - if (pPriv->freeTime < currentTime.milliseconds) { - if (pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } - pPriv->videoStatus = 0; - } - } - } -} + LXDisplayVideo(pScrni, surface->id, surface->width, surface->height, + &dstBox, srcW, srcH, drawW, drawH); -/****************** Offscreen stuff ***************/ + pPriv->isOn = TRUE; + + if (portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrni->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } -typedef struct -{ - FBAreaPtr area; - FBLinearPtr linear; - Bool isOn; + return Success; } -OffscreenPrivRec, *OffscreenPrivPtr; - -/*---------------------------------------------------------------------------- - * LXAllocateSurface - * - * Description :This function allocates an area of w by h in the offscreen - * Parameters. - * pScrni :Screen handler pointer having screen information. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int +static int LXAllocateSurface(ScrnInfoPtr pScrni, int id, unsigned short w, - unsigned short h, XF86SurfacePtr surface) + unsigned short h, XF86SurfacePtr surface) { - FBAreaPtr area; - int pitch, fbpitch, numlines; - OffscreenPrivRec *pPriv; + GeodeRec *pGeode = GEODEPTR(pScrni); + void * area = NULL; + int pitch, lines; + unsigned offset; + struct OffscreenPrivRec *pPriv; - DBLOG(1, "LXAllocateSurface(id %d, %dx%d)\n", id, w, h); + if (w > 1024 || h > 1024) + return BadAlloc; - if ((w > 1024) || (h > 1024)) - return BadAlloc; + /* The width needs to be word aligned */ + w = (w + 1) & ~1; - w = (w + 1) & ~1; - pitch = ((w << 1) + 15) & ~15; - fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3; - numlines = ((pitch * h) + fbpitch - 1) / fbpitch; + pitch = ((w << 1) + 15) & ~15; + lines = ((pitch * h) + (pGeode->Pitch - 1)) / pGeode->Pitch; + + offset = LXAllocateVidMem(pScrni, &area, lines); - if (!(area = LXAllocateMemory(pScrni, NULL, numlines))) - return BadAlloc; + if (offset == 0) { + ErrorF("Error while allocating an offscreen region.\n"); + return BadAlloc; + } - surface->width = w; - surface->height = h; + surface->width = w; + surface->height = h; + + surface->pitches = xalloc(sizeof(int)); - if (!(surface->pitches = xalloc(sizeof(int)))) - return BadAlloc; - if (!(surface->offsets = xalloc(sizeof(int)))) { - xfree(surface->pitches); - return BadAlloc; - } - if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { - xfree(surface->pitches); - xfree(surface->offsets); - return BadAlloc; - } + surface->offsets = xalloc(sizeof(int)); + + pPriv = xalloc(sizeof(struct OffscreenPrivRec)); + if (pPriv && surface->pitches && surface->offsets) { + pPriv->area = area; + pPriv->offset = offset; + pPriv->isOn = FALSE; - + surface->pScrn = pScrni; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = area->box.y1 * fbpitch; + surface->offsets[0] = offset; surface->devPrivate.ptr = (pointer) pPriv; - + return Success; + } + + if (surface->offsets) + xfree(surface->offsets); + + if (surface->pitches) + xfree(surface->pitches); + + if (area) + exaOffscreenFree(pScrni->pScreen, area); + + return BadAlloc; } static int -LXStopSurface(XF86SurfacePtr surface) +LXStopSurface(XF86SurfacePtr surface) { - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; + struct OffscreenPrivRec *pPriv = (struct OffscreenPrivRec *) + surface->devPrivate.ptr; - DBLOG(1, "LXStopSurface()\n"); - - if (pPriv->isOn) { - pPriv->isOn = FALSE; - } - - return Success; + pPriv->isOn = FALSE; + return Success; } static int LXFreeSurface(XF86SurfacePtr surface) { - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; - - DBLOG(1, "LXFreeSurface()\n"); + struct OffscreenPrivRec *pPriv = (struct OffscreenPrivRec *) + surface->devPrivate.ptr; + ScrnInfoPtr pScrni = surface->pScrn; - if (pPriv->isOn) - LXStopSurface(surface); + if (pPriv->isOn) + LXStopSurface(surface); - xf86FreeOffscreenArea(pPriv->area); - xfree(surface->pitches); - xfree(surface->offsets); - xfree(surface->devPrivate.ptr); + if (pPriv->area) + exaOffscreenFree(pScrni->pScreen, pPriv->area); - return Success; + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + + return Success; } static int @@ -1375,98 +905,78 @@ LXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value) (pointer) (GET_PORT_PRIVATE(pScrni))); } -static int -LXDisplaySurface(XF86SurfacePtr surface, short src_x, short src_y, - short drw_x, short drw_y, short src_w, short src_h, - short drw_w, short drw_h, RegionPtr clipBoxes) -{ - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; - ScrnInfoPtr pScrni = surface->pScrn; - GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); - INT32 x1, y1, x2, y2; - BoxRec dstBox; - - DBLOG(1, "LXDisplaySurface(src %d,%d %dx%d, dst %d,%d %dx%d)\n", - src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h); - - DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); - x1 = src_x; - x2 = src_x + src_w; - y1 = src_y; - y2 = src_y + src_h; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - - if ((x1 >= x2) || (y1 >= y2)) - return Success; - - dstBox.x1 -= pScrni->frameX0; - dstBox.x2 -= pScrni->frameX0; - dstBox.y1 -= pScrni->frameY0; - dstBox.y2 -= pScrni->frameY0; - - xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); - - LXDisplayVideo(pScrni, surface->id, surface->offsets[0], - surface->width, surface->height, surface->pitches[0], - x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); - - pPriv->isOn = TRUE; - if (portPriv->videoStatus & CLIENT_VIDEO_ON) { - REGION_EMPTY(pScrni->pScreen, &portPriv->clip); - UpdateCurrentTime(); - portPriv->videoStatus = FREE_TIMER; - portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - - return Success; -} -/*---------------------------------------------------------------------------- - * LXInitOffscreenImages - * - * Description :This function sets up the offscreen memory management.It fills - * in the XF86OffscreenImagePtr structure with functions to handle - * offscreen memory operations. - * - * Parameters. - * pScrn :Screen handler pointer having screen information. - * - * Returns : None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ static void -LXInitOffscreenImages(ScreenPtr pScrn) +LXInitOffscreenImages(ScreenPtr pScrn) { - XF86OffscreenImagePtr offscreenImages; - - DBLOG(1, "LXInitOffscreenImages()\n"); - - /* need to free this someplace */ - if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) - return; - - offscreenImages[0].image = &Images[0]; - offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - offscreenImages[0].alloc_surface = LXAllocateSurface; - offscreenImages[0].free_surface = LXFreeSurface; - offscreenImages[0].display = LXDisplaySurface; - offscreenImages[0].stop = LXStopSurface; - offscreenImages[0].setAttribute = LXSetSurfaceAttribute; - offscreenImages[0].getAttribute = LXGetSurfaceAttribute; - offscreenImages[0].max_width = 1024; - offscreenImages[0].max_height = 1024; - offscreenImages[0].num_attributes = NUM_ATTRIBUTES; - offscreenImages[0].attributes = Attributes; - - xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); + XF86OffscreenImagePtr offscreenImages; + + /* need to free this someplace */ + if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; + + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = LXAllocateSurface; + offscreenImages[0].free_surface = LXFreeSurface; + offscreenImages[0].display = LXDisplaySurface; + offscreenImages[0].stop = LXStopSurface; + offscreenImages[0].setAttribute = LXSetSurfaceAttribute; + offscreenImages[0].getAttribute = LXGetSurfaceAttribute; + offscreenImages[0].max_width = 1024; + offscreenImages[0].max_height = 1024; + offscreenImages[0].num_attributes = ARRAY_SIZE(Attributes); + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); +} + +void +LXInitVideo(ScreenPtr pScrn) +{ + GeodeRec *pGeode; + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + pGeode = GEODEPTR(pScrni); + + if (pGeode->NoAccel) { + ErrorF("Cannot run Xv without accelerations!\n"); + return; + } + + if (!(newAdaptor = LXSetupImageVideo(pScrn))) { + ErrorF("Error while setting up the adaptor.\n"); + return; + } + + LXInitOffscreenImages(pScrn); + + num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); + + if (!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); + + if (newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + else + ErrorF("Memory error while setting up the adaptor\n"); + } + + if (num_adaptors) + xf86XVScreenInit(pScrn, adaptors, num_adaptors); + + if (newAdaptors) + xfree(newAdaptors); } - -#endif /* !XvExtension */ -#endif /* !AMD_V4L2_VIDEO */ |