From 3f75eaacdc8f7cab3d6106bad991910f10074cf8 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard <julliard@winehq.org> Date: Fri, 22 Dec 2000 01:07:57 +0000 Subject: [PATCH] Authors: Ove Kaaven <ovek@transgaming.com>, Gavriel State <gav@transgaming.com> More DIB section copy-blitting improvements: Handle 8bpp DIBs, DC mapping modes, and clipping. Take advantage of the DIBsection's XShmImage mechanism to get a really fast blit to the display. --- graphics/x11drv/bitblt.c | 40 ++++++++------ graphics/x11drv/dib.c | 113 +++++++++++++++++++++++++++++++++------ include/x11drv.h | 4 ++ 3 files changed, 125 insertions(+), 32 deletions(-) diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c index 68f87263c20..4e9ee00dd4d 100644 --- a/graphics/x11drv/bitblt.c +++ b/graphics/x11drv/bitblt.c @@ -1490,6 +1490,7 @@ BOOL X11DRV_BitBlt( DC *dcDst, INT xDst, INT yDst, struct StretchBlt_params params; BOOL result = FALSE; INT sSrc, sDst; + RECT visRectDst, visRectSrc; if (((rop >> 16) & 0x55) == ((rop >> 17) & 0x55)) { /* FIXME: seems the ROP doesn't include destination; @@ -1499,29 +1500,36 @@ BOOL X11DRV_BitBlt( DC *dcDst, INT xDst, INT yDst, } sDst = X11DRV_LockDIBSection( dcDst, DIB_Status_None, FALSE ); sSrc = X11DRV_LockDIBSection( dcSrc, DIB_Status_None, FALSE ); + if ((sSrc == DIB_Status_AppMod) && (rop == SRCCOPY)) { - BITMAPOBJ *bmp; - BOOL done = FALSE; + /* do everything ourselves; map coordinates */ + xSrc = dcSrc->DCOrgX + XLPTODP( dcSrc, xSrc ); + ySrc = dcSrc->DCOrgY + YLPTODP( dcSrc, ySrc ); + xDst = dcDst->DCOrgX + XLPTODP( dcDst, xDst ); + yDst = dcDst->DCOrgY + YLPTODP( dcDst, yDst ); + width = MulDiv(width, dcDst->vportExtX, dcDst->wndExtX); + height = MulDiv(height, dcDst->vportExtY, dcDst->wndExtY); + + /* Perform basic clipping */ + if (!BITBLT_GetVisRectangles( dcDst, xDst, yDst, width, height, + dcSrc, xSrc, ySrc, width, height, + &visRectSrc, &visRectDst )) + goto END; + xSrc = visRectSrc.left; + ySrc = visRectSrc.top; + xDst = visRectDst.left; + yDst = visRectDst.top; + width = visRectDst.right - visRectDst.left; + height = visRectDst.bottom - visRectDst.top; + if (sDst == DIB_Status_AppMod) { FIXME("potential optimization - client-side DIB copy\n"); } - X11DRV_CoerceDIBSection( dcDst, DIB_Status_GdiMod, FALSE ); - bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC ); - if (bmp->dib) { - if (bmp->dib->dsBmih.biBitCount > 8) { - if (X11DRV_SetDIBitsToDevice( dcDst, xDst, yDst, width, height, xSrc, ySrc, - 0, bmp->dib->dsBm.bmHeight, bmp->dib->dsBm.bmBits, - (BITMAPINFO*)&(bmp->dib->dsBmih), 0)) - result = TRUE; - done = TRUE; - } - else FIXME("potential optimization - 8 bpp SetDIBitsToDevice\n"); - } - GDI_ReleaseObj( dcSrc->hBitmap ); - if (done) goto END; + X11DRV_DIB_CopyDIBSection( dcSrc, dcDst, xSrc, ySrc, xDst, yDst, width, height ); + goto END; } params.dcDst = dcDst; diff --git a/graphics/x11drv/dib.c b/graphics/x11drv/dib.c index 4cdbb582bd1..f2eac0c33fc 100644 --- a/graphics/x11drv/dib.c +++ b/graphics/x11drv/dib.c @@ -122,10 +122,15 @@ int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping, } else /* DIB_PAL_COLORS */ { - WORD * index = (WORD *)colorPtr; - - for (i = start; i < end; i++, index++) - colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) ); + if (colorPtr) { + WORD * index = (WORD *)colorPtr; + + for (i = start; i < end; i++, index++) + colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) ); + } else { + for (i = start; i < end; i++) + colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) ); + } } return colorMapping; @@ -142,14 +147,14 @@ int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth, { int colors; BOOL isInfo; - WORD *colorPtr; + const void *colorPtr; int *colorMapping; if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)))) { colors = info->bmiHeader.biClrUsed; if (!colors) colors = 1 << info->bmiHeader.biBitCount; - colorPtr = (WORD *)info->bmiColors; + colorPtr = info->bmiColors; } else /* assume BITMAPCOREINFO */ { @@ -163,6 +168,9 @@ int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth, return NULL; } + /* just so CopyDIBSection doesn't have to create an identity palette */ + if (coloruse == (WORD)-1) colorPtr = NULL; + if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0, colors * sizeof(int) ))) return NULL; @@ -2684,6 +2692,10 @@ int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr ) break; } + TRACE("XPutImage(%p,%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n", + display, descr->drawable, descr->gc, bmpImage, + descr->xSrc, descr->ySrc, descr->xDest, descr->yDest, + descr->width, descr->height); if (descr->useShm) { XShmPutImage( display, descr->drawable, descr->gc, bmpImage, @@ -3126,7 +3138,12 @@ static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot ) /*********************************************************************** * X11DRV_DIB_DoUpdateDIBSection */ -static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB) +static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB, + void *colorMap, int nColorMap, + Drawable dest, + DWORD xSrc, DWORD ySrc, + DWORD xDest, DWORD yDest, + DWORD width, DWORD height) { X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; X11DRV_DIB_IMAGEBITS_DESCR descr; @@ -3138,8 +3155,8 @@ static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB) descr.dc = NULL; descr.palentry = NULL; descr.image = dib->image; - descr.colorMap = (RGBQUAD *)dib->colorMap; - descr.nColorMap = dib->nColorMap; + descr.colorMap = colorMap; + descr.nColorMap = nColorMap; descr.bits = dib->dibSection.dsBm.bmBits; descr.depth = bmp->bitmap.bmBitsPixel; @@ -3166,14 +3183,14 @@ static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB) } /* Hack for now */ - descr.drawable = (Pixmap)bmp->physBitmap; + descr.drawable = dest; descr.gc = BITMAP_GC(bmp); - descr.xSrc = 0; - descr.ySrc = 0; - descr.xDest = 0; - descr.yDest = 0; - descr.width = bmp->bitmap.bmWidth; - descr.height = bmp->bitmap.bmHeight; + descr.xSrc = xSrc; + descr.ySrc = ySrc; + descr.xDest = xDest; + descr.yDest = yDest; + descr.width = width; + descr.height = height; #ifdef HAVE_LIBXXSHM descr.useShm = (dib->shminfo.shmid != -1); #else @@ -3197,6 +3214,70 @@ static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB) } } +/*********************************************************************** + * X11DRV_DIB_CopyDIBSection + */ +void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst, + DWORD xSrc, DWORD ySrc, + DWORD xDest, DWORD yDest, + DWORD width, DWORD height) +{ + BITMAPOBJ *bmp; + X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev; + int nColorMap = 0, *colorMap = NULL; + + TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst, + xSrc, ySrc, xDest, yDest, width, height); + /* this function is meant as an optimization for BitBlt, + * not to be called otherwise */ + if (!(dcSrc->flags & DC_MEMORY)) { + ERR("called for non-memory source DC!?\n"); + return; + } + + bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC ); + if (!(bmp && bmp->dib)) { + ERR("called for non-DIBSection!?\n"); + GDI_ReleaseObj( dcSrc->hBitmap ); + return; + } + /* while BitBlt should already have made sure we only get + * positive values, we should check for oversize values */ + if ((xSrc < bmp->bitmap.bmWidth) && + (ySrc < bmp->bitmap.bmHeight)) { + if (xSrc + width > bmp->bitmap.bmWidth) + width = bmp->bitmap.bmWidth - xSrc; + if (ySrc + height > bmp->bitmap.bmHeight) + height = bmp->bitmap.bmHeight - ySrc; + /* if the source bitmap is 8bpp or less, we're supposed to use the + * DC's palette for color conversion (not the DIB color table) */ + if (bmp->dib->dsBm.bmBitsPixel <= 8) + colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1, + bmp->dib->dsBm.bmBitsPixel, + (BITMAPINFO*)&(bmp->dib->dsBmih), + &nColorMap ); + /* perform the copy */ + X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap, + physDev->drawable, xSrc, ySrc, xDest, yDest, + width, height); + /* free color mapping */ + if (colorMap) + HeapFree(GetProcessHeap(), 0, colorMap); + } + GDI_ReleaseObj( dcSrc->hBitmap ); +} + +/*********************************************************************** + * X11DRV_DIB_DoUpdateDIBSection + */ +static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB) +{ + X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; + X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap, + (Drawable)bmp->physBitmap, 0, 0, 0, 0, + bmp->bitmap.bmWidth, bmp->bitmap.bmHeight); +} + /*********************************************************************** * X11DRV_DIB_FaultHandler */ diff --git a/include/x11drv.h b/include/x11drv.h index f0b391fbbd1..17c22d1d914 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -298,6 +298,10 @@ extern UINT X11DRV_DIB_GetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC*,UINT extern INT X11DRV_DIB_Coerce(struct tagBITMAPOBJ *,INT,BOOL); extern INT X11DRV_DIB_Lock(struct tagBITMAPOBJ *,INT,BOOL); extern void X11DRV_DIB_Unlock(struct tagBITMAPOBJ *,BOOL); +void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst, + DWORD xSrc, DWORD ySrc, + DWORD xDest, DWORD yDest, + DWORD width, DWORD height); /************************************************************************** * X11 GDI driver -- GitLab