diff --git a/src/render/opengl/linux/egl/render_opengl_linux_egl.c b/src/render/opengl/linux/egl/render_opengl_linux_egl.c index 43e4d541..dc87a62c 100644 --- a/src/render/opengl/linux/egl/render_opengl_linux_egl.c +++ b/src/render/opengl/linux/egl/render_opengl_linux_egl.c @@ -51,7 +51,63 @@ r_ogl_os_init(CmdLine *cmdln) wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't initialize EGL API to OpenGL.")); abort_self(1); } - + + //- choose EGL config, extract matching X11 visual/colormap, publish to os layer + { + EGLint config_filter[] = + { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT, + EGL_CONFORMANT, EGL_OPENGL_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_NONE, + }; + EGLConfig configs[256] = {0}; + EGLint configs_count = 0; + if(!eglChooseConfig(r_ogl_lnx_state->display, config_filter, configs, ArrayCount(configs), &configs_count) || configs_count == 0) + { + wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration.")); + abort_self(1); + } + int screen = DefaultScreen(lnx_wm_state->display); + XVisualInfo vi_template = {0}; + XVisualInfo *vi = 0; + int vi_count = 0; + for(EGLint idx = 0; idx < configs_count && vi == 0; idx += 1) + { + EGLint native_visual_id = 0; + if(!eglGetConfigAttrib(r_ogl_lnx_state->display, configs[idx], EGL_NATIVE_VISUAL_ID, &native_visual_id) || native_visual_id == 0) + { + continue; + } + vi_template.visualid = native_visual_id; + vi_template.screen = screen; + vi = XGetVisualInfo(lnx_wm_state->display, VisualIDMask|VisualScreenMask, &vi_template, &vi_count); + if(vi != 0 && vi_count > 0) + { + r_ogl_lnx_state->config = configs[idx]; + break; + } + if(vi != 0) { XFree(vi); vi = 0; } + } + if(vi == 0 || r_ogl_lnx_state->config == 0) + { + wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't find an EGL config with a matching X11 visual.")); + abort_self(1); + } + lnx_wm_state->window_visual = vi->visual; + lnx_wm_state->window_depth = vi->depth; + lnx_wm_state->window_colormap = XCreateColormap(lnx_wm_state->display, + XRootWindow(lnx_wm_state->display, vi->screen), + vi->visual, AllocNone); + XFree(vi); + } + //- rjf: construct context { B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); @@ -66,16 +122,23 @@ r_ogl_os_init(CmdLine *cmdln) debug_mode ? EGL_CONTEXT_OPENGL_DEBUG : EGL_NONE, EGL_TRUE, EGL_NONE, }; - r_ogl_lnx_state->context = eglCreateContext(r_ogl_lnx_state->display, 0, EGL_NO_CONTEXT, options); + r_ogl_lnx_state->context = eglCreateContext(r_ogl_lnx_state->display, r_ogl_lnx_state->config, EGL_NO_CONTEXT, options); if(r_ogl_lnx_state->context == EGL_NO_CONTEXT) { wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't create OpenGL context with EGL.")); abort_self(1); } } - - eglMakeCurrent(r_ogl_lnx_state->display, 0, 0, r_ogl_lnx_state->context); - glDrawBuffer(GL_BACK); + + //- bind context to 1x1 pbuffer so GL calls work before any window exists + { + EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; + EGLSurface init_surface = eglCreatePbufferSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, pbuffer_attribs); + if(init_surface == EGL_NO_SURFACE || !eglMakeCurrent(r_ogl_lnx_state->display, init_surface, init_surface, r_ogl_lnx_state->context)) + { + eglMakeCurrent(r_ogl_lnx_state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, r_ogl_lnx_state->context); + } + } } internal R_Handle @@ -97,60 +160,11 @@ r_ogl_os_window_equip(WM_Window window) EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, EGL_NONE, }; - if(r_ogl_lnx_state->config == 0) + w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, surface_options); + if(w->surface == EGL_NO_SURFACE) { - //- rjf: get all EGL configs - EGLConfig configs[256] = {0}; - EGLint configs_count = 0; - { - EGLint options[] = - { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_CONFORMANT, EGL_OPENGL_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, - - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_DEPTH_SIZE, 24, - EGL_STENCIL_SIZE, 8, - - EGL_NONE, - }; - if(!eglChooseConfig(r_ogl_lnx_state->display, options, configs, ArrayCount(configs), &configs_count) || configs_count == 0) - { - wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration.")); - abort_self(1); - } - } - - //- rjf: actually choose the egl config - { - EGLint config_options[] = - { - EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, - EGL_NONE, - }; - for(U32 idx = 0; idx < configs_count; idx += 1) - { - w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, configs[idx], window_os->window, config_options); - if(w->surface != EGL_NO_SURFACE) - { - r_ogl_lnx_state->config = configs[idx]; - break; - } - } - if(r_ogl_lnx_state->config == 0) - { - wm_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't find a suitable EGL configuration.")); - abort_self(1); - } - } - } - else - { - w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, surface_options); + EGLint surface_options_linear[] = { EGL_NONE }; + w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, surface_options_linear); } if(w->surface == EGL_NO_SURFACE) { diff --git a/src/render/opengl/linux/egl/render_opengl_linux_egl.h b/src/render/opengl/linux/egl/render_opengl_linux_egl.h index 77d687d7..27a0ba88 100644 --- a/src/render/opengl/linux/egl/render_opengl_linux_egl.h +++ b/src/render/opengl/linux/egl/render_opengl_linux_egl.h @@ -7,6 +7,7 @@ #define glTexImage3D glTexImage3D__static #define glTexSubImage3D glTexSubImage3D__static #define glActiveTexture glActiveTexture__static +#include #include #include #undef glTexImage3D