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
7da242db
Commit
7da242db
authored
Nov 07, 1999
by
Ove Kaaven
Committed by
Alexandre Julliard
Nov 07, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DirectX-XShm now waits for the X server to finish the previous frame
before sending another frame down its pipe, avoiding the X server overload and resulting slowness that used to be.
parent
56403478
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
140 additions
and
5 deletions
+140
-5
ddraw.c
graphics/ddraw.c
+10
-3
ddraw_private.h
graphics/ddraw_private.h
+1
-1
ts_xlib.h
include/ts_xlib.h
+1
-0
x11drv.h
include/x11drv.h
+3
-0
X11_calls
tsx11/X11_calls
+1
-0
ts_xlib.c
tsx11/ts_xlib.c
+11
-0
event.c
windows/x11drv/event.c
+113
-1
No files found.
graphics/ddraw.c
View file @
7da242db
...
...
@@ -708,7 +708,11 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
This
->
s
.
palette
);
#ifdef HAVE_LIBXXSHM
if
(
This
->
s
.
ddraw
->
e
.
xlib
.
xshm_active
)
if
(
This
->
s
.
ddraw
->
e
.
xlib
.
xshm_active
)
{
int
compl
=
This
->
s
.
ddraw
->
e
.
xlib
.
xshm_compl
;
if
(
compl
)
X11DRV_EVENT_WaitShmCompletion
(
compl
);
This
->
s
.
ddraw
->
e
.
xlib
.
xshm_compl
=
X11DRV_EVENT_PrepareShmCompletion
(
This
->
s
.
ddraw
->
d
.
drawable
);
TSXShmPutImage
(
display
,
This
->
s
.
ddraw
->
d
.
drawable
,
DefaultGCOfScreen
(
X11DRV_GetXScreen
()),
...
...
@@ -716,7 +720,8 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
0
,
0
,
0
,
0
,
This
->
t
.
xlib
.
image
->
width
,
This
->
t
.
xlib
.
image
->
height
,
False
);
True
);
}
else
#endif
TSXPutImage
(
display
,
...
...
@@ -5027,8 +5032,10 @@ static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUn
#ifdef HAVE_LIBXXSHM
/* Test if XShm is available. */
if
(((
*
ilplpDD
)
->
e
.
xlib
.
xshm_active
=
DDRAW_XSHM_Available
()))
if
(((
*
ilplpDD
)
->
e
.
xlib
.
xshm_active
=
DDRAW_XSHM_Available
()))
{
(
*
ilplpDD
)
->
e
.
xlib
.
xshm_compl
=
0
;
TRACE
(
"Using XShm extension.
\n
"
);
}
#endif
return
DD_OK
;
...
...
graphics/ddraw_private.h
View file @
7da242db
...
...
@@ -81,7 +81,7 @@ struct _dga_directdrawdata
struct
_xlib_directdrawdata
{
#ifdef HAVE_LIBXXSHM
int
xshm_active
;
int
xshm_active
,
xshm_compl
;
#endif
/* defined(HAVE_LIBXXSHM) */
/* are these needed for anything? (draw_surf is the active surface)
...
...
include/ts_xlib.h
View file @
7da242db
...
...
@@ -53,6 +53,7 @@ extern int TSXChangeGC(Display*, GC, unsigned long, XGCValues*);
extern
int
TSXChangeKeyboardControl
(
Display
*
,
unsigned
long
,
XKeyboardControl
*
);
extern
int
TSXChangeProperty
(
Display
*
,
Window
,
Atom
,
Atom
,
int
,
int
,
const
unsigned
char
*
,
int
);
extern
int
TSXChangeWindowAttributes
(
Display
*
,
Window
,
unsigned
long
,
XSetWindowAttributes
*
);
extern
int
TSXCheckTypedEvent
(
Display
*
,
int
,
XEvent
*
);
extern
int
TSXCheckTypedWindowEvent
(
Display
*
,
Window
,
int
,
XEvent
*
);
extern
int
TSXCheckWindowEvent
(
Display
*
,
Window
,
long
,
XEvent
*
);
extern
int
TSXConvertSelection
(
Display
*
,
Atom
,
Atom
,
Atom
,
Window
,
Time
);
...
...
include/x11drv.h
View file @
7da242db
...
...
@@ -469,4 +469,7 @@ extern void X11DRV_WND_SetDrawable(struct tagWND *wndPtr, struct tagDC *dc, WORD
extern
BOOL
X11DRV_WND_SetHostAttr
(
struct
tagWND
*
wndPtr
,
INT
haKey
,
INT
value
);
extern
BOOL
X11DRV_WND_IsSelfClipping
(
struct
tagWND
*
wndPtr
);
extern
int
X11DRV_EVENT_PrepareShmCompletion
(
Drawable
dw
);
extern
void
X11DRV_EVENT_WaitShmCompletion
(
int
compl
);
#endif
/* __WINE_X11DRV_H */
tsx11/X11_calls
View file @
7da242db
...
...
@@ -16,6 +16,7 @@ XChangeGC
XChangeKeyboardControl
XChangeProperty
XChangeWindowAttributes
XCheckTypedEvent
XCheckTypedWindowEvent
XCheckWindowEvent
XClipBox
...
...
tsx11/ts_xlib.c
View file @
7da242db
...
...
@@ -422,6 +422,17 @@ int TSXChangeWindowAttributes(Display* a0, Window a1, unsigned long a2, XSetWin
return
r
;
}
int
TSXCheckTypedEvent
(
Display
*
a0
,
int
a1
,
XEvent
*
a2
)
{
int
r
;
TRACE
(
"Call XCheckTypedEvent
\n
"
);
EnterCriticalSection
(
&
X11DRV_CritSection
);
r
=
XCheckTypedEvent
(
a0
,
a1
,
a2
);
LeaveCriticalSection
(
&
X11DRV_CritSection
);
TRACE
(
"Ret XCheckTypedEvent
\n
"
);
return
r
;
}
int
TSXCheckTypedWindowEvent
(
Display
*
a0
,
Window
a1
,
int
a2
,
XEvent
*
a3
)
{
int
r
;
...
...
windows/x11drv/event.c
View file @
7da242db
...
...
@@ -14,6 +14,9 @@
#include "ts_xlib.h"
#include "ts_xresource.h"
#include "ts_xutil.h"
#ifdef HAVE_LIBXXSHM
#include "ts_xshm.h"
#endif
#include <assert.h>
#include <string.h>
...
...
@@ -102,6 +105,11 @@ static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
static
void
EVENT_MapNotify
(
HWND
pWnd
,
XMapEvent
*
event
);
static
void
EVENT_UnmapNotify
(
HWND
pWnd
,
XUnmapEvent
*
event
);
#ifdef HAVE_LIBXXSHM
static
void
EVENT_ShmCompletion
(
XShmCompletionEvent
*
event
);
static
int
ShmCompletionType
;
#endif
/* Usable only with OLVWM - compile option perhaps?
static void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event );
*/
...
...
@@ -121,6 +129,10 @@ static BOOL in_transition = FALSE; /* This is not used as for today */
*/
BOOL
X11DRV_EVENT_Init
(
void
)
{
#ifdef HAVE_LIBXXSHM
ShmCompletionType
=
XShmGetEventBase
(
display
)
+
ShmCompletion
;
#endif
/* Install the X event processing callback */
SERVICE_AddObject
(
FILE_DupUnixHandle
(
ConnectionNumber
(
display
),
GENERIC_READ
|
SYNCHRONIZE
),
...
...
@@ -150,7 +162,7 @@ static void CALLBACK EVENT_ProcessAllEvents( ULONG_PTR arg )
{
XEvent
event
;
TRACE_
(
event
)(
"called
.
\n
"
);
TRACE_
(
event
)(
"called
(thread %lx).
\n
"
,
GetCurrentThreadId
()
);
EnterCriticalSection
(
&
X11DRV_CritSection
);
while
(
XPending
(
display
)
)
...
...
@@ -211,6 +223,13 @@ static void EVENT_ProcessEvent( XEvent *event )
case
ReparentNotify
:
return
;
}
#ifdef HAVE_LIBXXSHM
if
(
event
->
type
==
ShmCompletionType
)
{
EVENT_ShmCompletion
(
(
XShmCompletionEvent
*
)
event
);
return
;
}
#endif
if
(
TSXFindContext
(
display
,
event
->
xany
.
window
,
winContext
,
(
char
**
)
&
hWnd
)
!=
0
)
{
...
...
@@ -373,6 +392,7 @@ static void EVENT_ProcessEvent( XEvent *event )
event_names
[
event
->
type
],
hWnd
);
break
;
}
TRACE_
(
event
)(
"returns.
\n
"
);
}
/***********************************************************************
...
...
@@ -1780,4 +1800,96 @@ INPUT_TYPE X11DRV_EVENT_SetInputMehod(INPUT_TYPE type)
return
prev
;
}
#ifdef HAVE_LIBXXSHM
/*
Normal XShm operation:
X11 service thread app thread
------------- ----------------- ------------------------
(idle) ddraw calls XShmPutImage
(copies data) (waiting for shm_event)
ShmCompletion -> (waiting for shm_event)
(idle) signal shm_event ->
(idle) returns to app
However, this situation can occur for some reason:
X11 service thread app thread
------------- ----------------- ------------------------
Expose ->
WM_ERASEBKGND? ->
(waiting for app) ddraw calls XShmPutImage
(copies data) (waiting for app) (waiting for shm_event)
ShmCompletion (waiting for app) (waiting for shm_event)
(idle) DEADLOCK DEADLOCK
which is why I also wait for shm_read and do XCheckTypedEvent()
calls in the wait loop. This results in:
X11 service thread app thread
------------- ----------------- ------------------------
ShmCompletion (waiting for app) waking up on shm_read
(idle) (waiting for app) XCheckTypedEvent() -> signal shm_event
(waiting for app) returns
(idle)
*/
/* FIXME: this is not pretty */
static
Drawable
shm_draw
=
0
;
static
HANDLE
shm_event
=
0
,
shm_read
=
0
;
static
void
EVENT_ShmCompletion
(
XShmCompletionEvent
*
event
)
{
TRACE_
(
event
)(
"Got ShmCompletion for drawable %ld (time %ld)
\n
"
,
event
->
drawable
,
GetTickCount
()
);
if
(
event
->
drawable
==
shm_draw
)
{
HANDLE
event
=
shm_event
;
shm_draw
=
0
;
shm_event
=
0
;
SetEvent
(
event
);
TRACE_
(
event
)(
"Event object triggered
\n
"
);
}
else
ERR_
(
event
)(
"Got ShmCompletion for unknown drawable %ld
\n
"
,
event
->
drawable
);
}
int
X11DRV_EVENT_PrepareShmCompletion
(
Drawable
dw
)
{
if
(
shm_draw
)
{
ERR_
(
event
)(
"Multiple ShmCompletion requests not implemented
\n
"
);
return
0
;
}
TRACE_
(
event
)(
"Preparing ShmCompletion (%d) wait for drawable %ld (time %ld)
\n
"
,
ShmCompletionType
,
dw
,
GetTickCount
()
);
shm_draw
=
dw
;
if
(
!
shm_event
)
/* use manual reset just in case */
shm_event
=
ConvertToGlobalHandle
(
CreateEventA
(
NULL
,
TRUE
,
FALSE
,
NULL
)
);
if
(
!
shm_read
)
shm_read
=
ConvertToGlobalHandle
(
FILE_DupUnixHandle
(
ConnectionNumber
(
display
),
GENERIC_READ
|
SYNCHRONIZE
)
);
return
shm_event
;
}
void
X11DRV_EVENT_WaitShmCompletion
(
int
compl
)
{
if
(
!
compl
)
return
;
TRACE_
(
event
)(
"Waiting for ShmCompletion (%d) (thread %lx) (time %ld)
\n
"
,
ShmCompletionType
,
GetCurrentThreadId
(),
GetTickCount
()
);
/* already triggered? */
if
(
WaitForSingleObject
(
compl
,
0
)
!=
WAIT_OBJECT_0
)
{
/* nope, may need to poll X event queue, in case the service thread is blocked */
XEvent
event
;
HANDLE
hnd
[
2
];
hnd
[
0
]
=
compl
;
hnd
[
1
]
=
shm_read
;
do
{
/* check X event queue */
if
(
TSXCheckTypedEvent
(
display
,
ShmCompletionType
,
&
event
))
{
EVENT_ProcessEvent
(
&
event
);
}
}
while
(
WaitForMultipleObjects
(
2
,
hnd
,
FALSE
,
INFINITE
)
>
WAIT_OBJECT_0
);
}
ResetEvent
(
compl
);
/* manual reset */
TRACE_
(
event
)(
"Wait complete (time %ld)
\n
"
,
GetTickCount
()
);
}
#endif
#endif
/* !defined(X_DISPLAY_MISSING) */
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