Fix KdXv interface to pass drawable down so that bits can be put into

drawable pixmap rather than directly into the frame buffer. Rewrite
    logic in kdoffscreen to make space for new allocations, now deals
    correctly with locked areas.
This commit is contained in:
Keith Packard 2003-11-10 20:35:05 +00:00
parent e500986657
commit 5dc119b73f
4 changed files with 114 additions and 94 deletions

View File

@ -327,9 +327,8 @@ mach64CopyPlanarData(KdScreenInfo *screen,
} }
static void static void
mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg) mach64PaintRegion (DrawablePtr pDraw, RegionPtr pRgn, Pixel fg)
{ {
WindowPtr pRoot = WindowTable[pScreen->myNum];
GCPtr pGC; GCPtr pGC;
CARD32 val[2]; CARD32 val[2];
xRectangle *rects, *r; xRectangle *rects, *r;
@ -342,15 +341,15 @@ mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg)
r = rects; r = rects;
while (nBox--) while (nBox--)
{ {
r->x = pBox->x1; r->x = pBox->x1 - pDraw->x;
r->y = pBox->y1; r->y = pBox->y1 - pDraw->y;
r->width = pBox->x2 - pBox->x1; r->width = pBox->x2 - pBox->x1;
r->height = pBox->y2 - pBox->y1; r->height = pBox->y2 - pBox->y1;
r++; r++;
pBox++; pBox++;
} }
pGC = GetScratchGC (pRoot->drawable.depth, pScreen); pGC = GetScratchGC (pDraw->depth, pDraw->pScreen);
if (!pGC) if (!pGC)
goto bail1; goto bail1;
@ -358,9 +357,9 @@ mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg)
val[1] = IncludeInferiors; val[1] = IncludeInferiors;
ChangeGC (pGC, GCForeground|GCSubwindowMode, val); ChangeGC (pGC, GCForeground|GCSubwindowMode, val);
ValidateGC (&pRoot->drawable, pGC); ValidateGC (pDraw, pGC);
(*pGC->ops->PolyFillRect) (&pRoot->drawable, pGC, (*pGC->ops->PolyFillRect) (pDraw, pGC,
REGION_NUM_RECTS (pRgn), rects); REGION_NUM_RECTS (pRgn), rects);
FreeScratchGC (pGC); FreeScratchGC (pGC);
@ -571,6 +570,7 @@ mach64VideoSave (KdOffscreenArea *area)
static int static int
mach64PutImage(KdScreenInfo *screen, mach64PutImage(KdScreenInfo *screen,
DrawablePtr pDraw,
short src_x, short src_x,
short src_y, short src_y,
short drw_x, short drw_x,
@ -778,7 +778,7 @@ mach64PutImage(KdScreenInfo *screen,
if (!REGION_EQUAL (screen->pScreen, &pPortPriv->clip, clipBoxes)) if (!REGION_EQUAL (screen->pScreen, &pPortPriv->clip, clipBoxes))
{ {
REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes); REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes);
mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey); mach64PaintRegion (pDraw, &pPortPriv->clip, pPortPriv->colorKey);
} }
pPortPriv->videoOn = TRUE; pPortPriv->videoOn = TRUE;
@ -880,6 +880,7 @@ static void mach64ResetVideo(KdScreenInfo *screen)
static int static int
mach64ReputImage (KdScreenInfo *screen, mach64ReputImage (KdScreenInfo *screen,
DrawablePtr pDraw,
short drw_x, short drw_x,
short drw_y, short drw_y,
RegionPtr clipBoxes, RegionPtr clipBoxes,
@ -898,7 +899,7 @@ mach64ReputImage (KdScreenInfo *screen,
if (!REGION_EQUAL (screen->pScreen, &pPortPriv->clip, clipBoxes)) if (!REGION_EQUAL (screen->pScreen, &pPortPriv->clip, clipBoxes))
{ {
REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes); REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes);
mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey); mach64PaintRegion (pDraw, &pPortPriv->clip, pPortPriv->colorKey);
} }
return Success; return Success;
} }

View File

@ -83,7 +83,7 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
{ {
RealOffscreenArea *area, **prev; RealOffscreenArea *area, **prev;
KdScreenPriv (pScreen); KdScreenPriv (pScreen);
int tmp, real_size; int tmp, real_size = 0;
KdOffscreenValidate (pScreen); KdOffscreenValidate (pScreen);
if (!align) if (!align)
@ -102,8 +102,6 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
return NULL; return NULL;
} }
retry:
/* Go through the areas */ /* Go through the areas */
for (area = pScreenPriv->screen->off_screen_areas; area; area = area->next) for (area = pScreenPriv->screen->off_screen_areas; area; area = area->next)
{ {
@ -119,13 +117,74 @@ retry:
/* does it fit? */ /* does it fit? */
if (real_size <= area->area.size) if (real_size <= area->area.size)
break;
}
if (!area)
{ {
RealOffscreenArea *new_area; /*
* Kick out existing users to make space.
*
* First, locate a region which can hold the desired object.
*/
/* prev points at the first object to boot */
prev = (RealOffscreenArea **) &pScreenPriv->screen->off_screen_areas;
while ((area = *prev))
{
int avail;
RealOffscreenArea *scan;
/* adjust size to match alignment requirement */
real_size = size;
tmp = area->area.offset % align;
if (tmp)
real_size += (align - tmp);
avail = 0;
/* now see if we can make room here */
for (scan = area; scan; scan = scan->next)
{
if (scan->locked)
break;
avail += scan->area.size;
if (avail >= real_size)
break;
}
/* space? */
if (avail >= real_size)
break;
/* nope, try the next area */
prev = &scan->next;
}
if (!area)
{
DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size));
/* Could not allocate memory */
KdOffscreenValidate (pScreen);
return NULL;
}
/*
* Kick out first area if in use
*/
if (area->area.screen)
KdOffscreenKickOut (&area->area);
/*
* Now get the system to merge the other needed areas together
*/
while (area->area.size < real_size)
{
assert (area->next && area->next->area.screen);
KdOffscreenKickOut (&area->next->area);
}
}
/* save extra space in new area */ /* save extra space in new area */
if (real_size < area->area.size) if (real_size < area->area.size)
{ {
new_area = xalloc (sizeof (RealOffscreenArea)); RealOffscreenArea *new_area = xalloc (sizeof (RealOffscreenArea));
if (!new_area) if (!new_area)
return NULL; return NULL;
new_area->area.offset = area->area.offset + real_size; new_area->area.offset = area->area.offset + real_size;
@ -139,6 +198,9 @@ retry:
area->next = new_area; area->next = new_area;
area->area.size = real_size; area->area.size = real_size;
} }
/*
* Mark this area as in use
*/
area->area.screen = pScreen; area->area.screen = pScreen;
area->area.privData = privData; area->area.privData = privData;
area->locked = locked; area->locked = locked;
@ -148,50 +210,6 @@ retry:
DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->area.offset)); DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->area.offset));
return &area->area; return &area->area;
}
}
/*
* Kick out existing users. This is pretty simplistic; it just
* keeps deleting areas until the first area is free and has enough room
*/
prev = (RealOffscreenArea **) &pScreenPriv->screen->off_screen_areas;
while ((area = *prev))
{
if (area->area.screen && !area->locked)
{
KdOffscreenKickOut (&area->area);
continue;
}
/* adjust size to match alignment requirement */
real_size = size;
tmp = area->area.offset % align;
if (tmp)
real_size += (align - tmp);
/* does it fit? */
if (real_size <= area->area.size)
goto retry;
/* kick out the next area */
area = area->next;
if (!area)
break;
/* skip over locked areas */
if (area->locked)
{
prev = &area->next;
continue;
}
assert (area->area.screen);
KdOffscreenKickOut (&area->area);
}
DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size));
/* Could not allocate memory */
KdOffscreenValidate (pScreen);
return NULL;
} }
void void

View File

@ -694,7 +694,7 @@ KdXVRegetVideo(XvPortRecPrivatePtr portPriv)
REGION_SUBTRACT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, &ClipRegion); REGION_SUBTRACT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, &ClipRegion);
} }
ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->screen, ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->screen, portPriv->pDraw,
portPriv->vid_x, portPriv->vid_y, portPriv->vid_x, portPriv->vid_y,
WinBox.x1, WinBox.y1, WinBox.x1, WinBox.y1,
portPriv->vid_w, portPriv->vid_h, portPriv->vid_w, portPriv->vid_h,
@ -785,7 +785,7 @@ KdXVReputVideo(XvPortRecPrivatePtr portPriv)
REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
} }
ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->screen, ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->screen, portPriv->pDraw,
portPriv->vid_x, portPriv->vid_y, portPriv->vid_x, portPriv->vid_y,
WinBox.x1, WinBox.y1, WinBox.x1, WinBox.y1,
portPriv->vid_w, portPriv->vid_h, portPriv->vid_w, portPriv->vid_h,
@ -874,7 +874,7 @@ KdXVReputImage(XvPortRecPrivatePtr portPriv)
REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
} }
ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, portPriv->pDraw,
WinBox.x1, WinBox.y1, WinBox.x1, WinBox.y1,
&ClipRegion, portPriv->DevPriv.ptr); &ClipRegion, portPriv->DevPriv.ptr);
@ -1387,7 +1387,7 @@ KdXVPutStill(
REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
} }
ret = (*portPriv->AdaptorRec->PutStill)(portPriv->screen, ret = (*portPriv->AdaptorRec->PutStill)(portPriv->screen, pDraw,
vid_x, vid_y, WinBox.x1, WinBox.y1, vid_x, vid_y, WinBox.x1, WinBox.y1,
vid_w, vid_h, drw_w, drw_h, vid_w, vid_h, drw_w, drw_h,
&ClipRegion, portPriv->DevPriv.ptr); &ClipRegion, portPriv->DevPriv.ptr);
@ -1515,7 +1515,7 @@ KdXVGetStill(
REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
} }
ret = (*portPriv->AdaptorRec->GetStill)(portPriv->screen, ret = (*portPriv->AdaptorRec->GetStill)(portPriv->screen, pDraw,
vid_x, vid_y, WinBox.x1, WinBox.y1, vid_x, vid_y, WinBox.x1, WinBox.y1,
vid_w, vid_h, drw_w, drw_h, vid_w, vid_h, drw_w, drw_h,
&ClipRegion, portPriv->DevPriv.ptr); &ClipRegion, portPriv->DevPriv.ptr);
@ -1687,7 +1687,7 @@ KdXVPutImage(
REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
} }
ret = (*portPriv->AdaptorRec->PutImage)(portPriv->screen, ret = (*portPriv->AdaptorRec->PutImage)(portPriv->screen, pDraw,
src_x, src_y, WinBox.x1, WinBox.y1, src_x, src_y, WinBox.x1, WinBox.y1,
src_w, src_h, drw_w, drw_h, format->id, data, width, height, src_w, src_h, drw_w, drw_h, format->id, data, width, height,
sync, &ClipRegion, portPriv->DevPriv.ptr); sync, &ClipRegion, portPriv->DevPriv.ptr);

View File

@ -98,19 +98,19 @@ typedef struct {
} KdSurfaceRec, *KdSurfacePtr; } KdSurfaceRec, *KdSurfacePtr;
typedef int (* PutVideoFuncPtr)( KdScreenInfo * screen, typedef int (* PutVideoFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw,
short vid_x, short vid_y, short drw_x, short drw_y, short vid_x, short vid_y, short drw_x, short drw_y,
short vid_w, short vid_h, short drw_w, short drw_h, short vid_w, short vid_h, short drw_w, short drw_h,
RegionPtr clipBoxes, pointer data ); RegionPtr clipBoxes, pointer data );
typedef int (* PutStillFuncPtr)( KdScreenInfo * screen, typedef int (* PutStillFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw,
short vid_x, short vid_y, short drw_x, short drw_y, short vid_x, short vid_y, short drw_x, short drw_y,
short vid_w, short vid_h, short drw_w, short drw_h, short vid_w, short vid_h, short drw_w, short drw_h,
RegionPtr clipBoxes, pointer data ); RegionPtr clipBoxes, pointer data );
typedef int (* GetVideoFuncPtr)( KdScreenInfo * screen, typedef int (* GetVideoFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw,
short vid_x, short vid_y, short drw_x, short drw_y, short vid_x, short vid_y, short drw_x, short drw_y,
short vid_w, short vid_h, short drw_w, short drw_h, short vid_w, short vid_h, short drw_w, short drw_h,
RegionPtr clipBoxes, pointer data ); RegionPtr clipBoxes, pointer data );
typedef int (* GetStillFuncPtr)( KdScreenInfo * screen, typedef int (* GetStillFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw,
short vid_x, short vid_y, short drw_x, short drw_y, short vid_x, short vid_y, short drw_x, short drw_y,
short vid_w, short vid_h, short drw_w, short drw_h, short vid_w, short vid_h, short drw_w, short drw_h,
RegionPtr clipBoxes, pointer data ); RegionPtr clipBoxes, pointer data );
@ -122,12 +122,13 @@ typedef int (* GetPortAttributeFuncPtr)(KdScreenInfo * screen, Atom attribute,
typedef void (* QueryBestSizeFuncPtr)(KdScreenInfo * screen, Bool motion, typedef void (* QueryBestSizeFuncPtr)(KdScreenInfo * screen, Bool motion,
short vid_w, short vid_h, short drw_w, short drw_h, short vid_w, short vid_h, short drw_w, short drw_h,
unsigned int *p_w, unsigned int *p_h, pointer data); unsigned int *p_w, unsigned int *p_h, pointer data);
typedef int (* PutImageFuncPtr)( KdScreenInfo * screen, typedef int (* PutImageFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw,
short src_x, short src_y, short drw_x, short drw_y, short src_x, short src_y, short drw_x, short drw_y,
short src_w, short src_h, short drw_w, short drw_h, short src_w, short src_h, short drw_w, short drw_h,
int image, unsigned char* buf, short width, short height, Bool Sync, int image, unsigned char* buf, short width, short height, Bool Sync,
RegionPtr clipBoxes, pointer data ); RegionPtr clipBoxes, pointer data );
typedef int (* ReputImageFuncPtr)( KdScreenInfo * screen, short drw_x, short drw_y, typedef int (* ReputImageFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw,
short drw_x, short drw_y,
RegionPtr clipBoxes, pointer data ); RegionPtr clipBoxes, pointer data );
typedef int (*QueryImageAttributesFuncPtr)(KdScreenInfo * screen, typedef int (*QueryImageAttributesFuncPtr)(KdScreenInfo * screen,
int image, unsigned short *width, unsigned short *height, int image, unsigned short *width, unsigned short *height,