From 5dc119b73ffcae32c2d470b734dfa2f8af58e77e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 10 Nov 2003 20:35:05 +0000 Subject: [PATCH] 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. --- hw/kdrive/mach64/mach64video.c | 19 ++-- hw/kdrive/src/koffscreen.c | 162 ++++++++++++++++++--------------- hw/kdrive/src/kxv.c | 12 +-- hw/kdrive/src/kxv.h | 15 +-- 4 files changed, 114 insertions(+), 94 deletions(-) diff --git a/hw/kdrive/mach64/mach64video.c b/hw/kdrive/mach64/mach64video.c index 64e5fb795..23d671580 100644 --- a/hw/kdrive/mach64/mach64video.c +++ b/hw/kdrive/mach64/mach64video.c @@ -327,9 +327,8 @@ mach64CopyPlanarData(KdScreenInfo *screen, } static void -mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg) +mach64PaintRegion (DrawablePtr pDraw, RegionPtr pRgn, Pixel fg) { - WindowPtr pRoot = WindowTable[pScreen->myNum]; GCPtr pGC; CARD32 val[2]; xRectangle *rects, *r; @@ -342,15 +341,15 @@ mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg) r = rects; while (nBox--) { - r->x = pBox->x1; - r->y = pBox->y1; + r->x = pBox->x1 - pDraw->x; + r->y = pBox->y1 - pDraw->y; r->width = pBox->x2 - pBox->x1; r->height = pBox->y2 - pBox->y1; r++; pBox++; } - pGC = GetScratchGC (pRoot->drawable.depth, pScreen); + pGC = GetScratchGC (pDraw->depth, pDraw->pScreen); if (!pGC) goto bail1; @@ -358,9 +357,9 @@ mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg) val[1] = IncludeInferiors; 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); FreeScratchGC (pGC); @@ -571,6 +570,7 @@ mach64VideoSave (KdOffscreenArea *area) static int mach64PutImage(KdScreenInfo *screen, + DrawablePtr pDraw, short src_x, short src_y, short drw_x, @@ -778,7 +778,7 @@ mach64PutImage(KdScreenInfo *screen, if (!REGION_EQUAL (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; @@ -880,6 +880,7 @@ static void mach64ResetVideo(KdScreenInfo *screen) static int mach64ReputImage (KdScreenInfo *screen, + DrawablePtr pDraw, short drw_x, short drw_y, RegionPtr clipBoxes, @@ -898,7 +899,7 @@ mach64ReputImage (KdScreenInfo *screen, if (!REGION_EQUAL (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; } diff --git a/hw/kdrive/src/koffscreen.c b/hw/kdrive/src/koffscreen.c index 09dfc3de3..71dfa6bb0 100644 --- a/hw/kdrive/src/koffscreen.c +++ b/hw/kdrive/src/koffscreen.c @@ -83,7 +83,7 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, { RealOffscreenArea *area, **prev; KdScreenPriv (pScreen); - int tmp, real_size; + int tmp, real_size = 0; KdOffscreenValidate (pScreen); if (!align) @@ -102,8 +102,6 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, return NULL; } -retry: - /* Go through the areas */ for (area = pScreenPriv->screen->off_screen_areas; area; area = area->next) { @@ -119,79 +117,99 @@ retry: /* does it fit? */ if (real_size <= area->area.size) - { - RealOffscreenArea *new_area; - - /* save extra space in new area */ - if (real_size < area->area.size) - { - new_area = xalloc (sizeof (RealOffscreenArea)); - if (!new_area) - return NULL; - new_area->area.offset = area->area.offset + real_size; - new_area->area.size = area->area.size - real_size; - new_area->area.screen = 0; - new_area->locked = FALSE; - new_area->save = 0; - if ((new_area->next = area->next)) - new_area->next->prev = new_area; - new_area->prev = area; - area->next = new_area; - area->area.size = real_size; - } - area->area.screen = pScreen; - area->area.privData = privData; - area->locked = locked; - area->save = save; - - KdOffscreenValidate (pScreen); - - DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->area.offset)); - 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 */ + if (!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 */ + if (real_size < area->area.size) + { + RealOffscreenArea *new_area = xalloc (sizeof (RealOffscreenArea)); + if (!new_area) + return NULL; + new_area->area.offset = area->area.offset + real_size; + new_area->area.size = area->area.size - real_size; + new_area->area.screen = 0; + new_area->locked = FALSE; + new_area->save = 0; + if ((new_area->next = area->next)) + new_area->next->prev = new_area; + new_area->prev = area; + area->next = new_area; + area->area.size = real_size; + } + /* + * Mark this area as in use + */ + area->area.screen = pScreen; + area->area.privData = privData; + area->locked = locked; + area->save = save; + KdOffscreenValidate (pScreen); - return NULL; + + DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->area.offset)); + return &area->area; } void diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c index 6699197e3..ea36bc788 100644 --- a/hw/kdrive/src/kxv.c +++ b/hw/kdrive/src/kxv.c @@ -694,7 +694,7 @@ KdXVRegetVideo(XvPortRecPrivatePtr portPriv) 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, WinBox.x1, WinBox.y1, portPriv->vid_w, portPriv->vid_h, @@ -785,7 +785,7 @@ KdXVReputVideo(XvPortRecPrivatePtr portPriv) 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, WinBox.x1, WinBox.y1, portPriv->vid_w, portPriv->vid_h, @@ -874,7 +874,7 @@ KdXVReputImage(XvPortRecPrivatePtr portPriv) REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); } - ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, + ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, portPriv->pDraw, WinBox.x1, WinBox.y1, &ClipRegion, portPriv->DevPriv.ptr); @@ -1387,7 +1387,7 @@ KdXVPutStill( 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_w, vid_h, drw_w, drw_h, &ClipRegion, portPriv->DevPriv.ptr); @@ -1515,7 +1515,7 @@ KdXVGetStill( 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_w, vid_h, drw_w, drw_h, &ClipRegion, portPriv->DevPriv.ptr); @@ -1687,7 +1687,7 @@ KdXVPutImage( 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_w, src_h, drw_w, drw_h, format->id, data, width, height, sync, &ClipRegion, portPriv->DevPriv.ptr); diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h index 1e8980c06..6335f7cb5 100644 --- a/hw/kdrive/src/kxv.h +++ b/hw/kdrive/src/kxv.h @@ -98,19 +98,19 @@ typedef struct { } 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_w, short vid_h, short drw_w, short drw_h, 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_w, short vid_h, short drw_w, short drw_h, 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_w, short vid_h, short drw_w, short drw_h, 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_w, short vid_h, short drw_w, short drw_h, RegionPtr clipBoxes, pointer data ); @@ -122,13 +122,14 @@ typedef int (* GetPortAttributeFuncPtr)(KdScreenInfo * screen, Atom attribute, typedef void (* QueryBestSizeFuncPtr)(KdScreenInfo * screen, Bool motion, short vid_w, short vid_h, short drw_w, short drw_h, 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_w, short src_h, short drw_w, short drw_h, int image, unsigned char* buf, short width, short height, Bool Sync, RegionPtr clipBoxes, pointer data ); -typedef int (* ReputImageFuncPtr)( KdScreenInfo * screen, short drw_x, short drw_y, - RegionPtr clipBoxes, pointer data ); +typedef int (* ReputImageFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw, + short drw_x, short drw_y, + RegionPtr clipBoxes, pointer data ); typedef int (*QueryImageAttributesFuncPtr)(KdScreenInfo * screen, int image, unsigned short *width, unsigned short *height, int *pitches, int *offsets);