Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
d88ff791
Commit
d88ff791
authored
Aug 31, 2007
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: New DC locking mechanism that doesn't require holding the global GDI lock.
parent
ee2db299
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
138 additions
and
34 deletions
+138
-34
bitmap.c
dlls/gdi32/bitmap.c
+1
-1
clipping.c
dlls/gdi32/clipping.c
+1
-4
dc.c
dlls/gdi32/dc.c
+118
-28
init.c
dlls/gdi32/enhmfdrv/init.c
+6
-0
gdi_private.h
dlls/gdi32/gdi_private.h
+6
-1
init.c
dlls/gdi32/mfdrv/init.c
+6
-0
No files found.
dlls/gdi32/bitmap.c
View file @
d88ff791
...
...
@@ -587,7 +587,7 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
if
(
handle
)
{
dc
->
hBitmap
=
handle
;
dc
->
flags
&=
~
DC_DIRTY
;
dc
->
dirty
=
0
;
SetRectRgn
(
dc
->
hVisRgn
,
0
,
0
,
bitmap
->
bitmap
.
bmWidth
,
bitmap
->
bitmap
.
bmHeight
);
DC_InitDC
(
dc
);
}
...
...
dlls/gdi32/clipping.c
View file @
d88ff791
...
...
@@ -58,8 +58,6 @@ void CLIPPING_UpdateGCRegion( DC * dc )
exit
(
1
);
}
if
(
dc
->
flags
&
DC_DIRTY
)
ERR
(
"DC is dirty. Please report this.
\n
"
);
/* update the intersection of meta and clip regions */
if
(
dc
->
hMetaRgn
&&
dc
->
hClipRgn
)
{
...
...
@@ -177,7 +175,7 @@ INT16 WINAPI SelectVisRgn16( HDC16 hdc16, HRGN16 hrgn )
TRACE
(
"%p %04x
\n
"
,
hdc
,
hrgn
);
dc
->
flags
&=
~
DC_DIRTY
;
dc
->
dirty
=
0
;
retval
=
CombineRgn
(
dc
->
hVisRgn
,
HRGN_32
(
hrgn
),
0
,
RGN_COPY
);
CLIPPING_UpdateGCRegion
(
dc
);
...
...
@@ -547,7 +545,6 @@ INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 )
dc
->
saved_visrgn
=
saved
->
next
;
DeleteObject
(
saved
->
hrgn
);
HeapFree
(
GetProcessHeap
(),
0
,
saved
);
dc
->
flags
&=
~
DC_DIRTY
;
CLIPPING_UpdateGCRegion
(
dc
);
done:
DC_ReleaseDCPtr
(
dc
);
...
...
dlls/gdi32/dc.c
View file @
d88ff791
...
...
@@ -20,6 +20,7 @@
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -50,6 +51,25 @@ static const struct gdi_obj_funcs dc_funcs =
DC_DeleteObject
/* pDeleteObject */
};
static
inline
DC
*
get_dc_obj
(
HDC
hdc
)
{
DC
*
dc
=
GDI_GetObjPtr
(
hdc
,
MAGIC_DONTCARE
);
if
(
!
dc
)
return
NULL
;
if
((
GDIMAGIC
(
dc
->
header
.
wMagic
)
!=
DC_MAGIC
)
&&
(
GDIMAGIC
(
dc
->
header
.
wMagic
)
!=
MEMORY_DC_MAGIC
)
&&
(
GDIMAGIC
(
dc
->
header
.
wMagic
)
!=
METAFILE_DC_MAGIC
)
&&
(
GDIMAGIC
(
dc
->
header
.
wMagic
)
!=
ENHMETAFILE_DC_MAGIC
))
{
GDI_ReleaseObj
(
hdc
);
SetLastError
(
ERROR_INVALID_HANDLE
);
dc
=
NULL
;
}
return
dc
;
}
/***********************************************************************
* DC_AllocDC
*/
...
...
@@ -63,6 +83,9 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
dc
->
hSelf
=
hdc
;
dc
->
funcs
=
funcs
;
dc
->
physDev
=
NULL
;
dc
->
thread
=
GetCurrentThreadId
();
dc
->
refcount
=
1
;
dc
->
dirty
=
0
;
dc
->
saveLevel
=
0
;
dc
->
saved_dc
=
0
;
dc
->
dwHookData
=
0
;
...
...
@@ -136,16 +159,22 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
*/
DC
*
DC_GetDCPtr
(
HDC
hdc
)
{
GDIOBJHDR
*
ptr
=
GDI_GetObjPtr
(
hdc
,
MAGIC_DONTCARE
);
if
(
!
ptr
)
return
NULL
;
if
((
GDIMAGIC
(
ptr
->
wMagic
)
==
DC_MAGIC
)
||
(
GDIMAGIC
(
ptr
->
wMagic
)
==
MEMORY_DC_MAGIC
)
||
(
GDIMAGIC
(
ptr
->
wMagic
)
==
METAFILE_DC_MAGIC
)
||
(
GDIMAGIC
(
ptr
->
wMagic
)
==
ENHMETAFILE_DC_MAGIC
))
return
(
DC
*
)
ptr
;
GDI_ReleaseObj
(
hdc
);
SetLastError
(
ERROR_INVALID_HANDLE
);
return
NULL
;
DC
*
dc
=
get_dc_obj
(
hdc
);
if
(
!
dc
)
return
NULL
;
if
(
!
InterlockedCompareExchange
(
&
dc
->
refcount
,
1
,
0
))
{
dc
->
thread
=
GetCurrentThreadId
();
}
else
if
(
dc
->
thread
!=
GetCurrentThreadId
())
{
GDI_ReleaseObj
(
hdc
);
SetLastError
(
ERROR_ACCESS_DENIED
);
return
NULL
;
}
else
InterlockedIncrement
(
&
dc
->
refcount
);
return
dc
;
}
/***********************************************************************
...
...
@@ -159,10 +188,9 @@ DC *DC_GetDCUpdate( HDC hdc )
{
DC
*
dc
=
DC_GetDCPtr
(
hdc
);
if
(
!
dc
)
return
NULL
;
while
(
dc
->
flags
&
DC_DIRTY
)
while
(
InterlockedExchange
(
&
dc
->
dirty
,
0
)
)
{
DCHOOKPROC
proc
=
dc
->
hookThunk
;
dc
->
flags
&=
~
DC_DIRTY
;
if
(
proc
)
{
DWORD_PTR
data
=
dc
->
dwHookData
;
...
...
@@ -181,6 +209,7 @@ DC *DC_GetDCUpdate( HDC hdc )
*/
void
DC_ReleaseDCPtr
(
DC
*
dc
)
{
release_dc_ptr
(
dc
);
GDI_ReleaseObj
(
dc
->
hSelf
);
}
...
...
@@ -190,11 +219,67 @@ void DC_ReleaseDCPtr( DC *dc )
*/
BOOL
DC_FreeDCPtr
(
DC
*
dc
)
{
assert
(
dc
->
refcount
==
1
);
return
GDI_FreeObject
(
dc
->
hSelf
,
dc
);
}
/***********************************************************************
* get_dc_ptr
*
* Retrieve a DC pointer but release the GDI lock.
*/
DC
*
get_dc_ptr
(
HDC
hdc
)
{
DC
*
dc
=
get_dc_obj
(
hdc
);
if
(
!
dc
)
return
NULL
;
if
(
!
InterlockedCompareExchange
(
&
dc
->
refcount
,
1
,
0
))
{
dc
->
thread
=
GetCurrentThreadId
();
}
else
if
(
dc
->
thread
!=
GetCurrentThreadId
())
{
WARN
(
"dc %p belongs to thread %04x
\n
"
,
hdc
,
dc
->
thread
);
GDI_ReleaseObj
(
hdc
);
return
NULL
;
}
else
InterlockedIncrement
(
&
dc
->
refcount
);
GDI_ReleaseObj
(
hdc
);
return
dc
;
}
/***********************************************************************
* release_dc_ptr
*/
void
release_dc_ptr
(
DC
*
dc
)
{
LONG
ref
;
dc
->
thread
=
0
;
ref
=
InterlockedDecrement
(
&
dc
->
refcount
);
assert
(
ref
>=
0
);
if
(
ref
)
dc
->
thread
=
GetCurrentThreadId
();
/* we still own it */
}
/***********************************************************************
* update_dc
*
* Make sure the DC vis region is up to date.
* This function may call up to USER so the GDI lock should _not_
* be held when calling it.
*/
void
update_dc
(
DC
*
dc
)
{
if
(
InterlockedExchange
(
&
dc
->
dirty
,
0
)
&&
dc
->
hookThunk
)
dc
->
hookThunk
(
dc
->
hSelf
,
DCHC_INVALIDVISRGN
,
dc
->
dwHookData
,
0
);
}
/***********************************************************************
* DC_DeleteObject
*/
static
BOOL
DC_DeleteObject
(
HGDIOBJ
handle
,
void
*
obj
)
...
...
@@ -355,6 +440,8 @@ HDC WINAPI GetDCState( HDC hdc )
newdc
->
BoundsRect
=
dc
->
BoundsRect
;
newdc
->
hSelf
=
(
HDC
)
handle
;
newdc
->
thread
=
GetCurrentThreadId
();
newdc
->
refcount
=
1
;
newdc
->
saveLevel
=
0
;
newdc
->
saved_dc
=
0
;
...
...
@@ -415,7 +502,7 @@ void WINAPI SetDCState( HDC hdc, HDC hdcs )
}
TRACE
(
"%p %p
\n
"
,
hdc
,
hdcs
);
dc
->
flags
=
dcs
->
flags
&
~
(
DC_SAVED
|
DC_DIRTY
)
;
dc
->
flags
=
dcs
->
flags
&
~
DC_SAVED
;
dc
->
layout
=
dcs
->
layout
;
dc
->
hDevice
=
dcs
->
hDevice
;
dc
->
ROPmode
=
dcs
->
ROPmode
;
...
...
@@ -801,6 +888,12 @@ BOOL WINAPI DeleteDC( HDC hdc )
GDI_CheckNotLock
();
if
(
!
(
dc
=
DC_GetDCPtr
(
hdc
)))
return
FALSE
;
if
(
dc
->
refcount
!=
1
)
{
FIXME
(
"not deleting busy DC %p refcount %u
\n
"
,
dc
->
hSelf
,
dc
->
refcount
);
DC_ReleaseDCPtr
(
dc
);
return
FALSE
;
}
/* Call hook procedure to check whether is it OK to delete this DC */
if
(
dc
->
hookThunk
)
...
...
@@ -1419,25 +1512,22 @@ DWORD WINAPI GetDCHook16( HDC16 hdc16, FARPROC16 *phookProc )
WORD
WINAPI
SetHookFlags16
(
HDC16
hdc16
,
WORD
flags
)
{
HDC
hdc
=
HDC_32
(
hdc16
);
DC
*
dc
=
DC_GetDCPtr
(
hdc
);
DC
*
dc
=
get_dc_obj
(
hdc
);
/* not get_dc_ptr, this needs to work from any thread */
LONG
ret
=
0
;
if
(
dc
)
{
WORD
wRet
=
dc
->
flags
&
DC_DIRTY
;
if
(
!
dc
)
return
0
;
/* "Undocumented Windows" info is slightly confusing.
*/
/* "Undocumented Windows" info is slightly confusing. */
TRACE
(
"hDC %p, flags %04x
\n
"
,
hdc
,
flags
);
TRACE
(
"hDC %p, flags %04x
\n
"
,
hdc
,
flags
);
if
(
flags
&
DCHF_INVALIDATEVISRGN
)
dc
->
flags
|=
DC_DIRTY
;
else
if
(
flags
&
DCHF_VALIDATEVISRGN
||
!
flags
)
dc
->
flags
&=
~
DC_DIRTY
;
DC_ReleaseDCPtr
(
dc
);
return
wRet
;
}
return
0
;
if
(
flags
&
DCHF_INVALIDATEVISRGN
)
ret
=
InterlockedExchange
(
&
dc
->
dirty
,
1
);
else
if
(
flags
&
DCHF_VALIDATEVISRGN
||
!
flags
)
ret
=
InterlockedExchange
(
&
dc
->
dirty
,
0
);
GDI_ReleaseObj
(
dc
);
return
ret
;
}
/***********************************************************************
...
...
dlls/gdi32/enhmfdrv/init.c
View file @
d88ff791
...
...
@@ -444,6 +444,12 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
DC_ReleaseDCPtr
(
dc
);
return
NULL
;
}
if
(
dc
->
refcount
!=
1
)
{
FIXME
(
"not deleting busy DC %p refcount %u
\n
"
,
dc
->
hSelf
,
dc
->
refcount
);
DC_ReleaseDCPtr
(
dc
);
return
NULL
;
}
physDev
=
(
EMFDRV_PDEVICE
*
)
dc
->
physDev
;
if
(
dc
->
saveLevel
)
...
...
dlls/gdi32/gdi_private.h
View file @
d88ff791
...
...
@@ -269,6 +269,9 @@ typedef struct tagDC
HDC
hSelf
;
/* Handle to this DC */
const
struct
tagDC_FUNCS
*
funcs
;
/* DC function table */
PHYSDEV
physDev
;
/* Physical device (driver-specific) */
DWORD
thread
;
/* thread owning the DC */
LONG
refcount
;
/* thread refcount */
LONG
dirty
;
/* dirty flag */
INT
saveLevel
;
HDC
saved_dc
;
DWORD_PTR
dwHookData
;
...
...
@@ -335,7 +338,6 @@ typedef struct tagDC
/* DC flags */
#define DC_SAVED 0x0002
/* It is a saved DC */
#define DC_DIRTY 0x0004
/* hVisRgn has to be updated */
#define DC_BOUNDS_ENABLE 0x0008
/* Bounding rectangle tracking is enabled */
#define DC_BOUNDS_SET 0x0010
/* Bounding rectangle has been set */
...
...
@@ -397,6 +399,9 @@ extern DC * DC_GetDCUpdate( HDC hdc );
extern
DC
*
DC_GetDCPtr
(
HDC
hdc
);
extern
void
DC_ReleaseDCPtr
(
DC
*
dc
);
extern
BOOL
DC_FreeDCPtr
(
DC
*
dc
);
extern
DC
*
get_dc_ptr
(
HDC
hdc
);
extern
void
release_dc_ptr
(
DC
*
dc
);
extern
void
update_dc
(
DC
*
dc
);
extern
void
DC_InitDC
(
DC
*
dc
);
extern
void
DC_UpdateXforms
(
DC
*
dc
);
...
...
dlls/gdi32/mfdrv/init.c
View file @
d88ff791
...
...
@@ -314,6 +314,12 @@ static DC *MFDRV_CloseMetaFile( HDC hdc )
DC_ReleaseDCPtr
(
dc
);
return
NULL
;
}
if
(
dc
->
refcount
!=
1
)
{
FIXME
(
"not deleting busy DC %p refcount %u
\n
"
,
dc
->
hSelf
,
dc
->
refcount
);
DC_ReleaseDCPtr
(
dc
);
return
NULL
;
}
physDev
=
(
METAFILEDRV_PDEVICE
*
)
dc
->
physDev
;
/* Construct the end of metafile record - this is documented
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment