summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-08-18 22:00:40 +0200
committerwm4 <wm4@nowhere>2015-08-18 23:00:51 +0200
commitc36c596b7bc4700d05eaacdd229e8ebd3e312018 (patch)
treefb8a5be8b205d79aaf7b1832f47bfc7f027552df
parentda8a9ff5891cc55b6ea978f11761d3a30b64269c (diff)
downloadmpv-c36c596b7bc4700d05eaacdd229e8ebd3e312018.tar.bz2
mpv-c36c596b7bc4700d05eaacdd229e8ebd3e312018.tar.xz
rpi: factor out context creation
To be used by vo_rpi.c. No functional changes.
-rw-r--r--video/out/gl_rpi.c154
-rw-r--r--video/out/gl_rpi.h17
2 files changed, 108 insertions, 63 deletions
diff --git a/video/out/gl_rpi.c b/video/out/gl_rpi.c
index f82046e899..cdcf0584de 100644
--- a/video/out/gl_rpi.c
+++ b/video/out/gl_rpi.c
@@ -23,25 +23,11 @@
#include <stddef.h>
#include <assert.h>
-#include <bcm_host.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
#include "common/common.h"
#include "x11_common.h"
#include "gl_common.h"
-struct priv {
- EGLDisplay egl_display;
- EGLContext egl_context;
- EGLSurface egl_surface;
- DISPMANX_DISPLAY_HANDLE_T display;
- DISPMANX_ELEMENT_HANDLE_T window;
- DISPMANX_UPDATE_HANDLE_T update;
- // yep, the API keeps a pointer to it
- EGL_DISPMANX_WINDOW_T egl_window;
- int w, h;
-};
+#include "gl_rpi.h"
static void *get_proc_address(const GLubyte *name)
{
@@ -60,10 +46,8 @@ static void *get_proc_address(const GLubyte *name)
return p;
}
-static EGLConfig select_fb_config_egl(struct MPGLContext *ctx)
+static EGLConfig select_fb_config_egl(struct mp_egl_rpi *p)
{
- struct priv *p = ctx->priv;
-
EGLint attributes[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
@@ -80,19 +64,102 @@ static EGLConfig select_fb_config_egl(struct MPGLContext *ctx)
eglChooseConfig(p->egl_display, attributes, &config, 1, &config_count);
if (!config_count) {
- MP_FATAL(ctx->vo, "Could find EGL configuration!\n");
+ MP_FATAL(p, "Could find EGL configuration!\n");
return NULL;
}
return config;
}
+int mp_egl_rpi_init(struct mp_egl_rpi *p, DISPMANX_ELEMENT_HANDLE_T window,
+ int w, int h)
+{
+ p->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!eglInitialize(p->egl_display, NULL, NULL)) {
+ MP_FATAL(p, "EGL failed to initialize.\n");
+ goto fail;
+ }
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+
+ EGLConfig config = select_fb_config_egl(p);
+ if (!config)
+ goto fail;
+
+ p->egl_window = (EGL_DISPMANX_WINDOW_T){
+ .element = window,
+ .width = w,
+ .height = h,
+ };
+ p->egl_surface = eglCreateWindowSurface(p->egl_display, config,
+ &p->egl_window, NULL);
+
+ if (p->egl_surface == EGL_NO_SURFACE) {
+ MP_FATAL(p, "Could not create EGL surface!\n");
+ goto fail;
+ }
+
+ EGLint context_attributes[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ p->egl_context = eglCreateContext(p->egl_display, config,
+ EGL_NO_CONTEXT, context_attributes);
+
+ if (p->egl_context == EGL_NO_CONTEXT) {
+ MP_FATAL(p, "Could not create EGL context!\n");
+ goto fail;
+ }
+
+ eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface,
+ p->egl_context);
+
+ p->gl = talloc_zero(NULL, struct GL);
+
+ const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS);
+ mpgl_load_functions(p->gl, get_proc_address, exts, p->log);
+
+ if (!p->gl->version && !p->gl->es)
+ goto fail;
+
+ return 0;
+
+fail:
+ mp_egl_rpi_destroy(p);
+ return -1;
+}
+
+void mp_egl_rpi_destroy(struct mp_egl_rpi *p)
+{
+ if (p->egl_context) {
+ eglMakeCurrent(p->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ eglDestroyContext(p->egl_display, p->egl_context);
+ }
+ p->egl_context = EGL_NO_CONTEXT;
+ if (p->egl_display)
+ eglTerminate(p->egl_display);
+ p->egl_display = EGL_NO_DISPLAY;
+ talloc_free(p->gl);
+ p->gl = NULL;
+}
+
+struct priv {
+ DISPMANX_DISPLAY_HANDLE_T display;
+ DISPMANX_ELEMENT_HANDLE_T window;
+ DISPMANX_UPDATE_HANDLE_T update;
+ struct mp_egl_rpi egl;
+ int w, h;
+};
+
static bool sc_config_window(struct MPGLContext *ctx, int flags)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
- if (p->egl_context) {
+ p->egl.log = vo->log;
+
+ if (p->egl.gl) {
vo->dwidth = p->w;
vo->dheight = p->h;
return true;
@@ -130,43 +197,10 @@ static bool sc_config_window(struct MPGLContext *ctx, int flags)
vc_dispmanx_update_submit_sync(p->update);
- p->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (!eglInitialize(p->egl_display, NULL, NULL)) {
- MP_FATAL(ctx->vo, "EGL failed to initialize.\n");
- return false;
- }
-
- eglBindAPI(EGL_OPENGL_ES_API);
-
- EGLConfig config = select_fb_config_egl(ctx);
- if (!config)
+ if (mp_egl_rpi_init(&p->egl, p->window, w, h) < 0)
return false;
- p->egl_window = (EGL_DISPMANX_WINDOW_T){.element = p->window, .width = w, .height = h};
- p->egl_surface = eglCreateWindowSurface(p->egl_display, config, &p->egl_window, NULL);
-
- if (p->egl_surface == EGL_NO_SURFACE) {
- MP_FATAL(ctx->vo, "Could not create EGL surface!\n");
- return false;
- }
-
- EGLint context_attributes[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
- p->egl_context = eglCreateContext(p->egl_display, config,
- EGL_NO_CONTEXT, context_attributes);
-
- if (p->egl_context == EGL_NO_CONTEXT) {
- MP_FATAL(ctx->vo, "Could not create EGL context!\n");
- return false;
- }
-
- eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface,
- p->egl_context);
-
- const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS);
- mpgl_load_functions(ctx->gl, get_proc_address, exts, vo->log);
+ ctx->gl = p->egl.gl;
vo->dwidth = p->w = w;
vo->dheight = p->h = h;
@@ -177,20 +211,14 @@ static bool sc_config_window(struct MPGLContext *ctx, int flags)
static void sc_releaseGlContext(MPGLContext *ctx)
{
struct priv *p = ctx->priv;
- if (p->egl_context) {
- eglMakeCurrent(p->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- eglDestroyContext(p->egl_display, p->egl_context);
- }
- p->egl_context = EGL_NO_CONTEXT;
- eglTerminate(p->egl_display);
+ mp_egl_rpi_destroy(&p->egl);
vc_dispmanx_display_close(p->display);
}
static void sc_swapGlBuffers(MPGLContext *ctx)
{
struct priv *p = ctx->priv;
- eglSwapBuffers(p->egl_display, p->egl_surface);
+ eglSwapBuffers(p->egl.egl_display, p->egl.egl_surface);
}
static int sc_vo_init(struct vo *vo)
diff --git a/video/out/gl_rpi.h b/video/out/gl_rpi.h
new file mode 100644
index 0000000000..e00762b632
--- /dev/null
+++ b/video/out/gl_rpi.h
@@ -0,0 +1,17 @@
+#include <bcm_host.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+struct mp_egl_rpi {
+ struct mp_log *log;
+ struct GL *gl;
+ EGLDisplay egl_display;
+ EGLContext egl_context;
+ EGLSurface egl_surface;
+ // yep, the API keeps a pointer to it
+ EGL_DISPMANX_WINDOW_T egl_window;
+};
+
+int mp_egl_rpi_init(struct mp_egl_rpi *p, DISPMANX_ELEMENT_HANDLE_T window,
+ int w, int h);
+void mp_egl_rpi_destroy(struct mp_egl_rpi *p);