Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
3ed9eb36
Commit
3ed9eb36
authored
Mar 07, 2014
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xcb/glx: reuse the GLX provider code and eliminate a lot of code
parent
26a023d8
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
30 additions
and
269 deletions
+30
-269
modules/video_output/xcb/glx.c
modules/video_output/xcb/glx.c
+30
-269
No files found.
modules/video_output/xcb/glx.c
View file @
3ed9eb36
...
...
@@ -29,12 +29,9 @@
#include <assert.h>
#include <xcb/xcb.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_xlib.h>
#include <vlc_vout_display.h>
#include <vlc_opengl.h>
#include "../opengl.h"
...
...
@@ -60,17 +57,13 @@ vlc_module_end ()
struct
vout_display_sys_t
{
Display
*
display
;
/* Xlib instance */
xcb_connection_t
*
conn
;
/**< XCB connection */
vout_window_t
*
embed
;
/* VLC window (when windowed) */
vlc_gl_t
*
gl
;
xcb_cursor_t
cursor
;
/* blank cursor */
xcb_window_t
window
;
/* drawable X window */
xcb_window_t
glwin
;
/* GLX window */
bool
visible
;
/* whether to draw */
GLXContext
ctx
;
vlc_gl_t
gl
;
vout_display_opengl_t
*
vgl
;
picture_pool_t
*
pool
;
/* picture pool */
};
...
...
@@ -81,100 +74,19 @@ static void PictureDisplay (vout_display_t *, picture_t *, subpicture_t *);
static
int
Control
(
vout_display_t
*
,
int
,
va_list
);
static
void
Manage
(
vout_display_t
*
);
static
void
SwapBuffers
(
vlc_gl_t
*
gl
);
static
void
*
GetProcAddress
(
vlc_gl_t
*
gl
,
const
char
*
);
static
unsigned
GetScreenNumber
(
xcb_connection_t
*
conn
,
const
xcb_screen_t
*
screen
)
{
const
xcb_setup_t
*
setup
=
xcb_get_setup
(
conn
);
unsigned
num
=
0
;
for
(
xcb_screen_iterator_t
i
=
xcb_setup_roots_iterator
(
setup
);;
xcb_screen_next
(
&
i
))
{
if
(
i
.
data
->
root
==
screen
->
root
)
return
num
;
num
++
;
}
}
static
bool
CheckGLX
(
vout_display_t
*
vd
,
Display
*
dpy
)
{
int
major
,
minor
;
bool
ok
=
false
;
if
(
!
glXQueryVersion
(
dpy
,
&
major
,
&
minor
))
msg_Dbg
(
vd
,
"GLX extension not available"
);
else
if
(
major
!=
1
)
msg_Dbg
(
vd
,
"GLX extension version %d.%d unknown"
,
major
,
minor
);
else
if
(
minor
<
3
)
msg_Dbg
(
vd
,
"GLX extension version %d.%d too old"
,
major
,
minor
);
else
{
msg_Dbg
(
vd
,
"using GLX extension version %d.%d"
,
major
,
minor
);
ok
=
true
;
}
return
ok
;
}
static
int
CreateWindow
(
vout_display_t
*
vd
,
xcb_connection_t
*
conn
,
const
xcb_screen_t
*
screen
,
uint_fast16_t
width
,
uint_fast16_t
height
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
xcb_pixmap_t
pixmap
=
xcb_generate_id
(
conn
);
const
uint32_t
mask
=
XCB_CW_BACK_PIXMAP
|
XCB_CW_BACK_PIXEL
|
XCB_CW_BORDER_PIXMAP
|
XCB_CW_BORDER_PIXEL
|
XCB_CW_EVENT_MASK
|
XCB_CW_COLORMAP
;
const
uint32_t
values
[]
=
{
pixmap
,
screen
->
black_pixel
,
pixmap
,
screen
->
black_pixel
,
XCB_EVENT_MASK_VISIBILITY_CHANGE
,
screen
->
default_colormap
,
};
xcb_void_cookie_t
cc
,
cm
;
xcb_create_pixmap
(
conn
,
screen
->
root_depth
,
pixmap
,
screen
->
root
,
1
,
1
);
cc
=
xcb_create_window_checked
(
conn
,
screen
->
root_depth
,
sys
->
window
,
sys
->
embed
->
handle
.
xid
,
0
,
0
,
width
,
height
,
0
,
XCB_WINDOW_CLASS_INPUT_OUTPUT
,
screen
->
root_visual
,
mask
,
values
);
cm
=
xcb_map_window_checked
(
conn
,
sys
->
window
);
if
(
XCB_error_Check
(
vd
,
conn
,
"cannot create X11 window"
,
cc
)
||
XCB_error_Check
(
vd
,
conn
,
"cannot map X11 window"
,
cm
))
return
VLC_EGENERIC
;
msg_Dbg
(
vd
,
"using X11 window %08"
PRIx32
,
sys
->
window
);
return
VLC_SUCCESS
;
}
/**
* Probe the X server.
*/
static
int
Open
(
vlc_object_t
*
obj
)
{
if
(
!
vlc_xlib_init
(
obj
))
return
VLC_EGENERIC
;
vout_display_t
*
vd
=
(
vout_display_t
*
)
obj
;
vout_display_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
if
(
sys
==
NULL
)
return
VLC_ENOMEM
;
vd
->
sys
=
sys
;
sys
->
vgl
=
NULL
;
sys
->
pool
=
NULL
;
sys
->
gl
.
sys
=
NULL
;
/* Get window, connect to X server (via XCB) */
xcb_connection_t
*
conn
;
...
...
@@ -186,142 +98,30 @@ static int Open (vlc_object_t *obj)
free
(
sys
);
return
VLC_EGENERIC
;
}
const
unsigned
snum
=
GetScreenNumber
(
conn
,
scr
);
sys
->
conn
=
conn
;
Display
*
dpy
=
XOpenDisplay
(
sys
->
embed
->
display
.
x11
);
if
(
dpy
==
NULL
)
{
xcb_disconnect
(
conn
);
vout_display_DeleteWindow
(
vd
,
sys
->
embed
);
free
(
sys
);
return
VLC_EGENERIC
;
}
sys
->
display
=
dpy
;
sys
->
ctx
=
NULL
;
if
(
!
CheckGLX
(
vd
,
dpy
))
goto
error
;
sys
->
window
=
xcb_generate_id
(
conn
);
/* Determine our pixel format */
static
const
int
attr
[]
=
{
GLX_RED_SIZE
,
5
,
GLX_GREEN_SIZE
,
5
,
GLX_BLUE_SIZE
,
5
,
GLX_DOUBLEBUFFER
,
True
,
GLX_X_RENDERABLE
,
True
,
GLX_DRAWABLE_TYPE
,
GLX_WINDOW_BIT
,
None
};
xcb_get_window_attributes_reply_t
*
wa
=
xcb_get_window_attributes_reply
(
conn
,
xcb_get_window_attributes
(
conn
,
sys
->
embed
->
handle
.
xid
),
NULL
);
if
(
wa
==
NULL
)
goto
error
;
xcb_visualid_t
visual
=
wa
->
visual
;
free
(
wa
);
int
nelem
;
GLXFBConfig
*
confs
=
glXChooseFBConfig
(
dpy
,
snum
,
attr
,
&
nelem
);
if
(
confs
==
NULL
)
{
msg_Err
(
vd
,
"no GLX frame buffer configurations"
);
goto
error
;
}
GLXFBConfig
conf
;
bool
found
=
false
;
for
(
int
i
=
0
;
i
<
nelem
&&
!
found
;
i
++
)
{
conf
=
confs
[
i
];
XVisualInfo
*
vi
=
glXGetVisualFromFBConfig
(
dpy
,
conf
);
if
(
vi
==
NULL
)
continue
;
if
(
vi
->
visualid
==
visual
)
found
=
true
;
XFree
(
vi
);
}
XFree
(
confs
);
if
(
!
found
)
{
msg_Err
(
vd
,
"no matching GLX frame buffer configuration"
);
sys
->
gl
=
vlc_gl_Create
(
sys
->
embed
,
VLC_OPENGL
,
"glx"
);
if
(
sys
->
gl
==
NULL
)
goto
error
;
}
sys
->
glwin
=
None
;
if
(
!
CreateWindow
(
vd
,
conn
,
scr
,
width
,
height
))
sys
->
glwin
=
glXCreateWindow
(
dpy
,
conf
,
sys
->
window
,
NULL
);
if
(
sys
->
glwin
==
None
)
{
msg_Err
(
vd
,
"cannot create GLX window"
);
goto
error
;
}
/* Create an OpenGL context */
sys
->
ctx
=
glXCreateNewContext
(
dpy
,
conf
,
GLX_RGBA_TYPE
,
NULL
,
True
);
if
(
sys
->
ctx
==
NULL
)
{
msg_Err
(
vd
,
"cannot create GLX context"
);
goto
error
;
}
const
vlc_fourcc_t
*
spu_chromas
;
if
(
!
glXMakeContextCurrent
(
dpy
,
sys
->
glwin
,
sys
->
glwin
,
sys
->
ctx
))
if
(
vlc_gl_MakeCurrent
(
sys
->
gl
))
goto
error
;
const
char
*
glx_extensions
=
glXQueryExtensionsString
(
dpy
,
snum
);
bool
is_swap_interval_set
=
false
;
#ifdef GLX_SGI_swap_control
if
(
HasExtension
(
glx_extensions
,
"GLX_SGI_swap_control"
))
{
PFNGLXSWAPINTERVALSGIPROC
SwapIntervalSGI
=
(
PFNGLXSWAPINTERVALSGIPROC
)
GetProcAddress
(
NULL
,
"glXSwapIntervalSGI"
);
if
(
!
is_swap_interval_set
&&
SwapIntervalSGI
)
is_swap_interval_set
=
!
SwapIntervalSGI
(
1
);
}
#endif
#ifdef GLX_EXT_swap_control
if
(
HasExtension
(
glx_extensions
,
"GLX_EXT_swap_control"
))
{
PFNGLXSWAPINTERVALEXTPROC
SwapIntervalEXT
=
(
PFNGLXSWAPINTERVALEXTPROC
)
GetProcAddress
(
NULL
,
"glXSwapIntervalEXT"
);
if
(
!
is_swap_interval_set
&&
SwapIntervalEXT
)
{
SwapIntervalEXT
(
dpy
,
sys
->
glwin
,
1
);
is_swap_interval_set
=
true
;
}
}
#endif
/* Initialize common OpenGL video display */
sys
->
gl
.
lock
=
NULL
;
sys
->
gl
.
unlock
=
NULL
;
sys
->
gl
.
swap
=
SwapBuffers
;
sys
->
gl
.
getProcAddress
=
GetProcAddress
;
sys
->
gl
.
sys
=
sys
;
vout_display_info_t
info
=
vd
->
info
;
info
.
has_pictures_invalid
=
false
;
info
.
has_event_thread
=
true
;
sys
->
vgl
=
vout_display_opengl_New
(
&
vd
->
fmt
,
&
info
.
subpicture_chromas
,
&
sys
->
gl
);
glXMakeContextCurrent
(
dpy
,
None
,
None
,
NULL
);
sys
->
vgl
=
vout_display_opengl_New
(
&
vd
->
fmt
,
&
spu_chromas
,
sys
->
gl
);
vlc_gl_ReleaseCurrent
(
sys
->
gl
);
if
(
sys
->
vgl
==
NULL
)
{
sys
->
gl
.
sys
=
NULL
;
goto
error
;
}
sys
->
cursor
=
XCB_cursor_Create
(
conn
,
scr
);
sys
->
visible
=
false
;
/* Setup vout_display_t once everything is fine */
vd
->
info
=
info
;
vd
->
sys
=
sys
;
vd
->
info
.
has_pictures_invalid
=
false
;
vd
->
info
.
has_event_thread
=
true
;
vd
->
info
.
subpicture_chromas
=
spu_chromas
;
vd
->
pool
=
Pool
;
vd
->
prepare
=
PictureRender
;
vd
->
display
=
PictureDisplay
;
...
...
@@ -338,7 +138,11 @@ static int Open (vlc_object_t *obj)
return
VLC_SUCCESS
;
error:
Close
(
obj
);
if
(
sys
->
gl
!=
NULL
)
vlc_gl_Destroy
(
sys
->
gl
);
xcb_disconnect
(
sys
->
conn
);
vout_display_DeleteWindow
(
vd
,
sys
->
embed
);
free
(
sys
);
return
VLC_EGENERIC
;
}
...
...
@@ -350,20 +154,11 @@ static void Close (vlc_object_t *obj)
{
vout_display_t
*
vd
=
(
vout_display_t
*
)
obj
;
vout_display_sys_t
*
sys
=
vd
->
sys
;
Display
*
dpy
=
sys
->
display
;
if
(
sys
->
gl
.
sys
!=
NULL
)
{
glXMakeContextCurrent
(
dpy
,
sys
->
glwin
,
sys
->
glwin
,
sys
->
ctx
);
vlc_gl_MakeCurrent
(
sys
->
gl
);
vout_display_opengl_Delete
(
sys
->
vgl
);
glXMakeContextCurrent
(
dpy
,
None
,
None
,
NULL
);
}
if
(
sys
->
ctx
!=
NULL
)
{
glXDestroyContext
(
dpy
,
sys
->
ctx
);
glXDestroyWindow
(
dpy
,
sys
->
glwin
);
}
XCloseDisplay
(
dpy
);
vlc_gl_ReleaseCurrent
(
sys
->
gl
);
vlc_gl_Destroy
(
sys
->
gl
);
/* show the default cursor */
xcb_change_window_attributes
(
sys
->
conn
,
sys
->
embed
->
handle
.
xid
,
...
...
@@ -375,23 +170,6 @@ static void Close (vlc_object_t *obj)
free
(
sys
);
}
static
void
SwapBuffers
(
vlc_gl_t
*
gl
)
{
vout_display_sys_t
*
sys
=
gl
->
sys
;
glXSwapBuffers
(
sys
->
display
,
sys
->
glwin
);
}
static
void
*
GetProcAddress
(
vlc_gl_t
*
gl
,
const
char
*
name
)
{
(
void
)
gl
;
#ifdef GLX_ARB_get_proc_address
return
glXGetProcAddressARB
((
const
GLubyte
*
)
name
);
#else
return
NULL
;
#endif
}
/**
* Return a direct buffer
*/
...
...
@@ -401,11 +179,9 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
if
(
!
sys
->
pool
)
{
Display
*
dpy
=
sys
->
display
;
glXMakeContextCurrent
(
dpy
,
sys
->
glwin
,
sys
->
glwin
,
sys
->
ctx
);
vlc_gl_MakeCurrent
(
sys
->
gl
);
sys
->
pool
=
vout_display_opengl_GetPool
(
sys
->
vgl
,
requested_count
);
glXMakeContextCurrent
(
dpy
,
None
,
None
,
NULL
);
vlc_gl_ReleaseCurrent
(
sys
->
gl
);
}
return
sys
->
pool
;
}
...
...
@@ -413,21 +189,19 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
static
void
PictureRender
(
vout_display_t
*
vd
,
picture_t
*
pic
,
subpicture_t
*
subpicture
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
Display
*
dpy
=
sys
->
display
;
glXMakeContextCurrent
(
dpy
,
sys
->
glwin
,
sys
->
glwin
,
sys
->
ctx
);
vlc_gl_MakeCurrent
(
sys
->
gl
);
vout_display_opengl_Prepare
(
sys
->
vgl
,
pic
,
subpicture
);
glXMakeContextCurrent
(
dpy
,
None
,
None
,
NULL
);
vlc_gl_ReleaseCurrent
(
sys
->
gl
);
}
static
void
PictureDisplay
(
vout_display_t
*
vd
,
picture_t
*
pic
,
subpicture_t
*
subpicture
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
Display
*
dpy
=
sys
->
display
;
glXMakeContextCurrent
(
dpy
,
sys
->
glwin
,
sys
->
glwin
,
sys
->
ctx
);
vlc_gl_MakeCurrent
(
sys
->
gl
);
vout_display_opengl_Display
(
sys
->
vgl
,
&
vd
->
source
);
glXMakeContextCurrent
(
dpy
,
None
,
None
,
NULL
);
vlc_gl_ReleaseCurrent
(
sys
->
gl
);
picture_Release
(
pic
);
if
(
subpicture
)
...
...
@@ -484,22 +258,9 @@ static int Control (vout_display_t *vd, int query, va_list ap)
vout_display_place_t
place
;
vout_display_PlacePicture
(
&
place
,
source
,
cfg
,
false
);
/* Move the picture within the window */
const
uint32_t
values
[]
=
{
place
.
x
,
place
.
y
,
place
.
width
,
place
.
height
,
};
xcb_void_cookie_t
ck
=
xcb_configure_window_checked
(
sys
->
conn
,
sys
->
window
,
XCB_CONFIG_WINDOW_X
|
XCB_CONFIG_WINDOW_Y
|
XCB_CONFIG_WINDOW_WIDTH
|
XCB_CONFIG_WINDOW_HEIGHT
,
values
);
if
(
XCB_error_Check
(
vd
,
sys
->
conn
,
"cannot resize X11 window"
,
ck
))
return
VLC_EGENERIC
;
Display
*
dpy
=
sys
->
display
;
glXMakeContextCurrent
(
dpy
,
sys
->
glwin
,
sys
->
glwin
,
sys
->
ctx
);
vlc_gl_MakeCurrent
(
sys
->
gl
);
glViewport
(
0
,
0
,
place
.
width
,
place
.
height
);
glXMakeContextCurrent
(
dpy
,
None
,
None
,
NULL
);
vlc_gl_ReleaseCurrent
(
sys
->
gl
);
return
VLC_SUCCESS
;
}
...
...
@@ -514,7 +275,7 @@ static int Control (vout_display_t *vd, int query, va_list ap)
case
VOUT_DISPLAY_GET_OPENGL
:
{
vlc_gl_t
**
gl
=
va_arg
(
ap
,
vlc_gl_t
**
);
*
gl
=
&
sys
->
gl
;
*
gl
=
sys
->
gl
;
return
VLC_SUCCESS
;
}
...
...
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