Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
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-gpu
Commits
e55de111
Commit
e55de111
authored
Feb 19, 2011
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
EGL: convert to OpenGL provider
parent
801fcb35
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
89 additions
and
235 deletions
+89
-235
modules/video_output/egl.c
modules/video_output/egl.c
+89
-235
No files found.
modules/video_output/egl.c
View file @
e55de111
/**
* @file egl.c
* @brief EGL
video output
module
* @brief EGL
OpenGL extension
module
*/
/*****************************************************************************
* Copyright © 2010-2011 Rémi Denis-Courmont
...
...
@@ -30,63 +30,47 @@
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
#include <vlc_opengl.h>
#include
"opengl.h"
#include
<vlc_vout_window.h>
#ifdef __unix__
# include <vlc_xlib.h>
#endif
#if USE_OPENGL_ES
# define VLC_API_NAME "OpenGL_ES"
# define VLC_API EGL_OPENGL_ES_API
# if USE_OPENGL_ES == 2
# define VLC_RENDERABLE_BIT EGL_OPENGL_ES2_BIT
# else
# define VLC_RENDERABLE_BIT EGL_OPENGL_ES_BIT
# endif
#else
# define VLC_API_NAME "OpenGL"
# define VLC_API EGL_OPENGL_API
# define VLC_RENDERABLE_BIT EGL_OPENGL_BIT
#endif
#ifdef __unix__
# include <dlfcn.h>
#endif
/* Plugin callbacks */
static
int
Open
(
vlc_object_t
*
);
static
int
OpenGLES2
(
vlc_object_t
*
);
static
int
OpenGLES
(
vlc_object_t
*
);
static
int
OpenGL
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
vlc_module_begin
()
set_shortname
(
N_
(
"EGL"
))
set_description
(
N_
(
"EGL
video output
"
))
set_description
(
N_
(
"EGL
extension for OpenGL
"
))
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
set_capability
(
"vout display"
,
0
)
set_callbacks
(
Open
,
Close
)
set_capability
(
"opengl"
,
50
)
set_callbacks
(
OpenGL
,
Close
)
add_submodule
()
set_capability
(
"opengl es2"
,
50
)
set_callbacks
(
OpenGLES2
,
Close
)
add_submodule
()
set_capability
(
"opengl es"
,
50
)
set_callbacks
(
OpenGLES
,
Close
)
vlc_module_end
()
struct
vout_display
_sys_t
typedef
struct
vlc_gl
_sys_t
{
EGLDisplay
display
;
EGLSurface
surface
;
EGLContext
context
;
}
vlc_gl_sys_t
;
vlc_gl_t
gl
;
vout_display_opengl_t
vgl
;
picture_pool_t
*
pool
;
vout_window_t
*
window
;
};
/* Display callbacks */
static
picture_pool_t
*
Pool
(
vout_display_t
*
,
unsigned
);
static
void
PictureRender
(
vout_display_t
*
,
picture_t
*
,
subpicture_t
*
);
static
void
PictureDisplay
(
vout_display_t
*
,
picture_t
*
,
subpicture_t
*
);
static
int
Control
(
vout_display_t
*
,
int
,
va_list
);
/* OpenGL callbacks */
static
void
SwapBuffers
(
vlc_gl_t
*
gl
);
static
int
MakeCurrent
(
vlc_gl_t
*
);
static
void
SwapBuffers
(
vlc_gl_t
*
);
static
bool
CheckAPI
(
EGLDisplay
dpy
,
const
char
*
api
)
{
...
...
@@ -107,45 +91,29 @@ static bool CheckAPI (EGLDisplay dpy, const char *api)
return
false
;
}
st
atic
vout_window_t
*
MakeWindow
(
vout_display_t
*
vd
,
EGLNativeWindowType
*
id
)
st
ruct
gl_api
{
vout_window_cfg_t
wnd_cfg
;
memset
(
&
wnd_cfg
,
0
,
sizeof
(
wnd_cfg
));
#if defined (WIN32)
wnd_cfg
.
type
=
VOUT_WINDOW_TYPE_HWND
;
#elif defined (__unix__)
wnd_cfg
.
type
=
VOUT_WINDOW_TYPE_XID
;
#else
# error Unknown native window type!
#endif
wnd_cfg
.
x
=
var_InheritInteger
(
vd
,
"video-x"
);
wnd_cfg
.
y
=
var_InheritInteger
(
vd
,
"video-y"
);
wnd_cfg
.
width
=
vd
->
cfg
->
display
.
width
;
wnd_cfg
.
height
=
vd
->
cfg
->
display
.
height
;
vout_window_t
*
wnd
=
vout_display_NewWindow
(
vd
,
&
wnd_cfg
);
if
(
wnd
!=
NULL
)
#if defined (WIN32)
*
id
=
wnd
->
handle
.
hwnd
;
#elif defined (__unix__)
*
id
=
wnd
->
handle
.
xid
;
#endif
else
msg_Err
(
vd
,
"parent window not available"
);
return
wnd
;
}
const
char
name
[
10
];
EGLenum
api
;
EGLint
min_minor
;
EGLint
render_bit
;
EGLint
attr
[
3
];
};
/**
* Probe EGL display availability
*/
static
int
Open
(
vlc_object_t
*
obj
)
static
int
Open
(
vlc_object_t
*
obj
,
const
struct
gl_api
*
api
)
{
vlc_gl_t
*
gl
=
(
vlc_gl_t
*
)
obj
;
#ifdef __unix__
/* EGL can only use the default X11 display */
if
(
gl
->
surface
->
display
.
x11
!=
NULL
)
return
VLC_EGENERIC
;
if
(
!
vlc_xlib_init
(
obj
))
return
VLC_EGENERIC
;
#endif
vout_display_t
*
vd
=
(
vout_display_t
*
)
obj
;
/* Initialize EGL display */
/* TODO: support various display types */
...
...
@@ -153,13 +121,11 @@ static int Open (vlc_object_t *obj)
if
(
dpy
==
EGL_NO_DISPLAY
)
return
VLC_EGENERIC
;
v
out_display
_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
v
lc_gl
_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
if
(
unlikely
(
sys
==
NULL
))
return
VLC_ENOMEM
;
vd
->
sys
=
sys
;
gl
->
sys
=
sys
;
sys
->
display
=
dpy
;
sys
->
gl
.
sys
=
NULL
;
sys
->
pool
=
NULL
;
#ifdef __unix__
/* XXX Explicit hack!
...
...
@@ -183,18 +149,8 @@ static int Open (vlc_object_t *obj)
return
VLC_EGENERIC
;
}
if
(
major
!=
1
)
goto
abort
;
#if USE_OPENGL_ES == 2
if
(
minor
<
3
)
/* Well well, this wouldn't compile with 1.2 anyway */
goto
abort
;
#elif USE_OPENGL_ES == 0
if
(
minor
<
4
)
goto
abort
;
#endif
if
(
!
CheckAPI
(
dpy
,
VLC_API_NAME
))
goto
abort
;
if
(
major
!=
1
||
minor
<
api
->
min_minor
||
!
CheckAPI
(
dpy
,
api
->
name
))
goto
error
;
msg_Dbg
(
obj
,
"EGL version %s by %s"
,
eglQueryString
(
dpy
,
EGL_VERSION
),
eglQueryString
(
dpy
,
EGL_VENDOR
));
...
...
@@ -204,11 +160,11 @@ static int Open (vlc_object_t *obj)
msg_Dbg
(
obj
,
" extensions: %s"
,
ext
);
}
static
const
EGLint
conf_attr
[]
=
{
const
EGLint
conf_attr
[]
=
{
EGL_RED_SIZE
,
5
,
EGL_GREEN_SIZE
,
5
,
EGL_BLUE_SIZE
,
5
,
EGL_RENDERABLE_TYPE
,
VLC_RENDERABLE_BIT
,
EGL_RENDERABLE_TYPE
,
api
->
render_bit
,
EGL_NONE
};
EGLConfig
cfgv
[
1
];
...
...
@@ -216,13 +172,14 @@ static int Open (vlc_object_t *obj)
if
(
eglChooseConfig
(
dpy
,
conf_attr
,
cfgv
,
1
,
&
cfgc
)
!=
EGL_TRUE
||
cfgc
==
0
)
goto
abort
;
goto
error
;
/* Create a drawing surface */
EGLNativeWindowType
win
;
sys
->
window
=
MakeWindow
(
vd
,
&
win
);
if
(
sys
->
window
==
NULL
)
goto
abort
;
#if defined (WIN32)
EGLNativeWindowType
win
=
gl
->
surface
->
handle
.
hwnd
;
#elif defined (__unix__)
EGLNativeWindowType
win
=
gl
->
surface
->
handle
.
xid
;
#endif
EGLSurface
surface
=
eglCreateWindowSurface
(
dpy
,
cfgv
[
0
],
win
,
NULL
);
if
(
surface
==
EGL_NO_SURFACE
)
...
...
@@ -232,186 +189,83 @@ static int Open (vlc_object_t *obj)
}
sys
->
surface
=
surface
;
if
(
eglBindAPI
(
VLC_API
)
!=
EGL_TRUE
)
if
(
eglBindAPI
(
api
->
api
)
!=
EGL_TRUE
)
{
msg_Err
(
obj
,
"cannot bind EGL API"
);
goto
error
;
}
static
const
EGLint
ctx_attr
[]
=
{
#if USE_OPENGL_ES
EGL_CONTEXT_CLIENT_VERSION
,
USE_OPENGL_ES
,
#endif
EGL_NONE
};
EGLContext
ctx
=
eglCreateContext
(
dpy
,
cfgv
[
0
],
EGL_NO_CONTEXT
,
ctx_
attr
);
api
->
attr
);
if
(
ctx
==
EGL_NO_CONTEXT
)
{
msg_Err
(
obj
,
"cannot create EGL context"
);
goto
error
;
}
if
(
eglMakeCurrent
(
dpy
,
surface
,
surface
,
ctx
)
!=
EGL_TRUE
)
goto
error
;
sys
->
context
=
ctx
;
/* Initialize OpenGL callbacks */
sys
->
gl
.
lock
=
NULL
;
sys
->
gl
.
unlock
=
NULL
;
sys
->
gl
.
swap
=
SwapBuffers
;
sys
->
gl
.
sys
=
sys
;
if
(
vout_display_opengl_Init
(
&
sys
->
vgl
,
&
vd
->
fmt
,
&
sys
->
gl
))
goto
error
;
/* Initialize video display */
vd
->
info
.
has_pictures_invalid
=
false
;
vd
->
info
.
has_event_thread
=
false
;
vd
->
pool
=
Pool
;
vd
->
prepare
=
PictureRender
;
vd
->
display
=
PictureDisplay
;
vd
->
control
=
Control
;
vd
->
manage
=
NULL
;
gl
->
sys
=
sys
;
gl
->
makeCurrent
=
MakeCurrent
;
gl
->
swap
=
SwapBuffers
;
gl
->
lock
=
NULL
;
gl
->
unlock
=
NULL
;
return
VLC_SUCCESS
;
error:
vout_display_DeleteWindow
(
vd
,
sys
->
window
);
abort:
eglTerminate
(
dpy
);
free
(
sys
);
Close
(
obj
);
return
VLC_EGENERIC
;
}
/**
* Destrisconnect from the X server.
*/
static
void
Close
(
vlc_object_t
*
obj
)
static
int
OpenGLES2
(
vlc_object_t
*
obj
)
{
vout_display_t
*
vd
=
(
vout_display_t
*
)
obj
;
vout_display_sys_t
*
sys
=
vd
->
sys
;
EGLDisplay
dpy
=
sys
->
display
;
if
(
sys
->
gl
.
sys
!=
NULL
)
vout_display_opengl_Clean
(
&
sys
->
vgl
);
eglTerminate
(
dpy
);
vout_display_DeleteWindow
(
vd
,
sys
->
window
);
free
(
sys
);
}
static
void
SwapBuffers
(
vlc_gl_t
*
gl
)
{
vout_display_sys_t
*
sys
=
gl
->
sys
;
eglSwapBuffers
(
sys
->
display
,
sys
->
surface
);
static
const
struct
gl_api
api
=
{
"OpenGL_ES"
,
EGL_OPENGL_ES_API
,
3
,
EGL_OPENGL_ES2_BIT
,
{
EGL_CONTEXT_CLIENT_VERSION
,
2
,
EGL_NONE
},
};
return
Open
(
obj
,
&
api
);
}
/**
* Return a direct buffer
*/
static
picture_pool_t
*
Pool
(
vout_display_t
*
vd
,
unsigned
count
)
static
int
OpenGLES
(
vlc_object_t
*
obj
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
if
(
!
sys
->
pool
)
sys
->
pool
=
vout_display_opengl_GetPool
(
&
sys
->
vgl
);
(
void
)
count
;
return
sys
->
pool
;
static
const
struct
gl_api
api
=
{
"OpenGL_ES"
,
EGL_OPENGL_ES_API
,
0
,
EGL_OPENGL_ES_BIT
,
{
EGL_CONTEXT_CLIENT_VERSION
,
1
,
EGL_NONE
},
};
return
Open
(
obj
,
&
api
);
}
static
void
PictureRender
(
vout_display_t
*
vd
,
picture_t
*
pic
,
subpicture_t
*
subpicture
)
static
int
OpenGL
(
vlc_object_t
*
obj
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
vout_display_opengl_Prepare
(
&
sys
->
vgl
,
pic
);
(
void
)
subpicture
;
static
const
struct
gl_api
api
=
{
"OpenGL"
,
EGL_OPENGL_API
,
4
,
EGL_OPENGL_BIT
,
{
EGL_NONE
},
};
return
Open
(
obj
,
&
api
);
}
static
void
PictureDisplay
(
vout_display_t
*
vd
,
picture_t
*
pic
,
subpicture_t
*
subpicture
)
static
void
Close
(
vlc_object_t
*
obj
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
vlc_gl_t
*
gl
=
(
vlc_gl_t
*
)
obj
;
vlc_gl_sys_t
*
sys
=
gl
->
sys
;
vout_display_opengl_Display
(
&
sys
->
vgl
,
&
vd
->
source
);
picture_Release
(
pic
);
(
void
)
subpicture
;
eglTerminate
(
sys
->
display
);
free
(
sys
);
}
static
int
Control
(
vout_display_t
*
vd
,
int
query
,
va_list
ap
)
static
int
MakeCurrent
(
vlc_gl_t
*
gl
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
switch
(
query
)
{
case
VOUT_DISPLAY_HIDE_MOUSE
:
case
VOUT_DISPLAY_RESET_PICTURES
:
// not needed?
break
;
case
VOUT_DISPLAY_CHANGE_FULLSCREEN
:
{
const
vout_display_cfg_t
*
cfg
=
va_arg
(
ap
,
const
vout_display_cfg_t
*
);
return
vout_window_SetFullScreen
(
sys
->
window
,
cfg
->
is_fullscreen
);
}
case
VOUT_DISPLAY_CHANGE_WINDOW_STATE
:
{
unsigned
state
=
va_arg
(
ap
,
unsigned
);
return
vout_window_SetState
(
sys
->
window
,
state
);
}
vlc_gl_sys_t
*
sys
=
gl
->
sys
;
case
VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
:
case
VOUT_DISPLAY_CHANGE_DISPLAY_FILLED
:
case
VOUT_DISPLAY_CHANGE_ZOOM
:
{
const
vout_display_cfg_t
*
cfg
=
va_arg
(
ap
,
const
vout_display_cfg_t
*
);
const
video_format_t
*
src
=
&
vd
->
source
;
if
(
query
==
VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
)
{
bool
force
=
false
;
force
=
va_arg
(
ap
,
int
);
if
(
force
&&
(
cfg
->
display
.
width
!=
vd
->
cfg
->
display
.
width
||
cfg
->
display
.
height
!=
vd
->
cfg
->
display
.
height
)
&&
vout_window_SetSize
(
sys
->
window
,
cfg
->
display
.
width
,
cfg
->
display
.
height
))
if
(
eglMakeCurrent
(
sys
->
display
,
sys
->
surface
,
sys
->
surface
,
sys
->
context
)
!=
EGL_TRUE
)
return
VLC_EGENERIC
;
}
vout_display_place_t
place
;
vout_display_PlacePicture
(
&
place
,
src
,
cfg
,
false
);
glViewport
(
0
,
0
,
place
.
width
,
place
.
height
);
return
VLC_SUCCESS
;
}
case
VOUT_DISPLAY_CHANGE_SOURCE_ASPECT
:
case
VOUT_DISPLAY_CHANGE_SOURCE_CROP
:
{
const
vout_display_cfg_t
*
cfg
=
vd
->
cfg
;
const
video_format_t
*
src
=
va_arg
(
ap
,
const
video_format_t
*
);
vout_display_place_t
place
;
vout_display_PlacePicture
(
&
place
,
src
,
cfg
,
false
);
glViewport
(
0
,
0
,
place
.
width
,
place
.
height
);
return
VLC_SUCCESS
;
}
case
VOUT_DISPLAY_GET_OPENGL
:
{
vlc_gl_t
**
gl
=
va_arg
(
ap
,
vlc_gl_t
**
);
}
*
gl
=
&
sys
->
gl
;
return
VLC_SUCCESS
;
}
static
void
SwapBuffers
(
vlc_gl_t
*
gl
)
{
vlc_gl_sys_t
*
sys
=
gl
->
sys
;
default:
msg_Err
(
vd
,
"Unknown request %d"
,
query
);
}
return
VLC_EGENERIC
;
eglSwapBuffers
(
sys
->
display
,
sys
->
surface
);
}
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