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
ac4f2ac3
Commit
ac4f2ac3
authored
Feb 12, 2018
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winex11: Hold a reference to the drawable from the GL context.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
6dc30a2e
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
106 additions
and
29 deletions
+106
-29
opengl.c
dlls/winex11.drv/opengl.c
+59
-17
window.c
dlls/winex11.drv/window.c
+47
-12
No files found.
dlls/winex11.drv/opengl.c
View file @
ac4f2ac3
...
...
@@ -217,7 +217,8 @@ struct wgl_context
int
numAttribs
;
/* This is needed for delaying wglCreateContextAttribsARB */
int
attribList
[
16
];
/* This is needed for delaying wglCreateContextAttribsARB */
GLXContext
ctx
;
GLXDrawable
drawables
[
2
];
struct
gl_drawable
*
drawables
[
2
];
struct
gl_drawable
*
new_drawables
[
2
];
BOOL
refresh_drawables
;
struct
list
entry
;
};
...
...
@@ -1228,12 +1229,15 @@ static void release_gl_drawable( struct gl_drawable *gl )
if
(
InterlockedDecrement
(
&
gl
->
ref
))
return
;
switch
(
gl
->
type
)
{
case
DC_GL_WINDOW
:
case
DC_GL_CHILD_WIN
:
TRACE
(
"destroying %lx drawable %lx
\n
"
,
gl
->
window
,
gl
->
drawable
);
pglXDestroyWindow
(
gdi_display
,
gl
->
drawable
);
XDestroyWindow
(
gdi_display
,
gl
->
window
);
XFreeColormap
(
gdi_display
,
gl
->
colormap
);
if
(
gl
->
colormap
)
XFreeColormap
(
gdi_display
,
gl
->
colormap
);
break
;
case
DC_GL_PIXMAP_WIN
:
TRACE
(
"destroying pixmap %lx drawable %lx
\n
"
,
gl
->
pixmap
,
gl
->
drawable
);
pglXDestroyPixmap
(
gdi_display
,
gl
->
drawable
);
XFreePixmap
(
gdi_display
,
gl
->
pixmap
);
break
;
...
...
@@ -1251,13 +1255,15 @@ static void mark_drawable_dirty( struct gl_drawable *old, struct gl_drawable *ne
EnterCriticalSection
(
&
context_section
);
LIST_FOR_EACH_ENTRY
(
ctx
,
&
context_list
,
struct
wgl_context
,
entry
)
{
if
(
old
->
drawable
==
ctx
->
drawables
[
0
])
{
ctx
->
drawables
[
0
]
=
new
->
drawable
;
ctx
->
refresh_drawables
=
TRUE
;
if
(
old
==
ctx
->
drawables
[
0
]
||
old
==
ctx
->
new_drawables
[
0
])
{
release_gl_drawable
(
ctx
->
new_drawables
[
0
]
);
ctx
->
new_drawables
[
0
]
=
grab_gl_drawable
(
new
);
}
if
(
old
->
drawable
==
ctx
->
drawables
[
1
])
{
ctx
->
drawables
[
1
]
=
new
->
drawable
;
ctx
->
refresh_drawables
=
TRUE
;
if
(
old
==
ctx
->
drawables
[
1
]
||
old
==
ctx
->
new_drawables
[
1
])
{
release_gl_drawable
(
ctx
->
new_drawables
[
1
]
);
ctx
->
new_drawables
[
1
]
=
grab_gl_drawable
(
new
);
}
}
LeaveCriticalSection
(
&
context_section
);
...
...
@@ -1266,14 +1272,30 @@ static void mark_drawable_dirty( struct gl_drawable *old, struct gl_drawable *ne
/* Given the current context, make sure its drawable is sync'd */
static
inline
void
sync_context
(
struct
wgl_context
*
context
)
{
BOOL
refresh
=
FALSE
;
EnterCriticalSection
(
&
context_section
);
if
(
context
->
refresh_drawables
)
{
if
(
context
->
new_drawables
[
0
])
{
release_gl_drawable
(
context
->
drawables
[
0
]
);
context
->
drawables
[
0
]
=
context
->
new_drawables
[
0
];
context
->
new_drawables
[
0
]
=
NULL
;
refresh
=
TRUE
;
}
if
(
context
->
new_drawables
[
1
])
{
release_gl_drawable
(
context
->
drawables
[
1
]
);
context
->
drawables
[
1
]
=
context
->
new_drawables
[
1
];
context
->
new_drawables
[
1
]
=
NULL
;
refresh
=
TRUE
;
}
if
(
refresh
)
{
if
(
glxRequireVersion
(
3
))
pglXMakeContextCurrent
(
gdi_display
,
context
->
drawables
[
0
],
context
->
drawables
[
1
],
context
->
ctx
);
pglXMakeContextCurrent
(
gdi_display
,
context
->
drawables
[
0
]
->
drawable
,
context
->
drawables
[
1
]
->
drawable
,
context
->
ctx
);
else
pglXMakeCurrent
(
gdi_display
,
context
->
drawables
[
0
],
context
->
ctx
);
context
->
refresh_drawables
=
FALSE
;
pglXMakeCurrent
(
gdi_display
,
context
->
drawables
[
0
]
->
drawable
,
context
->
ctx
);
}
LeaveCriticalSection
(
&
context_section
);
}
...
...
@@ -1385,6 +1407,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel
if
(
gl
->
window
)
gl
->
drawable
=
pglXCreateWindow
(
gdi_display
,
gl
->
format
->
fbconfig
,
gl
->
window
,
NULL
);
release_win_data
(
data
);
TRACE
(
"%p created client %lx drawable %lx
\n
"
,
hwnd
,
gl
->
window
,
gl
->
drawable
);
}
}
#ifdef SONAME_LIBXCOMPOSITE
...
...
@@ -1425,6 +1448,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel
}
}
else
XFreeColormap
(
gdi_display
,
gl
->
colormap
);
TRACE
(
"%p created child %lx drawable %lx
\n
"
,
hwnd
,
gl
->
window
,
gl
->
drawable
);
}
#endif
else
...
...
@@ -1837,6 +1861,10 @@ static BOOL glxdrv_wglDeleteContext(struct wgl_context *ctx)
LeaveCriticalSection
(
&
context_section
);
if
(
ctx
->
ctx
)
pglXDestroyContext
(
gdi_display
,
ctx
->
ctx
);
release_gl_drawable
(
ctx
->
drawables
[
0
]
);
release_gl_drawable
(
ctx
->
drawables
[
1
]
);
release_gl_drawable
(
ctx
->
new_drawables
[
0
]
);
release_gl_drawable
(
ctx
->
new_drawables
[
1
]
);
return
HeapFree
(
GetProcessHeap
(),
0
,
ctx
);
}
...
...
@@ -1849,6 +1877,22 @@ static PROC glxdrv_wglGetProcAddress(LPCSTR lpszProc)
return
pglXGetProcAddressARB
((
const
GLubyte
*
)
lpszProc
);
}
static
void
set_context_drawables
(
struct
wgl_context
*
ctx
,
struct
gl_drawable
*
draw
,
struct
gl_drawable
*
read
)
{
struct
gl_drawable
*
prev
[
4
];
int
i
;
prev
[
0
]
=
ctx
->
drawables
[
0
];
prev
[
1
]
=
ctx
->
drawables
[
1
];
prev
[
2
]
=
ctx
->
new_drawables
[
0
];
prev
[
3
]
=
ctx
->
new_drawables
[
1
];
ctx
->
drawables
[
0
]
=
grab_gl_drawable
(
draw
);
ctx
->
drawables
[
1
]
=
read
?
grab_gl_drawable
(
read
)
:
NULL
;
ctx
->
new_drawables
[
0
]
=
ctx
->
new_drawables
[
1
]
=
NULL
;
for
(
i
=
0
;
i
<
4
;
i
++
)
release_gl_drawable
(
prev
[
i
]
);
}
/***********************************************************************
* glxdrv_wglMakeCurrent
*/
...
...
@@ -1885,8 +1929,7 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
NtCurrentTeb
()
->
glContext
=
ctx
;
ctx
->
has_been_current
=
TRUE
;
ctx
->
hdc
=
hdc
;
ctx
->
drawables
[
0
]
=
gl
->
drawable
;
ctx
->
drawables
[
1
]
=
gl
->
drawable
;
set_context_drawables
(
ctx
,
gl
,
gl
);
ctx
->
refresh_drawables
=
FALSE
;
LeaveCriticalSection
(
&
context_section
);
goto
done
;
...
...
@@ -1931,8 +1974,7 @@ static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct
{
ctx
->
has_been_current
=
TRUE
;
ctx
->
hdc
=
draw_hdc
;
ctx
->
drawables
[
0
]
=
draw_gl
->
drawable
;
ctx
->
drawables
[
1
]
=
read_gl
?
read_gl
->
drawable
:
0
;
set_context_drawables
(
ctx
,
draw_gl
,
read_gl
);
ctx
->
refresh_drawables
=
FALSE
;
NtCurrentTeb
()
->
glContext
=
ctx
;
LeaveCriticalSection
(
&
context_section
);
...
...
dlls/winex11.drv/window.c
View file @
ac4f2ac3
...
...
@@ -1390,11 +1390,37 @@ static void move_window_bits( HWND hwnd, Window window, const RECT *old_rect, co
}
/***********************************************************************
* get_dummy_parent
*
* Create a dummy parent window for child windows that don't have a true X11 parent.
*/
static
Window
get_dummy_parent
(
void
)
{
static
Window
dummy_parent
;
if
(
!
dummy_parent
)
{
XSetWindowAttributes
attrib
;
attrib
.
override_redirect
=
True
;
attrib
.
border_pixel
=
0
;
attrib
.
colormap
=
default_colormap
;
dummy_parent
=
XCreateWindow
(
gdi_display
,
root_window
,
-
1
,
-
1
,
1
,
1
,
0
,
default_visual
.
depth
,
InputOutput
,
default_visual
.
visual
,
CWColormap
|
CWBorderPixel
|
CWOverrideRedirect
,
&
attrib
);
XMapWindow
(
gdi_display
,
dummy_parent
);
}
return
dummy_parent
;
}
/**********************************************************************
* create_client_window
*/
Window
create_client_window
(
struct
x11drv_win_data
*
data
,
const
XVisualInfo
*
visual
)
{
Window
dummy_parent
=
get_dummy_parent
();
XSetWindowAttributes
attr
;
int
x
=
data
->
client_rect
.
left
-
data
->
whole_rect
.
left
;
int
y
=
data
->
client_rect
.
top
-
data
->
whole_rect
.
top
;
...
...
@@ -1404,11 +1430,12 @@ Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *vi
if
(
data
->
client_window
)
{
XDeleteContext
(
data
->
display
,
data
->
client_window
,
winContext
);
XDestroyWindow
(
data
->
display
,
data
->
client_window
);
XReparentWindow
(
gdi_display
,
data
->
client_window
,
dummy_parent
,
0
,
0
);
TRACE
(
"%p reparent xwin %lx/%lx
\n
"
,
data
->
hwnd
,
data
->
whole_window
,
data
->
client_window
);
}
if
(
data
->
colormap
)
XFreeColormap
(
data
->
display
,
data
->
colormap
);
data
->
colormap
=
XCreateColormap
(
data
->
display
,
root_window
,
visual
->
visual
,
if
(
data
->
colormap
)
XFreeColormap
(
gdi_
display
,
data
->
colormap
);
data
->
colormap
=
XCreateColormap
(
gdi_display
,
dummy_parent
,
visual
->
visual
,
(
visual
->
class
==
PseudoColor
||
visual
->
class
==
GrayScale
||
visual
->
class
==
DirectColor
)
?
AllocAll
:
AllocNone
);
...
...
@@ -1416,18 +1443,19 @@ Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *vi
attr
.
bit_gravity
=
NorthWestGravity
;
attr
.
win_gravity
=
NorthWestGravity
;
attr
.
backing_store
=
NotUseful
;
attr
.
event_mask
=
ExposureMask
;
attr
.
border_pixel
=
0
;
data
->
client_window
=
XCreateWindow
(
data
->
display
,
data
->
whole_window
,
x
,
y
,
cx
,
cy
,
data
->
client_window
=
XCreateWindow
(
gdi_
display
,
data
->
whole_window
,
x
,
y
,
cx
,
cy
,
0
,
default_visual
.
depth
,
InputOutput
,
visual
->
visual
,
CWBitGravity
|
CWWinGravity
|
CWBackingStore
|
CWColormap
|
CW
EventMask
|
CW
BorderPixel
,
&
attr
);
CWColormap
|
CWBorderPixel
,
&
attr
);
if
(
!
data
->
client_window
)
return
0
;
TRACE
(
"%p xwin %lx/%lx
\n
"
,
data
->
hwnd
,
data
->
whole_window
,
data
->
client_window
);
XSaveContext
(
data
->
display
,
data
->
client_window
,
winContext
,
(
char
*
)
data
->
hwnd
);
XMapWindow
(
data
->
display
,
data
->
client_window
);
XSync
(
data
->
display
,
False
);
XMapWindow
(
gdi_display
,
data
->
client_window
);
XSync
(
gdi_display
,
False
);
XSelectInput
(
data
->
display
,
data
->
client_window
,
ExposureMask
);
return
data
->
client_window
;
}
...
...
@@ -1528,9 +1556,17 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
}
TRACE
(
"win %p xwin %lx
\n
"
,
data
->
hwnd
,
data
->
whole
_window
);
TRACE
(
"win %p xwin %lx
/%lx
\n
"
,
data
->
hwnd
,
data
->
whole_window
,
data
->
client
_window
);
XDeleteContext
(
data
->
display
,
data
->
whole_window
,
winContext
);
if
(
data
->
client_window
)
XDeleteContext
(
data
->
display
,
data
->
client_window
,
winContext
);
if
(
data
->
client_window
)
{
XDeleteContext
(
data
->
display
,
data
->
client_window
,
winContext
);
if
(
!
already_destroyed
)
{
XSelectInput
(
data
->
display
,
data
->
client_window
,
0
);
XReparentWindow
(
data
->
display
,
data
->
client_window
,
get_dummy_parent
(),
0
,
0
);
}
}
if
(
!
already_destroyed
)
XDestroyWindow
(
data
->
display
,
data
->
whole_window
);
if
(
data
->
colormap
)
XFreeColormap
(
data
->
display
,
data
->
colormap
);
data
->
whole_window
=
data
->
client_window
=
0
;
...
...
@@ -1633,8 +1669,6 @@ void CDECL X11DRV_DestroyWindow( HWND hwnd )
struct
x11drv_thread_data
*
thread_data
=
x11drv_thread_data
();
struct
x11drv_win_data
*
data
;
destroy_gl_drawable
(
hwnd
);
if
(
!
(
data
=
get_win_data
(
hwnd
)))
return
;
destroy_whole_window
(
data
,
FALSE
);
...
...
@@ -1646,6 +1680,7 @@ void CDECL X11DRV_DestroyWindow( HWND hwnd )
XDeleteContext
(
gdi_display
,
(
XID
)
hwnd
,
win_data_context
);
release_win_data
(
data
);
HeapFree
(
GetProcessHeap
(),
0
,
data
);
destroy_gl_drawable
(
hwnd
);
}
...
...
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