Commit 447ddfd3 authored by Alexandre Julliard's avatar Alexandre Julliard

Authors: Ove Kaaven <ovek@transgaming.com>, Andrew Lewycky…

Authors: Ove Kaaven <ovek@transgaming.com>, Andrew Lewycky <andrew@transgaming.com>, Gavriel State <gav@transgaming.com> DIB section improvements; UpdateDIBSection has been replaced with LockDIBSection and UnlockDIBSection, for improved thread safety. DIB_Status_* is now driver-independent, and there's a new DIB_Status_AuxMod. Better handling of DIB surfaces with nonstandard pitch. Slight optimization of DIBsection->display BitBlt.
parent cfb63bd2
......@@ -223,6 +223,23 @@ UINT TTYDRV_BITMAP_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT cou
}
/***********************************************************************
* TTYDRV_BITMAP_Lock
*/
INT TTYDRV_BITMAP_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
{
FIXME("(%p): stub\n", bmp);
return DIB_Status_None;
}
/***********************************************************************
* TTYDRV_BITMAP_Unlock
*/
void TTYDRV_BITMAP_Unlock(BITMAPOBJ *bmp, BOOL commit)
{
FIXME("(%p): stub\n", bmp);
}
/***********************************************************************
* TTYDRV_BITMAP_GetDIBits
*/
INT TTYDRV_BITMAP_GetDIBits(
......
......@@ -124,7 +124,9 @@ BITMAP_DRIVER TTYDRV_BITMAP_Driver =
TTYDRV_BITMAP_GetDIBits,
TTYDRV_BITMAP_DeleteDIBSection,
TTYDRV_BITMAP_SetDIBColorTable,
TTYDRV_BITMAP_GetDIBColorTable
TTYDRV_BITMAP_GetDIBColorTable,
TTYDRV_BITMAP_Lock,
TTYDRV_BITMAP_Unlock
};
PALETTE_DRIVER TTYDRV_PALETTE_Driver =
......
......@@ -53,6 +53,8 @@ extern INT TTYDRV_BITMAP_GetDIBits(struct tagBITMAPOBJ *bmp, struct tagDC *dc, U
extern void TTYDRV_BITMAP_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
extern UINT TTYDRV_BITMAP_SetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,const RGBQUAD *);
extern UINT TTYDRV_BITMAP_GetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,RGBQUAD *);
extern INT TTYDRV_BITMAP_Lock(struct tagBITMAPOBJ *,INT,BOOL);
extern void TTYDRV_BITMAP_Unlock(struct tagBITMAPOBJ *,BOOL);
#ifndef WINE_CURSES
typedef struct { int dummy; } WINDOW;
......
......@@ -1471,11 +1471,11 @@ BOOL X11DRV_PatBlt( DC *dc, INT left, INT top,
params.heightSrc = 0;
params.rop = rop;
X11DRV_DIB_UpdateDIBSection( dc, FALSE );
X11DRV_LockDIBSection( dc, DIB_Status_GdiMod, FALSE );
EnterCriticalSection( &X11DRV_CritSection );
result = (BOOL)CALL_LARGE_STACK( BITBLT_DoStretchBlt, &params );
LeaveCriticalSection( &X11DRV_CritSection );
X11DRV_DIB_UpdateDIBSection( dc, TRUE );
X11DRV_UnlockDIBSection( dc, TRUE );
return result;
}
......@@ -1488,7 +1488,41 @@ BOOL X11DRV_BitBlt( DC *dcDst, INT xDst, INT yDst,
INT xSrc, INT ySrc, DWORD rop )
{
struct StretchBlt_params params;
BOOL result;
BOOL result = FALSE;
INT sSrc, sDst;
if (((rop >> 16) & 0x55) == ((rop >> 17) & 0x55)) {
/* FIXME: seems the ROP doesn't include destination;
* now if the destination area include the entire dcDst,
* we can pass TRUE instead of FALSE to CoerceDIBSection(dcDst...),
* which may avoid a copy in some situations */
}
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;
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;
}
params.dcDst = dcDst;
params.xDst = xDst;
......@@ -1502,13 +1536,17 @@ BOOL X11DRV_BitBlt( DC *dcDst, INT xDst, INT yDst,
params.heightSrc = height;
params.rop = rop;
X11DRV_DIB_UpdateDIBSection( dcDst, FALSE );
X11DRV_DIB_UpdateDIBSection( dcSrc, FALSE );
X11DRV_CoerceDIBSection( dcDst, DIB_Status_GdiMod, FALSE );
X11DRV_CoerceDIBSection( dcSrc, DIB_Status_GdiMod, FALSE );
EnterCriticalSection( &X11DRV_CritSection );
result = (BOOL)CALL_LARGE_STACK( BITBLT_DoStretchBlt, &params );
LeaveCriticalSection( &X11DRV_CritSection );
X11DRV_DIB_UpdateDIBSection( dcDst, TRUE );
END:
X11DRV_UnlockDIBSection( dcSrc, FALSE );
X11DRV_UnlockDIBSection( dcDst, TRUE );
return result;
}
......@@ -1536,13 +1574,15 @@ BOOL X11DRV_StretchBlt( DC *dcDst, INT xDst, INT yDst,
params.heightSrc = heightSrc;
params.rop = rop;
X11DRV_DIB_UpdateDIBSection( dcDst, FALSE );
X11DRV_DIB_UpdateDIBSection( dcSrc, FALSE );
X11DRV_LockDIBSection( dcDst, DIB_Status_GdiMod, FALSE );
X11DRV_LockDIBSection( dcSrc, DIB_Status_GdiMod, FALSE );
EnterCriticalSection( &X11DRV_CritSection );
result = (BOOL)CALL_LARGE_STACK( BITBLT_DoStretchBlt, &params );
LeaveCriticalSection( &X11DRV_CritSection );
X11DRV_DIB_UpdateDIBSection( dcDst, TRUE );
X11DRV_UnlockDIBSection( dcSrc, FALSE );
X11DRV_UnlockDIBSection( dcDst, TRUE );
return result;
}
......@@ -295,14 +295,14 @@ X11DRV_LineTo( DC *dc, INT x, INT y )
if (X11DRV_SetupGCForPen( dc )) {
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
TSXDrawLine(display, physDev->drawable, physDev->gc,
dc->DCOrgX + XLPTODP( dc, dc->CursPosX ),
dc->DCOrgY + YLPTODP( dc, dc->CursPosY ),
dc->DCOrgX + XLPTODP( dc, x ),
dc->DCOrgY + YLPTODP( dc, y ) );
/* Update the DIBSection from the pixmap */
X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, TRUE);
}
return TRUE;
}
......@@ -386,7 +386,7 @@ X11DRV_DrawArc( DC *dc, INT left, INT top, INT right,
if (idiff_angle <= 0) idiff_angle += 360 * 64;
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
/* Fill arc with brush if Chord() or Pie() */
......@@ -465,7 +465,7 @@ X11DRV_DrawArc( DC *dc, INT left, INT top, INT right,
}
/* Update the DIBSection of the pixmap */
if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
physDev->pen.endcap = oldendcap;
......@@ -544,7 +544,7 @@ X11DRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
physDev->pen.width = width;
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if (X11DRV_SetupGCForBrush( dc ))
{
......@@ -562,7 +562,7 @@ X11DRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
}
/* Update the DIBSection from the pixmap */
if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
return TRUE;
......@@ -612,7 +612,7 @@ X11DRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
physDev->pen.linejoin = PS_JOIN_MITER;
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if ((right > left + width) && (bottom > top + width))
if (X11DRV_SetupGCForBrush( dc ))
......@@ -632,7 +632,7 @@ X11DRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
}
/* Update the DIBSection from the pixmap */
if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
physDev->pen.linejoin = oldjoinstyle;
......@@ -690,7 +690,7 @@ X11DRV_RoundRect( DC *dc, INT left, INT top, INT right,
physDev->pen.endcap = PS_ENDCAP_SQUARE;
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if (X11DRV_SetupGCForBrush( dc ))
{
......@@ -834,7 +834,7 @@ X11DRV_RoundRect( DC *dc, INT left, INT top, INT right,
}
/* Update the DIBSection from the pixmap */
if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
physDev->pen.endcap = oldendcap;
......@@ -939,14 +939,14 @@ X11DRV_PaintRgn( DC *dc, HRGN hrgn )
if (X11DRV_SetupGCForBrush( dc ))
{
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
TSXFillRectangle( display, physDev->drawable, physDev->gc,
box.left, box.top,
box.right-box.left, box.bottom-box.top );
/* Update the DIBSection from the pixmap */
X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, TRUE);
}
/* Restore the visible region */
......@@ -982,13 +982,13 @@ X11DRV_Polyline( DC *dc, const POINT* pt, INT count )
if (X11DRV_SetupGCForPen ( dc ))
{
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
TSXDrawLines( display, physDev->drawable, physDev->gc,
points, count, CoordModeOrigin );
/* Update the DIBSection from the pixmap */
X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, TRUE);
}
HeapFree( GetProcessHeap(), 0, points );
......@@ -1021,7 +1021,7 @@ X11DRV_Polygon( DC *dc, const POINT* pt, INT count )
points[count] = points[0];
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if (X11DRV_SetupGCForBrush( dc ))
{
......@@ -1037,7 +1037,7 @@ X11DRV_Polygon( DC *dc, const POINT* pt, INT count )
}
/* Update the DIBSection from the pixmap */
if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, update);
HeapFree( GetProcessHeap(), 0, points );
return TRUE;
......@@ -1068,7 +1068,7 @@ X11DRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
XPoint *points;
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
for (i = 0; i < polygons; i++) if (counts[i] > max) max = counts[i];
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (max+1) )))
......@@ -1090,7 +1090,7 @@ X11DRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
}
/* Update the DIBSection of the dc's bitmap */
X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, TRUE);
HeapFree( GetProcessHeap(), 0, points );
}
......@@ -1112,7 +1112,7 @@ X11DRV_PolyPolyline( DC *dc, const POINT* pt, const DWORD* counts, DWORD polylin
XPoint *points;
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
for (i = 0; i < polylines; i++) if (counts[i] > max) max = counts[i];
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * max )))
......@@ -1133,7 +1133,7 @@ X11DRV_PolyPolyline( DC *dc, const POINT* pt, const DWORD* counts, DWORD polylin
}
/* Update the DIBSection of the dc's bitmap */
X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, TRUE);
HeapFree( GetProcessHeap(), 0, points );
}
......@@ -1247,7 +1247,7 @@ static BOOL X11DRV_DoFloodFill( const struct FloodFill_params *params )
if (X11DRV_SetupGCForBrush( dc ))
{
/* Update the pixmap from the DIB section */
X11DRV_DIB_UpdateDIBSection(dc, FALSE);
X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
/* ROP mode is always GXcopy for flood-fill */
XSetFunction( display, physDev->gc, GXcopy );
......@@ -1260,7 +1260,7 @@ static BOOL X11DRV_DoFloodFill( const struct FloodFill_params *params )
params->fillType );
/* Update the DIBSection of the dc's bitmap */
X11DRV_DIB_UpdateDIBSection(dc, TRUE);
X11DRV_UnlockDIBSection(dc, TRUE);
}
XDestroyImage( image );
......
......@@ -133,7 +133,9 @@ BITMAP_DRIVER X11DRV_BITMAP_Driver =
X11DRV_DIB_GetDIBits,
X11DRV_DIB_DeleteDIBSection,
X11DRV_DIB_SetDIBColorTable,
X11DRV_DIB_GetDIBColorTable
X11DRV_DIB_GetDIBColorTable,
X11DRV_DIB_Lock,
X11DRV_DIB_Unlock
};
PALETTE_DRIVER X11DRV_PALETTE_Driver =
......
......@@ -18,6 +18,7 @@
#include "gdi.h"
#include "heap.h"
#include "x11font.h"
#include "bitmap.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(text);
......@@ -112,7 +113,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
if (flags & ETO_OPAQUE)
{
X11DRV_DIB_UpdateDIBSection( dc, FALSE );
X11DRV_LockDIBSection( dc, DIB_Status_GdiMod, FALSE );
dibUpdateFlag = TRUE;
TSXSetForeground( display, physDev->gc, physDev->backgroundPixel );
TSXFillRectangle( display, physDev->drawable, physDev->gc,
......@@ -196,7 +197,7 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
if (!dibUpdateFlag)
{
X11DRV_DIB_UpdateDIBSection( dc, FALSE );
X11DRV_LockDIBSection( dc, DIB_Status_GdiMod, FALSE );
dibUpdateFlag = TRUE;
}
......@@ -384,7 +385,7 @@ FAIL:
result = FALSE;
END:
if (dibUpdateFlag) X11DRV_DIB_UpdateDIBSection( dc, TRUE );
if (dibUpdateFlag) X11DRV_UnlockDIBSection( dc, TRUE );
return result;
}
......
......@@ -18,6 +18,9 @@ struct tagGDI_BITMAP_DRIVER;
#define DDB_COPY 4
#define DDB_SETWITHFILLER 8
/* DIB Section sync state */
enum { DIB_Status_None, DIB_Status_InSync, DIB_Status_GdiMod, DIB_Status_AppMod, DIB_Status_AuxMod };
/* GDI logical bitmap object */
typedef struct tagBITMAPOBJ
{
......@@ -37,6 +40,8 @@ typedef struct tagBITMAP_DRIVER
VOID (*pDeleteDIBSection)(struct tagBITMAPOBJ *);
UINT (*pSetDIBColorTable)(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,const RGBQUAD *);
UINT (*pGetDIBColorTable)(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,RGBQUAD *);
INT (*pLockDIB)(struct tagBITMAPOBJ *,INT,BOOL);
VOID (*pUnlockDIB)(struct tagBITMAPOBJ *,BOOL);
} BITMAP_DRIVER;
extern BITMAP_DRIVER *BITMAP_Driver;
......
......@@ -214,7 +214,7 @@ typedef struct
DIBSECTION dibSection;
/* Mapping status */
enum { X11DRV_DIB_NoHandler, X11DRV_DIB_InSync, X11DRV_DIB_AppMod, X11DRV_DIB_GdiMod } status;
int status, p_status;
/* Color map info */
int nColorMap;
......@@ -231,6 +231,13 @@ typedef struct
XShmSegmentInfo shminfo;
#endif
/* Aux buffer access function */
void (*copy_aux)(void*ctx, int req);
void *aux_ctx;
/* GDI access lock */
CRITICAL_SECTION lock;
} X11DRV_DIBSECTION;
/* This structure holds the arguments for DIB_SetImageBits() */
......@@ -259,14 +266,18 @@ typedef struct
DWORD gMask;
DWORD bMask;
BOOL useShm;
int dibpitch;
} X11DRV_DIB_IMAGEBITS_DESCR;
extern int *X11DRV_DIB_BuildColorMap( struct tagDC *dc, WORD coloruse,
WORD depth, const BITMAPINFO *info,
int *nColors );
extern void X11DRV_DIB_UpdateDIBSection(struct tagDC *dc, BOOL toDIB);
extern void X11DRV_DIB_UpdateDIBSection2(HBITMAP hbmp, BOOL toDIB);
extern INT X11DRV_CoerceDIBSection(struct tagDC *dc,INT,BOOL);
extern INT X11DRV_LockDIBSection(struct tagDC *dc,INT,BOOL);
extern void X11DRV_UnlockDIBSection(struct tagDC *dc,BOOL);
extern INT X11DRV_LockDIBSection2(HBITMAP bmp,INT,BOOL);
extern void X11DRV_UnlockDIBSection2(HBITMAP bmp,BOOL);
extern HBITMAP X11DRV_DIB_CreateDIBSection(struct tagDC *dc, BITMAPINFO *bmi, UINT usage,
LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
......@@ -284,6 +295,9 @@ extern INT X11DRV_DIB_GetDIBits(struct tagBITMAPOBJ *bmp, struct tagDC *dc, UINT
extern void X11DRV_DIB_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
extern UINT X11DRV_DIB_SetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC*,UINT,UINT,const RGBQUAD *);
extern UINT X11DRV_DIB_GetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC*,UINT,UINT,RGBQUAD *);
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);
/**************************************************************************
* X11 GDI driver
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment