gdi32: Allocate the DIB driver on first use, and free it only upon DC destruction.
This commit is contained in:
parent
da0327917c
commit
d12d98511c
|
@ -702,13 +702,18 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||||
}
|
}
|
||||||
|
|
||||||
old_physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
|
old_physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
|
||||||
if(old_physdev == &dc->dibdrv.dev)
|
if(old_physdev == dc->dibdrv)
|
||||||
old_physdev = pop_dc_driver( &dc->physDev );
|
old_physdev = pop_dc_driver( &dc->physDev );
|
||||||
|
|
||||||
if(bitmap->dib)
|
if(bitmap->dib)
|
||||||
{
|
{
|
||||||
physdev = &dc->dibdrv.dev;
|
physdev = dc->dibdrv;
|
||||||
push_dc_driver( &dc->physDev, physdev, physdev->funcs );
|
if (physdev) push_dc_driver( &dc->physDev, physdev, physdev->funcs );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!dib_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL )) goto done;
|
||||||
|
dc->dibdrv = physdev = dc->physDev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
|
physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
|
||||||
|
@ -742,8 +747,10 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||||
done:
|
done:
|
||||||
if(!ret)
|
if(!ret)
|
||||||
{
|
{
|
||||||
if(physdev == &dc->dibdrv.dev) pop_dc_driver( &dc->physDev );
|
if (physdev && physdev == dc->dibdrv)
|
||||||
if(old_physdev == &dc->dibdrv.dev) push_dc_driver( &dc->physDev, old_physdev, old_physdev->funcs );
|
pop_dc_driver( &dc->physDev );
|
||||||
|
if (old_physdev && old_physdev == dc->dibdrv)
|
||||||
|
push_dc_driver( &dc->physDev, old_physdev, old_physdev->funcs );
|
||||||
}
|
}
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -392,7 +392,7 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||||
PHYSDEV pattern_dev = physdev;
|
PHYSDEV pattern_dev = physdev;
|
||||||
/* FIXME: This will go away once the dib driver implements
|
/* FIXME: This will go away once the dib driver implements
|
||||||
pattern brushes */
|
pattern brushes */
|
||||||
if(pattern_dev == &dc->dibdrv.dev)
|
if(pattern_dev == dc->dibdrv)
|
||||||
pattern_dev = GET_NEXT_PHYSDEV( physdev, pSelectBrush );
|
pattern_dev = GET_NEXT_PHYSDEV( physdev, pSelectBrush );
|
||||||
|
|
||||||
BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, pattern_dev );
|
BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, pattern_dev );
|
||||||
|
|
|
@ -79,8 +79,7 @@ DC *alloc_dc_ptr( WORD magic )
|
||||||
|
|
||||||
dc->nulldrv.funcs = &null_driver;
|
dc->nulldrv.funcs = &null_driver;
|
||||||
dc->nulldrv.next = NULL;
|
dc->nulldrv.next = NULL;
|
||||||
dc->dibdrv.dev.funcs = &dib_driver;
|
dc->dibdrv = NULL;
|
||||||
dc->dibdrv.dev.next = NULL;
|
|
||||||
dc->physDev = &dc->nulldrv;
|
dc->physDev = &dc->nulldrv;
|
||||||
dc->thread = GetCurrentThreadId();
|
dc->thread = GetCurrentThreadId();
|
||||||
dc->refcount = 1;
|
dc->refcount = 1;
|
||||||
|
@ -185,7 +184,9 @@ void free_dc_ptr( DC *dc )
|
||||||
{
|
{
|
||||||
PHYSDEV physdev = pop_dc_driver( &dc->physDev );
|
PHYSDEV physdev = pop_dc_driver( &dc->physDev );
|
||||||
physdev->funcs->pDeleteDC( physdev );
|
physdev->funcs->pDeleteDC( physdev );
|
||||||
|
if (physdev == dc->dibdrv) dc->dibdrv = NULL;
|
||||||
}
|
}
|
||||||
|
if (dc->dibdrv) dc->dibdrv->funcs->pDeleteDC( dc->dibdrv );
|
||||||
free_gdi_handle( dc->hSelf );
|
free_gdi_handle( dc->hSelf );
|
||||||
free_dc_state( dc );
|
free_dc_state( dc );
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,6 +349,26 @@ void restore_clipping_region( dibdrv_physdev *pdev, HRGN rgn )
|
||||||
pdev->clip = rgn;
|
pdev->clip = rgn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* dibdrv_CreateDC
|
||||||
|
*/
|
||||||
|
static BOOL dibdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
|
||||||
|
LPCWSTR output, const DEVMODEW *data )
|
||||||
|
{
|
||||||
|
dibdrv_physdev *pdev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pdev) );
|
||||||
|
|
||||||
|
if (!pdev) return FALSE;
|
||||||
|
if (!(pdev->clip = CreateRectRgn(0, 0, 0, 0)))
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, pdev );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
clear_dib_info(&pdev->dib);
|
||||||
|
clear_dib_info(&pdev->brush_dib);
|
||||||
|
push_dc_driver( dev, &pdev->dev, &dib_driver );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* dibdrv_DeleteDC
|
* dibdrv_DeleteDC
|
||||||
*/
|
*/
|
||||||
|
@ -359,7 +379,8 @@ static BOOL dibdrv_DeleteDC( PHYSDEV dev )
|
||||||
DeleteObject(pdev->clip);
|
DeleteObject(pdev->clip);
|
||||||
free_pattern_brush(pdev);
|
free_pattern_brush(pdev);
|
||||||
free_dib_info(&pdev->dib);
|
free_dib_info(&pdev->dib);
|
||||||
return 0;
|
HeapFree( GetProcessHeap(), 0, pdev );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -375,13 +396,8 @@ static HBITMAP dibdrv_SelectBitmap( PHYSDEV dev, HBITMAP bitmap )
|
||||||
if (!bmp) return 0;
|
if (!bmp) return 0;
|
||||||
assert(bmp->dib);
|
assert(bmp->dib);
|
||||||
|
|
||||||
pdev->clip = CreateRectRgn(0, 0, 0, 0);
|
free_dib_info(&pdev->dib);
|
||||||
pdev->defer = 0;
|
pdev->defer = 0;
|
||||||
|
|
||||||
clear_dib_info(&pdev->dib);
|
|
||||||
clear_dib_info(&pdev->brush_dib);
|
|
||||||
pdev->brush_and_bits = pdev->brush_xor_bits = NULL;
|
|
||||||
|
|
||||||
if(!init_dib_info_from_bitmapobj(&pdev->dib, bmp, private_color_table))
|
if(!init_dib_info_from_bitmapobj(&pdev->dib, bmp, private_color_table))
|
||||||
pdev->defer |= DEFER_FORMAT;
|
pdev->defer |= DEFER_FORMAT;
|
||||||
|
|
||||||
|
@ -494,7 +510,7 @@ const DC_FUNCTIONS dib_driver =
|
||||||
NULL, /* pCloseFigure */
|
NULL, /* pCloseFigure */
|
||||||
NULL, /* pCreateBitmap */
|
NULL, /* pCreateBitmap */
|
||||||
NULL, /* pCreateCompatibleDC */
|
NULL, /* pCreateCompatibleDC */
|
||||||
NULL, /* pCreateDC */
|
dibdrv_CreateDC, /* pCreateDC */
|
||||||
NULL, /* pCreateDIBSection */
|
NULL, /* pCreateDIBSection */
|
||||||
NULL, /* pDeleteBitmap */
|
NULL, /* pDeleteBitmap */
|
||||||
dibdrv_DeleteDC, /* pDeleteDC */
|
dibdrv_DeleteDC, /* pDeleteDC */
|
||||||
|
|
|
@ -40,11 +40,6 @@ static inline dibdrv_physdev *get_dibdrv_pdev( PHYSDEV dev )
|
||||||
return (dibdrv_physdev *)dev;
|
return (dibdrv_physdev *)dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline DC *get_dibdrv_dc( PHYSDEV dev )
|
|
||||||
{
|
|
||||||
return CONTAINING_RECORD( dev, DC, dibdrv );
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct primitive_funcs
|
typedef struct primitive_funcs
|
||||||
{
|
{
|
||||||
void (* solid_rects)(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor);
|
void (* solid_rects)(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor);
|
||||||
|
|
|
@ -186,8 +186,8 @@ typedef struct tagDC
|
||||||
GDIOBJHDR header;
|
GDIOBJHDR header;
|
||||||
HDC hSelf; /* Handle to this DC */
|
HDC hSelf; /* Handle to this DC */
|
||||||
struct gdi_physdev nulldrv; /* physdev for the null driver */
|
struct gdi_physdev nulldrv; /* physdev for the null driver */
|
||||||
struct dibdrv_physdev dibdrv; /* physdev for the dib driver */
|
PHYSDEV dibdrv; /* physdev for the dib driver */
|
||||||
PHYSDEV physDev; /* Physical device (driver-specific) */
|
PHYSDEV physDev; /* current top of the physdev stack */
|
||||||
DWORD thread; /* thread owning the DC */
|
DWORD thread; /* thread owning the DC */
|
||||||
LONG refcount; /* thread refcount */
|
LONG refcount; /* thread refcount */
|
||||||
LONG dirty; /* dirty flag */
|
LONG dirty; /* dirty flag */
|
||||||
|
|
Loading…
Reference in New Issue