From c36c596b7bc4700d05eaacdd229e8ebd3e312018 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Aug 2015 22:00:40 +0200 Subject: rpi: factor out context creation To be used by vo_rpi.c. No functional changes. --- video/out/gl_rpi.c | 154 +++++++++++++++++++++++++++++++---------------------- video/out/gl_rpi.h | 17 ++++++ 2 files changed, 108 insertions(+), 63 deletions(-) create mode 100644 video/out/gl_rpi.h 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 #include -#include -#include -#include - #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 +#include +#include + +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); -- cgit v1.2.3