From 38886de0c3e9ea5729ef23e4c653fa2822f52e8f Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 6 Apr 2021 14:43:39 +0200 Subject: xscreensaver 6.00 --- hacks/glx/xlock-gl-utils.c | 158 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 5 deletions(-) (limited to 'hacks/glx/xlock-gl-utils.c') diff --git a/hacks/glx/xlock-gl-utils.c b/hacks/glx/xlock-gl-utils.c index 3e610a1..0d017b8 100644 --- a/hacks/glx/xlock-gl-utils.c +++ b/hacks/glx/xlock-gl-utils.c @@ -1,5 +1,5 @@ /* xlock-gl.c --- xscreensaver compatibility layer for xlockmore GL modules. - * xscreensaver, Copyright (c) 1997-2015 Jamie Zawinski + * xscreensaver, Copyright (c) 1997-2021 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -14,8 +14,10 @@ * By Jamie Zawinski on 31-May-97. */ -#include #include "xlockmoreI.h" + +#ifdef HAVE_GL /* whole file */ + #include "texfont.h" #ifndef isupper @@ -26,6 +28,7 @@ #endif +# ifndef HAVE_EGL /* Gag -- we use this to turn X errors from glXCreateContext() into something that will actually make sense to the user. */ @@ -43,11 +46,13 @@ BadValue_ehandler (Display *dpy, XErrorEvent *error) else return orig_ehandler (dpy, error); } +#endif /* !HAVE_EGL */ GLXContext * init_GL(ModeInfo * mi) { + /* The Android version of this function is in android/screenhack-android.c */ Display *dpy = mi->dpy; Window window = mi->window; Screen *screen = mi->xgwa.screen; @@ -61,7 +66,10 @@ init_GL(ModeInfo * mi) } # ifdef HAVE_JWZGLES - jwzgles_make_current(jwzgles_make_state(state)); + mi->jwzgles_state = jwzgles_make_state(); + mi->xlmft->jwzgles_make_current = jwzgles_make_current; + mi->xlmft->jwzgles_free = jwzgles_free_state; + mi->xlmft->jwzgles_make_current (mi->jwzgles_state); # endif vi_in.screen = screen_number (screen); @@ -70,6 +78,113 @@ init_GL(ModeInfo * mi) &vi_in, &out_count); if (! vi_out) abort (); +# ifdef HAVE_EGL + { + egl_data *d = (egl_data *) calloc (1, sizeof(*d)); + + /* The correct EGL config has been selected by utils/visual-gl.c + (via hacks/glx/xscreensaver-gl-visual) by calling get_egl_config() + from get_gl_visual and returning the corresponding X11 Visual. + That visual is the one that was used to create our window. We will + pass the corresponding visual ID to get_egl_config() to obtain the + same configuration here. */ + unsigned int vid = XVisualIDFromVisual (visual); + + const EGLint ctxattr1[] = { +# ifdef HAVE_JWZGLES + EGL_CONTEXT_MAJOR_VERSION, 1, /* Request an OpenGL ES 1.1 context. */ + EGL_CONTEXT_MINOR_VERSION, 1, +# else + EGL_CONTEXT_MAJOR_VERSION, 1, /* Request an OpenGL 1.3 context. */ + EGL_CONTEXT_MINOR_VERSION, 3, +# endif + EGL_NONE + }; + const EGLint *ctxattr = ctxattr1; + +# ifdef HAVE_GLES3 + const EGLint ctxattr3[] = { + EGL_CONTEXT_MAJOR_VERSION, 3, /* Request an OpenGL ES 3.0 context. */ + EGL_CONTEXT_MINOR_VERSION, 0, + EGL_NONE + }; + + if (get_boolean_resource (dpy, "prefersGLSL", "PrefersGLSL")) + ctxattr = ctxattr3; +# endif /* HAVE_GLES3 */ + + /* This is re-used, no need to close it. */ + d->egl_display = eglGetPlatformDisplay (EGL_PLATFORM_X11_KHR, + (EGLNativeDisplayType) dpy, NULL); + if (!d->egl_display) + { + fprintf (stderr, "%s: eglGetPlatformDisplay failed\n", progname); + abort(); + } + + get_egl_config (dpy, d->egl_display, vid, &d->egl_config); + if (!d->egl_config) + { + fprintf (stderr, "%s: no matching EGL config for X11 visual 0x%lx\n", + progname, vi_out->visualid); + abort(); + } + + d->egl_surface = eglCreatePlatformWindowSurface (d->egl_display, + d->egl_config, + &window, NULL); + if (! d->egl_surface) + { + fprintf (stderr, "%s: eglCreatePlatformWindowSurface failed:" + " window 0x%lx visual 0x%x\n", progname, window, vid); + abort(); + } + +#ifdef HAVE_JWZGLES + /* This call is not strictly necessary to get an OpenGL ES context + since the default API is EGL_OPENGL_ES_API, but it makes our + intention clear. + */ + if (!eglBindAPI (EGL_OPENGL_ES_API)) + { + fprintf (stderr, "%s: eglBindAPI failed\n", progname); + } +#else /* !HAVE_JWZGLES */ + /* This is necessary to get a OpenGL context instead of an OpenGLES + context. + */ + if (!eglBindAPI (EGL_OPENGL_API)) + { + fprintf (stderr, "%s: eglBindAPI failed\n", progname); + } +#endif /* !HAVE_JWZGLES */ + + d->egl_context = eglCreateContext (d->egl_display, d->egl_config, + EGL_NO_CONTEXT, ctxattr); + +# ifdef HAVE_GLES3 + /* If creation of a GLES 3.0 context failed, fall back to GLES 1.x. */ + if (!d->egl_context && ctxattr != ctxattr1) + { + /* fprintf (stderr, "%s: eglCreateContext 3.0 failed\n", progname); */ + d->egl_context = eglCreateContext (d->egl_display, d->egl_config, + EGL_NO_CONTEXT, ctxattr1); + } +# endif /* HAVE_GLES3 */ + + if (!d->egl_context) + { + fprintf (stderr, "%s: eglCreateContext failed\n", progname); + abort(); + } + + /* describe_gl_visual (stderr, screen, visual, False); */ + + mi->glx_context = d; /* #### leaked */ + + glXMakeCurrent (dpy, window, mi->glx_context); + } +# else /* GLX */ { XSync (dpy, False); orig_ehandler = XSetErrorHandler (BadValue_ehandler); @@ -80,8 +195,6 @@ init_GL(ModeInfo * mi) mi->glx_context = 0; } - XFree((char *) vi_out); - if (!mi->glx_context) { fprintf(stderr, "%s: couldn't create GL context for visual 0x%x.\n", @@ -100,6 +213,9 @@ init_GL(ModeInfo * mi) glClearIndex (BlackPixelOfScreen (screen)); } } +# endif /* GLX */ + + XFree((char *) vi_out); /* jwz: the doc for glDrawBuffer says "The initial value is GL_FRONT @@ -229,3 +345,35 @@ xlockmore_validate_gl_visual (Screen *screen, const char *name, Visual *visual) { return validate_gl_visual (stderr, screen, name, visual); } + + +#ifdef HAVE_EGL + +static egl_data *global_egl_kludge = 0; + +Bool +glXMakeCurrent (Display *dpy, GLXDrawable window, egl_data *d) +{ + if (!d) abort(); + if (! eglMakeCurrent (d->egl_display, d->egl_surface, d->egl_surface, + d->egl_context)) + abort(); + + global_egl_kludge = d; + + return True; +} + +void +glXSwapBuffers (Display *dpy, GLXDrawable win) +{ + egl_data *d = global_egl_kludge; + if (!d) abort(); + if (! eglSwapBuffers (d->egl_display, d->egl_surface)) + abort(); +} + +#endif /* HAVE_EGL */ + + +#endif /* HAVE_GL -- whole file */ -- cgit v1.2.3-55-g7522