Skip to content

Commit e6d5888

Browse files
committed
EGL port.
1 parent 8e521a8 commit e6d5888

2 files changed

Lines changed: 95 additions & 121 deletions

File tree

code/bin/4ed_build.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha
311311

312312
# define GCC_LIBS_COMMON \
313313
"-lX11 -lpthread -lm -lrt " \
314-
"-lGL -ldl -lXfixes -lfreetype -lfontconfig"
314+
"-lEGL -lGL -ldl -lXfixes -lfreetype -lfontconfig"
315315

316316
# define GCC_LIBS_X64 GCC_LIBS_COMMON
317317
# define GCC_LIBS_X86 GCC_LIBS_COMMON

code/platform_linux/linux_4ed.cpp

Lines changed: 94 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@
9999
//#include <fontconfig/fontconfig.h>
100100
#define internal static
101101

102-
#include <GL/glx.h>
103-
#include <GL/glext.h>
102+
#include <EGL/egl.h>
103+
#include <EGL/eglext.h>
104104

105105
#ifdef INSO_DEBUG
106106
#define LINUX_FN_DEBUG(fmt, ...) do { \
@@ -159,6 +159,11 @@ struct Linux_Vars {
159159
Thread_Context tctx;
160160
Arena frame_arena;
161161

162+
EGLDisplay egl_display;
163+
EGLSurface egl_surface;
164+
EGLContext egl_context;
165+
EGLConfig egl_config;
166+
162167
Display* dpy;
163168
Window win;
164169

@@ -622,123 +627,99 @@ font_make_face(Arena* arena, Face_Description* description, f32 scale_factor) {
622627
////////////////////////////
623628

624629
internal b32
625-
glx_init(void) {
626-
int glx_maj, glx_min;
627-
628-
if(!glXQueryVersion(linuxvars.dpy, &glx_maj, &glx_min)) {
629-
return false;
630+
egl_init(void) {
631+
linuxvars.egl_display = eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, linuxvars.dpy, 0);
632+
if(linuxvars.egl_display)
633+
{
634+
int egl_maj, egl_min;
635+
if(eglInitialize(linuxvars.egl_display, &egl_maj, &egl_min) &&
636+
((egl_maj > 1) || ((egl_maj == 1) && (egl_min >= 5))))
637+
{
638+
return eglBindAPI(EGL_OPENGL_API);
639+
}
630640
}
631641

632-
return glx_maj > 1 || (glx_maj == 1 && glx_min >= 3);
642+
return false;
633643
}
634644

635645
internal b32
636-
glx_get_config(GLXFBConfig* fb_config, XVisualInfo* vi) {
637-
638-
static const int attrs[] = {
639-
GLX_X_RENDERABLE , True,
640-
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
641-
GLX_RENDER_TYPE , GLX_RGBA_BIT,
642-
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
643-
GLX_RED_SIZE , 8,
644-
GLX_GREEN_SIZE , 8,
645-
GLX_BLUE_SIZE , 8,
646-
GLX_ALPHA_SIZE , 8,
647-
GLX_DEPTH_SIZE , 24,
648-
GLX_STENCIL_SIZE , 8,
649-
GLX_DOUBLEBUFFER , True,
650-
None
651-
};
652-
653-
int conf_count = 0;
654-
GLXFBConfig* conf_list = glXChooseFBConfig(linuxvars.dpy, DefaultScreen(linuxvars.dpy), attrs, &conf_count);
655-
if(!conf_count || conf_count <= 0) {
656-
return false;
657-
}
658-
659-
*fb_config = *conf_list;
660-
XFree(conf_list);
661-
662-
XVisualInfo* xvi = glXGetVisualFromFBConfig(linuxvars.dpy, *fb_config);
663-
if(!xvi) {
664-
return false;
665-
}
666-
667-
*vi = *xvi;
668-
XFree(xvi);
669-
670-
return true;
671-
}
672-
673-
internal b32 glx_ctx_error;
674-
675-
internal int
676-
glx_error_handler(Display* dpy, XErrorEvent* ev){
677-
glx_ctx_error = true;
678-
return 0;
679-
}
680-
681-
typedef GLXContext (glXCreateContextAttribsARB_Function)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
682-
typedef void (glXSwapIntervalEXT_Function) (Display *dpy, GLXDrawable drawable, int interval);
683-
typedef int (glXSwapIntervalMESA_Function) (unsigned int interval);
684-
typedef int (glXGetSwapIntervalMESA_Function) (void);
685-
typedef int (glXSwapIntervalSGI_Function) (int interval);
686-
687-
internal b32
688-
glx_create_context(GLXFBConfig fb_config){
689-
const char *glx_exts = glXQueryExtensionsString(linuxvars.dpy, DefaultScreen(linuxvars.dpy));
690-
691-
glXCreateContextAttribsARB_Function *glXCreateContextAttribsARB = 0;
692-
glXSwapIntervalEXT_Function *glXSwapIntervalEXT = 0;
693-
glXSwapIntervalMESA_Function *glXSwapIntervalMESA = 0;
694-
glXGetSwapIntervalMESA_Function *glXGetSwapIntervalMESA = 0;
695-
glXSwapIntervalSGI_Function *glXSwapIntervalSGI = 0;
646+
egl_create_context(void){
647+
Scratch_Block scratch(&linuxvars.tctx);
696648

697-
#define GLXLOAD(f) f = (f##_Function*) glXGetProcAddressARB((const GLubyte*) #f);
698-
GLXLOAD(glXCreateContextAttribsARB);
649+
EGLint config_attributes[] =
650+
{
651+
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
652+
EGL_CONFORMANT, EGL_OPENGL_BIT,
653+
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
654+
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
655+
656+
EGL_RED_SIZE, 8,
657+
EGL_GREEN_SIZE, 8,
658+
EGL_BLUE_SIZE, 8,
659+
EGL_ALPHA_SIZE, 8,
660+
661+
EGL_DEPTH_SIZE, 24,
662+
EGL_STENCIL_SIZE, 8,
663+
664+
EGL_NONE,
665+
};
699666

700-
GLXContext ctx = NULL;
701-
int (*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(&glx_error_handler);
667+
EGLAttrib surface_attributes[] =
668+
{
669+
// TODO(maria): decide if we want an sRGB capable surface;
670+
//EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB,
671+
EGL_NONE,
672+
};
702673

703-
if (glXCreateContextAttribsARB == NULL){
704-
//LOG("glXCreateContextAttribsARB() not found, using old-style GLX context\n" );
705-
ctx = glXCreateNewContext(linuxvars.dpy, fb_config, GLX_RGBA_TYPE, 0, True);
706-
} else {
707-
static const int context_attribs[] = {
708-
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
709-
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
710-
GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
674+
EGLint context_attributes[] =
675+
{
676+
EGL_CONTEXT_MAJOR_VERSION, 3,
677+
EGL_CONTEXT_MINOR_VERSION, 2,
678+
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
711679
#if GL_DEBUG_MODE
712-
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_DEBUG_BIT_ARB,
680+
EGL_CONTEXT_OPENGL_DEBUG, EGL_TRUE,
713681
#endif
714-
None
715-
};
716-
717-
ctx = glXCreateContextAttribsARB(linuxvars.dpy, fb_config, 0, True, context_attribs);
718-
}
719-
720-
XSync(linuxvars.dpy, False);
721-
if(glx_ctx_error || !ctx) {
722-
return false;
723-
}
724-
725-
XSync(linuxvars.dpy, False);
726-
XSetErrorHandler(old_handler);
727-
728-
//b32 direct = glXIsDirect(linuxvars.dpy, ctx);
729-
730-
//LOG("Making context current\n");
731-
glXMakeCurrent(linuxvars.dpy, linuxvars.win, ctx);
732-
733-
//glx_enable_vsync();
682+
EGL_NONE,
683+
};
734684

735-
// NOTE(allen): Load gl functions
736-
#define GL_FUNC(f,R,P) GLXLOAD(f)
685+
EGLint config_count = 0;
686+
if(eglChooseConfig(linuxvars.egl_display, config_attributes, 0, 0, &config_count) &&
687+
(config_count > 0))
688+
{
689+
EGLConfig *configs = push_array(scratch, EGLConfig, config_count);
690+
if(eglChooseConfig(linuxvars.egl_display, config_attributes, configs, config_count, &config_count) &&
691+
(config_count > 0))
692+
{
693+
for(i32 config_index = 0;
694+
config_index < config_count;
695+
++config_index)
696+
{
697+
EGLConfig test_config = configs[config_index];
698+
EGLSurface test_surface = eglCreatePlatformWindowSurface(linuxvars.egl_display, test_config, &linuxvars.win, surface_attributes);
699+
if(test_surface)
700+
{
701+
linuxvars.egl_config = test_config;
702+
linuxvars.egl_surface = test_surface;
703+
break;
704+
}
705+
}
706+
707+
if(linuxvars.egl_surface)
708+
{
709+
linuxvars.egl_context = eglCreateContext(linuxvars.egl_display, linuxvars.egl_config, EGL_NO_CONTEXT, context_attributes);
710+
if(linuxvars.egl_context && eglMakeCurrent(linuxvars.egl_display, linuxvars.egl_surface, linuxvars.egl_surface, linuxvars.egl_context))
711+
{
712+
// NOTE(allen): Load gl functions
713+
#define GL_FUNC(f,R,P) f = (f##_Function*)eglGetProcAddress(#f);
737714
#include "opengl/4ed_opengl_funcs.h"
715+
#undef GL_FUNC
716+
return true;
717+
}
718+
}
719+
}
720+
}
738721

739-
#undef GLXLOAD
740-
741-
return true;
722+
return false;
742723
}
743724

744725
////////////////////////////
@@ -771,14 +752,8 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
771752

772753
#undef LOAD_ATOM
773754

774-
if (!glx_init()){
775-
system_error_box("Your XServer's GLX version is too old. GLX 1.3+ is required.");
776-
}
777-
778-
GLXFBConfig fb_config;
779-
XVisualInfo vi;
780-
if (!glx_get_config(&fb_config, &vi)){
781-
system_error_box("Could not get a matching GLX FBConfig. Check your OpenGL drivers are installed correctly.");
755+
if (!egl_init()){
756+
system_error_box("Your EGL version is too old. EGL 1.5+ is required.");
782757
}
783758

784759
// TODO: window size
@@ -795,10 +770,9 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
795770
swa.backing_store = WhenMapped;
796771
swa.event_mask = StructureNotifyMask;
797772
swa.bit_gravity = NorthWestGravity;
798-
swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi.screen), vi.visual, AllocNone);
799773

800-
u32 CWflags = CWBackingStore|CWBitGravity|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask;
801-
linuxvars.win = XCreateWindow(dpy, RootWindow(dpy, vi.screen), 0, 0, w, h, 0, vi.depth, InputOutput, vi.visual, CWflags, &swa);
774+
u32 CWflags = CWBackingStore|CWBitGravity|CWBackPixel|CWBorderPixel|CWEventMask;
775+
linuxvars.win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, CWflags, &swa);
802776

803777
if (!linuxvars.win){
804778
system_error_box("XCreateWindow failed. Make sure your display is set up correctly.");
@@ -855,8 +829,8 @@ linux_x11_init(int argc, char** argv, Plat_Settings* settings) {
855829
// NOTE(inso): make the window visible
856830
XMapWindow(linuxvars.dpy, linuxvars.win);
857831

858-
if(!glx_create_context(fb_config)) {
859-
system_error_box("Unable to create GLX context.");
832+
if(!egl_create_context()) {
833+
system_error_box("Unable to create EGL context.");
860834
}
861835

862836
XRaiseWindow(linuxvars.dpy, linuxvars.win);
@@ -2019,7 +1993,7 @@ main(int argc, char **argv){
20191993
}
20201994

20211995
gl_render(&render_target);
2022-
glXSwapBuffers(linuxvars.dpy, linuxvars.win);
1996+
eglSwapBuffers(linuxvars.egl_display, linuxvars.egl_surface);
20231997

20241998
// TODO(allen): don't let the screen size change until HERE after the render
20251999

0 commit comments

Comments
 (0)