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.
This commit is contained in:
parent
188002fe71
commit
3f75eaacdc
|
@ -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;
|
||||
|
|
|
@ -122,10 +122,15 @@ int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
|
|||
}
|
||||
else /* DIB_PAL_COLORS */
|
||||
{
|
||||
WORD * index = (WORD *)colorPtr;
|
||||
if (colorPtr) {
|
||||
WORD * index = (WORD *)colorPtr;
|
||||
|
||||
for (i = start; i < end; i++, index++)
|
||||
colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue