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
b86787e5
Commit
b86787e5
authored
Apr 26, 2010
by
Roderick Colenbrander
Committed by
Alexandre Julliard
Apr 27, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wgl: Improve wglDeleteContext threading behavior.
parent
bfc4c710
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
100 additions
and
18 deletions
+100
-18
opengl.c
dlls/opengl32/tests/opengl.c
+56
-0
opengl.c
dlls/winex11.drv/opengl.c
+44
-18
No files found.
dlls/opengl32/tests/opengl.c
View file @
b86787e5
...
...
@@ -499,6 +499,61 @@ static void test_acceleration(HDC hdc)
}
}
struct
wgl_thread_param
{
HANDLE
test_finished
;
HGLRC
hglrc
;
BOOL
hglrc_deleted
;
};
static
DWORD
WINAPI
wgl_thread
(
void
*
param
)
{
struct
wgl_thread_param
*
p
=
param
;
p
->
hglrc_deleted
=
wglDeleteContext
(
p
->
hglrc
);
SetEvent
(
p
->
test_finished
);
return
0
;
}
static
void
test_deletecontext
(
HDC
hdc
)
{
struct
wgl_thread_param
thread_params
;
HGLRC
hglrc
=
wglCreateContext
(
hdc
);
HANDLE
thread_handle
;
DWORD
res
,
tid
;
if
(
!
hglrc
)
{
skip
(
"wglCreateContext failed!
\n
"
);
return
;
}
res
=
wglMakeCurrent
(
hdc
,
hglrc
);
if
(
!
res
)
{
skip
(
"wglMakeCurrent failed!
\n
"
);
return
;
}
/* WGL doesn't allow you to delete a context from a different thread than the one in which it is current.
* This differs from GLX which does allow it but it delays actual deletion until the context becomes not current.
*/
thread_params
.
hglrc
=
hglrc
;
thread_params
.
test_finished
=
CreateEvent
(
NULL
,
FALSE
,
FALSE
,
NULL
);
thread_handle
=
CreateThread
(
NULL
,
0
,
wgl_thread
,
&
thread_params
,
0
,
&
tid
);
ok
(
!!
thread_handle
,
"Failed to create thread, last error %#x.
\n
"
,
GetLastError
());
if
(
thread_handle
)
{
WaitForSingleObject
(
thread_handle
,
INFINITE
);
ok
(
thread_params
.
hglrc_deleted
==
FALSE
,
"Attempt to delete WGL context from another thread passed but should fail!
\n
"
);
}
CloseHandle
(
thread_params
.
test_finished
);
res
=
wglDeleteContext
(
hglrc
);
ok
(
res
==
TRUE
,
"wglDeleteContext failed
\n
"
);
}
static
void
test_make_current_read
(
HDC
hdc
)
{
int
res
;
...
...
@@ -802,6 +857,7 @@ START_TEST(opengl)
return
;
}
test_deletecontext
(
hdc
);
test_makecurrent
(
hdc
);
test_setpixelformat
(
hdc
);
test_sharelists
(
hdc
);
...
...
dlls/winex11.drv/opengl.c
View file @
b86787e5
...
...
@@ -113,6 +113,7 @@ typedef struct wine_glcontext {
BOOL
do_escape
;
BOOL
has_been_current
;
BOOL
sharing
;
DWORD
tid
;
BOOL
gl3_context
;
XVisualInfo
*
vis
;
WineGLPixelFormat
*
fmt
;
...
...
@@ -1763,29 +1764,33 @@ HGLRC CDECL X11DRV_wglCreateContext(X11DRV_PDEVICE *physDev)
BOOL
CDECL
X11DRV_wglDeleteContext
(
HGLRC
hglrc
)
{
Wine_GLContext
*
ctx
=
(
Wine_GLContext
*
)
hglrc
;
BOOL
ret
=
TRUE
;
TRACE
(
"(%p)
\n
"
,
hglrc
);
if
(
!
has_opengl
())
return
0
;
wine_tsx11_lock
();
/* A game (Half Life not to name it) deletes twice the same context,
* so make sure it is valid first */
if
(
is_valid_context
(
ctx
))
{
if
(
ctx
->
ctx
)
pglXDestroyContext
(
gdi_display
,
ctx
->
ctx
);
free_context
(
ctx
);
}
else
if
(
!
is_valid_context
(
ctx
))
{
WARN
(
"Error deleting context !
\n
"
);
SetLastError
(
ERROR_INVALID_HANDLE
);
ret
=
FALSE
;
ret
urn
FALSE
;
}
wine_tsx11_unlock
();
return
ret
;
/* WGL doesn't allow deletion of a context which is current in another thread */
if
(
ctx
->
tid
!=
0
&&
ctx
->
tid
!=
GetCurrentThreadId
())
{
TRACE
(
"Cannot delete context=%p because it is current in another thread.
\n
"
,
ctx
);
return
FALSE
;
}
if
(
ctx
->
ctx
)
{
wine_tsx11_lock
();
pglXDestroyContext
(
gdi_display
,
ctx
->
ctx
);
wine_tsx11_unlock
();
}
return
TRUE
;
}
/**
...
...
@@ -1857,16 +1862,26 @@ BOOL CDECL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
if
(
!
has_opengl
())
return
FALSE
;
wine_tsx11_lock
();
if
(
hglrc
==
NULL
)
{
if
(
hglrc
==
NULL
)
{
Wine_GLContext
*
prev_ctx
=
NtCurrentTeb
()
->
glContext
;
if
(
prev_ctx
)
prev_ctx
->
tid
=
0
;
ret
=
pglXMakeCurrent
(
gdi_display
,
None
,
NULL
);
NtCurrentTeb
()
->
glContext
=
NULL
;
}
else
if
(
ctx
->
fmt
->
iPixelFormat
!=
physDev
->
current_pf
)
{
}
else
if
(
ctx
->
fmt
->
iPixelFormat
!=
physDev
->
current_pf
)
{
WARN
(
"mismatched pixel format hdc %p %u ctx %p %u
\n
"
,
hdc
,
physDev
->
current_pf
,
ctx
,
ctx
->
fmt
->
iPixelFormat
);
SetLastError
(
ERROR_INVALID_PIXEL_FORMAT
);
ret
=
FALSE
;
}
else
{
}
else
{
Drawable
drawable
=
get_glxdrawable
(
physDev
);
Wine_GLContext
*
prev_ctx
=
NtCurrentTeb
()
->
glContext
;
if
(
prev_ctx
)
prev_ctx
->
tid
=
0
;
/* The describe lines below are for debugging purposes only */
if
(
TRACE_ON
(
wgl
))
{
...
...
@@ -1881,6 +1896,7 @@ BOOL CDECL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
if
(
ret
)
{
ctx
->
has_been_current
=
TRUE
;
ctx
->
tid
=
GetCurrentThreadId
();
ctx
->
hdc
=
hdc
;
ctx
->
read_hdc
=
hdc
;
ctx
->
drawables
[
0
]
=
drawable
;
...
...
@@ -1913,18 +1929,28 @@ BOOL CDECL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEV
if
(
!
has_opengl
())
return
0
;
wine_tsx11_lock
();
if
(
hglrc
==
NULL
)
{
if
(
hglrc
==
NULL
)
{
Wine_GLContext
*
prev_ctx
=
NtCurrentTeb
()
->
glContext
;
if
(
prev_ctx
)
prev_ctx
->
tid
=
0
;
ret
=
pglXMakeCurrent
(
gdi_display
,
None
,
NULL
);
NtCurrentTeb
()
->
glContext
=
NULL
;
}
else
{
}
else
{
if
(
NULL
==
pglXMakeContextCurrent
)
{
ret
=
FALSE
;
}
else
{
Wine_GLContext
*
prev_ctx
=
NtCurrentTeb
()
->
glContext
;
Wine_GLContext
*
ctx
=
(
Wine_GLContext
*
)
hglrc
;
Drawable
d_draw
=
get_glxdrawable
(
pDrawDev
);
Drawable
d_read
=
get_glxdrawable
(
pReadDev
);
if
(
prev_ctx
)
prev_ctx
->
tid
=
0
;
ctx
->
has_been_current
=
TRUE
;
ctx
->
tid
=
GetCurrentThreadId
();
ctx
->
hdc
=
pDrawDev
->
hdc
;
ctx
->
read_hdc
=
pReadDev
->
hdc
;
ctx
->
drawables
[
0
]
=
d_draw
;
...
...
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