Unnormal slowness in Heroes 4 (X11DRV_BitBlt?)

Marinescu-Ghetau Iulian giulian2003 at hotmail.com
Fri Dec 2 07:54:41 CST 2005


See http://bugs.winehq.org/show_bug.cgi?id=3902

Hey guys, a bit of help here! I did the following changes:

-added member to X_PHYSBITMAP:

XRectangle modified_rect;

-added 2 functions:

/***********************************************************************
*           X11DRV_SetBoundRect
*/
void X11DRV_SetBoundRect(X_PHYSBITMAP *physBitmap, INT x, INT y, INT width, 
INT
height)
{
	XRectangle *t;
	INT xMin,yMin,xMax,yMax;

	if (!physBitmap) return;

	t = &(physBitmap->modified_rect);

	if ( t->width && t->height && /*already a valid rect inside*/
             width && height ) /*not trying to invalidate rect*/
	{
		//calculate the union of the two rectangles
		xMin = ((t->x < x)?t->x:x);
		yMin = ((t->y < y)?t->y:y);
		xMax = ((t->x + t->width > x + width)?(t->x + t->width):(x +
width));
		yMax = ((t->y + t->height > y + height)?(t->y + t->height):(y +
height));

		t->x = xMin;
		t->y = yMin;
		t->width = xMax - xMin;
		t->height = yMax - yMin;

	}
	else
	{
		t->x = x;
		t->y = y;
		t->width = width;
		t->height = height;
	}

	TRACE("(%p,%d,%d,%d,%d)\n", physBitmap->hbitmap, t->x, t->y, t->width,
t->height);

}

/***********************************************************************
*           X11DRV_GetBoundRect
*/
UINT X11DRV_GetBoundRect(X_PHYSBITMAP *physBitmap, INT *x, INT *y, INT 
*width,
INT *height)
{

	DIBSECTION dib;
	XRectangle *t;


	if (!physBitmap || GetObjectW( physBitmap->hbitmap, sizeof(dib),
&dib ) != sizeof(dib))
	{
		ERR("called for non-DIBSection!?\n");
		return 1;
	}

	t = &(physBitmap->modified_rect);

	/* we should check for oversize values */
	if ( (t->width > 0) && (t->height > 0) &&
	     (t->x < dib.dsBm.bmWidth) && (t->y < dib.dsBm.bmHeight) )
	{
		*x = t->x;
		*y = t->y;

		if (t->x + t->width > dib.dsBm.bmWidth)
			*width = dib.dsBm.bmWidth - t->x;
		else
			*width = t->width;

		if (t->y + t->height > dib.dsBm.bmHeight)
			*height = dib.dsBm.bmHeight - t->y;
		else
			*height = t->height;
	}
	else
	{
		*x = 0;
		*y = 0;
		*width = dib.dsBm.bmWidth;
		*height = dib.dsBm.bmHeight;
	}

	TRACE("(%p,%d,%d,%d,%d)\n", physBitmap->hbitmap, *x, *y, *width,
*height);

	return 0;
}

-changed X11DRV_DIB_DoUpdateDIBSection like this:

static void X11DRV_DIB_DoUpdateDIBSection(X_PHYSBITMAP *physBitmap, BOOL 
toDIB)
{
	INT x,y,width,height;

	if ( X11DRV_GetBoundRect(physBitmap,&x,&y,&width,&height) ) return;

	/*invalidate bound rect*/
	X11DRV_SetBoundRect(physBitmap,0,0,0,0);

    X11DRV_DIB_DoCopyDIBSection(physBitmap, toDIB,
                                physBitmap->colorMap, physBitmap->nColorMap,
                                physBitmap->pixmap, x, y, x, y,
                                width, height);

}

- and finally, a GDI function calls it like this (for example bitblt):

    X11DRV_SetBoundRect(physDevDst->bitmap,xDst,yDst,width,height);
    X11DRV_CoerceDIBSection( physDevDst, DIB_Status_GdiMod, FALSE );
    if (physDevDst != physDevSrc)
    {
      X11DRV_SetBoundRect(physDevSrc->bitmap,xSrc,ySrc,width,height);
      X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod, FALSE );
    }
    result = BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, width, 
height,
                                        physDevSrc, xSrc, ySrc, width, 
height,
rop );

END:
    if (physDevDst != physDevSrc)
      X11DRV_UnlockDIBSection( physDevSrc, FALSE );
    X11DRV_UnlockDIBSection( physDevDst, TRUE );


What am i doing wrong, i mean is my logic correct ?





More information about the wine-devel mailing list