diff options
author | Keith Packard <keithp@keithp.com> | 2003-11-10 20:35:05 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2003-11-10 20:35:05 +0000 |
commit | 5dc119b73ffcae32c2d470b734dfa2f8af58e77e (patch) | |
tree | d8a45c66d90b47014bdf376ab7f80fdce23c869f | |
parent | e500986657ea8b4e14a1ff4730ecda4583c75277 (diff) |
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.
-rw-r--r-- | hw/kdrive/mach64/mach64video.c | 19 | ||||
-rw-r--r-- | hw/kdrive/src/koffscreen.c | 146 | ||||
-rw-r--r-- | hw/kdrive/src/kxv.c | 12 | ||||
-rw-r--r-- | hw/kdrive/src/kxv.h | 15 |
4 files changed, 106 insertions, 86 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) + break; + } + + 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)) { - RealOffscreenArea *new_area; - - /* save extra space in new area */ - if (real_size < area->area.size) + 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) { - 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; + if (scan->locked) + break; + avail += scan->area.size; + if (avail >= real_size) + break; } - 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 - */ + /* space? */ + if (avail >= real_size) + break; - prev = (RealOffscreenArea **) &pScreenPriv->screen->off_screen_areas; - while ((area = *prev)) - { - if (area->area.screen && !area->locked) + /* nope, try the next area */ + prev = &scan->next; + } + if (!area) { - KdOffscreenKickOut (&area->area); - continue; + DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size)); + /* Could not allocate memory */ + KdOffscreenValidate (pScreen); + return NULL; } - /* 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) + /* + * 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) { - prev = &area->next; - continue; + assert (area->next && area->next->area.screen); + KdOffscreenKickOut (&area->next->area); } - assert (area->area.screen); - KdOffscreenKickOut (&area->area); } - DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size)); - /* Could not allocate memory */ + /* 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); |