/** * Probe EGL display availability */ static int Open (vlc_object_t *obj, const struct gl_api *api) { vlc_gl_t *gl = (vlc_gl_t *)obj; vlc_gl_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; gl->sys = sys; sys->display = EGL_NO_DISPLAY; sys->surface = EGL_NO_SURFACE; vout_window_t *wnd = gl->surface; EGLSurface (*createSurface)(EGLDisplay, EGLConfig, void *, const EGLint *) = CreateWindowSurface; void *window; #ifdef USE_PLATFORM_X11 sys->x11 = NULL; if (wnd->type != VOUT_WINDOW_TYPE_XID || !vlc_xlib_init(obj)) goto error; window = &wnd->handle.xid; sys->x11 = XOpenDisplay(wnd->display.x11); if (sys->x11 == NULL) goto error; int snum; { XWindowAttributes wa; if (!XGetWindowAttributes(sys->x11, wnd->handle.xid, &wa)) goto error; snum = XScreenNumberOfScreen(wa.screen); } # ifdef EGL_EXT_platform_x11 if (CheckClientExt("EGL_EXT_platform_x11")) { const EGLint attrs[] = { EGL_PLATFORM_X11_SCREEN_EXT, snum, EGL_NONE }; sys->display = GetDisplayEXT(EGL_PLATFORM_X11_EXT, sys->x11, attrs); createSurface = CreateWindowSurfaceEXT; } else # endif { # ifdef __unix__ if (snum == XDefaultScreen(sys->x11)) sys->display = eglGetDisplay(sys->x11); } # endif #elif defined (USE_PLATFORM_WAYLAND) sys->window = NULL; if (wnd->type != VOUT_WINDOW_TYPE_WAYLAND) goto error; # ifdef EGL_EXT_platform_wayland if (!CheckClientExt("EGL_EXT_platform_wayland")) goto error; /* Resize() should be called with the proper size before Swap() */ window = wl_egl_window_create(wnd->handle.wl, 1, 1); if (window == NULL) goto error; sys->window = window; sys->display = GetDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, wnd->display.wl, NULL); createSurface = CreateWindowSurfaceEXT; # endif #elif defined (USE_PLATFORM_WIN32) if (wnd->type != VOUT_WINDOW_TYPE_HWND) goto error; window = &wnd->handle.hwnd; # if defined (_WIN32) || defined (__VC32__) \ && !defined (__CYGWIN__) && !defined (__SCITECH_SNAP__) sys->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); # endif #elif defined (USE_PLATFORM_ANDROID) if (wnd->type != VOUT_WINDOW_TYPE_ANDROID_NATIVE) goto error; window = &wnd->handle.anativewindow; # if defined (__ANDROID__) || defined (ANDROID) sys->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); # endif #endif if (sys->display == EGL_NO_DISPLAY) goto error; /* Initialize EGL display */ EGLint major, minor; if (eglInitialize(sys->display, &major, &minor) != EGL_TRUE) goto error; msg_Dbg(obj, "EGL version %s by %s", eglQueryString(sys->display, EGL_VERSION), eglQueryString(sys->display, EGL_VENDOR)); const char *ext = eglQueryString(sys->display, EGL_EXTENSIONS); if (*ext) msg_Dbg(obj, " extensions: %s", ext); if (major != 1 || minor < api->min_minor || !CheckAPI(sys->display, api->name)) { msg_Err(obj, "cannot select %s API", api->name); goto error; } const EGLint conf_attr[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 5, EGL_BLUE_SIZE, 5, EGL_RENDERABLE_TYPE, api->render_bit, EGL_NONE }; EGLConfig cfgv[1]; EGLint cfgc; if (eglChooseConfig(sys->display, conf_attr, cfgv, 1, &cfgc) != EGL_TRUE || cfgc == 0) { msg_Err (obj, "cannot choose EGL configuration"); goto error; } /* Create a drawing surface */ sys->surface = createSurface(sys->display, cfgv[0], window, NULL); if (sys->surface == EGL_NO_SURFACE) { msg_Err (obj, "cannot create EGL window surface"); goto error; } if (eglBindAPI (api->api) != EGL_TRUE) { msg_Err (obj, "cannot bind EGL API"); goto error; } EGLContext ctx = eglCreateContext(sys->display, cfgv[0], EGL_NO_CONTEXT, api->attr); if (ctx == EGL_NO_CONTEXT) { msg_Err (obj, "cannot create EGL context"); goto error; } sys->context = ctx; /* Initialize OpenGL callbacks */ gl->makeCurrent = MakeCurrent; gl->releaseCurrent = ReleaseCurrent; gl->resize = Resize; gl->swap = SwapBuffers; gl->getProcAddress = GetSymbol; return VLC_SUCCESS; error: Close (obj); return VLC_EGENERIC; }
/** * Probe EGL display availability */ static int Open (vlc_object_t *obj, const struct gl_api *api) { vlc_gl_t *gl = (vlc_gl_t *)obj; /* <EGL/eglplatform.h> defines the list and order of platforms */ #if defined(_WIN32) || defined(__VC32__) \ && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) # define vlc_eglGetWindow(w) ((w)->handle.hwnd) #elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ # error Symbian EGL not supported. #elif defined(WL_EGL_PLATFORM) # error Wayland EGL not supported. #elif defined(__GBM__) # error Glamor EGL not supported. #elif defined(ANDROID) # error Android EGL not supported #elif defined(__unix__) /* X11 */ # define vlc_eglGetWindow(w) ((w)->handle.xid) /* 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; #else # error EGL platform not recognized. #endif /* Initialize EGL display */ /* TODO: support various display types */ EGLDisplay dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY); if (dpy == EGL_NO_DISPLAY) return VLC_EGENERIC; vlc_gl_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; gl->sys = sys; sys->display = dpy; EGLint major, minor; if (eglInitialize (dpy, &major, &minor) != EGL_TRUE) { /* No need to call eglTerminate() in this case */ free (sys); return VLC_EGENERIC; } 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)); { const char *ext = eglQueryString (dpy, EGL_EXTENSIONS); if (*ext) msg_Dbg (obj, " extensions: %s", ext); } const EGLint conf_attr[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 5, EGL_BLUE_SIZE, 5, EGL_RENDERABLE_TYPE, api->render_bit, EGL_NONE }; EGLConfig cfgv[1]; EGLint cfgc; if (eglChooseConfig (dpy, conf_attr, cfgv, 1, &cfgc) != EGL_TRUE || cfgc == 0) goto error; /* Create a drawing surface */ EGLNativeWindowType win = vlc_eglGetWindow(gl->surface); EGLSurface surface = eglCreateWindowSurface (dpy, cfgv[0], win, NULL); if (surface == EGL_NO_SURFACE) { msg_Err (obj, "cannot create EGL window surface"); goto error; } sys->surface = surface; if (eglBindAPI (api->api) != EGL_TRUE) { msg_Err (obj, "cannot bind EGL API"); goto error; } EGLContext ctx = eglCreateContext (dpy, cfgv[0], EGL_NO_CONTEXT, api->attr); if (ctx == EGL_NO_CONTEXT) { msg_Err (obj, "cannot create EGL context"); goto error; } sys->context = ctx; /* Initialize OpenGL callbacks */ gl->sys = sys; gl->makeCurrent = MakeCurrent; gl->swap = SwapBuffers; gl->getProcAddress = GetSymbol; gl->lock = NULL; gl->unlock = NULL; return VLC_SUCCESS; error: Close (obj); return VLC_EGENERIC; }
/** * Probe EGL display availability */ 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 /* Initialize EGL display */ /* TODO: support various display types */ EGLDisplay dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY); if (dpy == EGL_NO_DISPLAY) return VLC_EGENERIC; vlc_gl_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; gl->sys = sys; sys->display = dpy; EGLint major, minor; if (eglInitialize (dpy, &major, &minor) != EGL_TRUE) { /* No need to call eglTerminate() in this case */ free (sys); return VLC_EGENERIC; } 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)); { const char *ext = eglQueryString (dpy, EGL_EXTENSIONS); if (*ext) msg_Dbg (obj, " extensions: %s", ext); } const EGLint conf_attr[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 5, EGL_BLUE_SIZE, 5, EGL_RENDERABLE_TYPE, api->render_bit, EGL_NONE }; EGLConfig cfgv[1]; EGLint cfgc; if (eglChooseConfig (dpy, conf_attr, cfgv, 1, &cfgc) != EGL_TRUE || cfgc == 0) goto error; /* Create a drawing surface */ #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) { msg_Err (obj, "cannot create EGL window surface"); goto error; } sys->surface = surface; if (eglBindAPI (api->api) != EGL_TRUE) { msg_Err (obj, "cannot bind EGL API"); goto error; } EGLContext ctx = eglCreateContext (dpy, cfgv[0], EGL_NO_CONTEXT, api->attr); if (ctx == EGL_NO_CONTEXT) { msg_Err (obj, "cannot create EGL context"); goto error; } sys->context = ctx; /* Initialize OpenGL callbacks */ gl->sys = sys; gl->makeCurrent = MakeCurrent; gl->swap = SwapBuffers; gl->lock = NULL; gl->unlock = NULL; return VLC_SUCCESS; error: Close (obj); return VLC_EGENERIC; }