WOO EGL context!

wayland
Patrick Cleavelin 2024-04-19 00:30:12 -05:00
parent 6119d34559
commit 2942efe6e2
3 changed files with 115 additions and 14 deletions

View File

@ -4,7 +4,7 @@ alias r := run
c_flags := if os() == "macos" {
"$(curl-config --libs) -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC"
} else if os_family() == "unix" {
"$(curl-config --libs) -lEGL -lGLESv2 -lGL -lm -lwayland-client -lX11 -lXi -lXcursor"
"$(curl-config --libs) -lEGL -lGLESv2 -lGL -lm -lwayland-client -lwayland-egl -lX11 -lXi -lXcursor"
} else { "" }
[macos]
@ -18,8 +18,8 @@ build: generate_wayland_protocols
cc -Ivendor/ -O0 -g -Wall -Wextra {{ c_flags }} src/*.c src/wayland-crap/*.c -o bin/chat_client
run: build
# nixGLIntel ./bin/chat_client
./bin/chat_client
nixGLIntel ./bin/chat_client
# ./bin/chat_client
[linux]
generate_wayland_protocols:

118
src/gfx.h
View File

@ -77,11 +77,13 @@ typedef struct {
#elif __linux__
#include "wayland-crap/xdg-shell.h"
#include <EGL/egl.h>
#include <GL/gl.h>
#include <X11/Xlib.h>
#include <sys/mman.h>
#include <syscall.h>
#include <unistd.h>
#include <wayland-client.h>
#include <wayland-egl.h>
// And I thought MacOS needed a lot of state to create a window
typedef struct {
@ -98,6 +100,12 @@ typedef struct {
struct wl_seat *seat;
struct wl_pointer *pointer;
EGLDisplay egl_display;
EGLConfig egl_config;
EGLSurface egl_surface;
EGLContext egl_context;
struct wl_egl_window *egl_window;
int mouse_x, mouse_y;
int mouse_left_down, mouse_right_down;
} _opengl_gfx_context_wayland;
@ -740,33 +748,39 @@ _opengl_gfx_init_context_wayland(uint32_t width, uint32_t height) {
// wait for all the globals to be registered
wl_display_roundtrip(cx.display);
xdg_wm_base_add_listener(cx.wm_base, &xdg_wm_base_listener, &cx);
xdg_wm_base_add_listener(cx.wm_base, &xdg_wm_base_listener,
&_gfx_context.backend);
cx.pointer = wl_seat_get_pointer(cx.seat);
wl_pointer_add_listener(cx.pointer, &pointer_listener, &cx);
wl_pointer_add_listener(cx.pointer, &pointer_listener,
&_gfx_context.backend);
cx.surface = wl_compositor_create_surface(cx.compositor);
cx.xdg_surface = xdg_wm_base_get_xdg_surface(cx.wm_base, cx.surface);
xdg_surface_add_listener(cx.xdg_surface, &xdg_surface_listener, &cx);
xdg_surface_add_listener(cx.xdg_surface, &xdg_surface_listener,
&_gfx_context.backend);
cx.xdg_toplevel = xdg_surface_get_toplevel(cx.xdg_surface);
xdg_toplevel_add_listener(cx.xdg_toplevel, &xdg_toplevel_listener, &cx);
xdg_toplevel_add_listener(cx.xdg_toplevel, &xdg_toplevel_listener,
&_gfx_context.backend);
xdg_toplevel_set_title(cx.xdg_toplevel, "chat - [Slack sux]");
xdg_toplevel_set_app_id(cx.xdg_toplevel, "nl.spacegirl.a_chat_client");
wl_surface_commit(cx.surface);
wl_display_roundtrip(cx.display);
int size = width * height * 4;
int buffer_size = width * height * 4;
int fd = syscall(SYS_memfd_create, "buffer", 0);
ftruncate(fd, size);
ftruncate(fd, buffer_size);
uint8_t *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
for (int i = 0; i < size; ++i) {
uint8_t *data =
mmap(NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
for (int i = 0; i < buffer_size; ++i) {
data[i] = 255;
}
cx.shared_memory_pool = wl_shm_create_pool(cx.shared_memory, fd, size);
cx.shared_memory_pool =
wl_shm_create_pool(cx.shared_memory, fd, buffer_size);
cx.buffer =
wl_shm_pool_create_buffer(cx.shared_memory_pool, 0, width, height,
width * 4, WL_SHM_FORMAT_ARGB8888);
@ -774,6 +788,86 @@ _opengl_gfx_init_context_wayland(uint32_t width, uint32_t height) {
wl_surface_attach(cx.surface, cx.buffer, 0, 0);
wl_surface_commit(cx.surface);
/* Init EGL */
EGLint major, minor, count, n, size;
EGLConfig *configs;
EGLint config_attribs[] = {
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
//
EGL_RED_SIZE,
8,
//
EGL_BLUE_SIZE,
8,
//
EGL_GREEN_SIZE,
8,
//
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
//
EGL_NONE,
};
static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE};
cx.egl_display = eglGetDisplay((EGLNativeDisplayType)cx.display);
if (cx.egl_display == EGL_NO_DISPLAY) {
fprintf(stderr, "Failed to create EGL display\n");
exit(1);
}
fprintf(stderr, "Created EGL display\n");
if (eglInitialize(cx.egl_display, &major, &minor) != EGL_TRUE) {
fprintf(stderr, "Failed to initialize EGL display\n");
exit(1);
}
fprintf(stderr, "EGL major: %d, minor: %d\n", major, minor);
eglGetConfigs(cx.egl_display, NULL, 0, &count);
configs = calloc(count, sizeof(EGLConfig));
eglChooseConfig(cx.egl_display, config_attribs, configs, count, &n);
for (int i = 0; i < n; ++i) {
eglGetConfigAttrib(cx.egl_display, configs[i], EGL_BUFFER_SIZE, &size);
fprintf(stderr, "EGL Buffer size: %d\n", size);
eglGetConfigAttrib(cx.egl_display, configs[i], EGL_RED_SIZE, &size);
fprintf(stderr, "EGL Red size: %d\n", size);
cx.egl_config = configs[i];
break;
}
cx.egl_context = eglCreateContext(cx.egl_display, cx.egl_config,
EGL_NO_CONTEXT, context_attribs);
cx.egl_window = wl_egl_window_create(cx.surface, width, height);
if (cx.egl_window == EGL_NO_SURFACE) {
fprintf(stderr, "Failed to create EGL window\n");
exit(1);
}
fprintf(stderr, "Created EGL window\n");
cx.egl_surface = eglCreateWindowSurface(cx.egl_display, cx.egl_config,
cx.egl_window, NULL);
if (eglMakeCurrent(cx.egl_display, cx.egl_surface, cx.egl_surface,
cx.egl_context) != EGL_TRUE) {
fprintf(stderr, "eglMakeCurrent() failed\n");
}
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
if (eglSwapBuffers(cx.egl_display, cx.egl_surface) != EGL_TRUE) {
fprintf(stderr, "eglSwapBuffers() failed\n");
}
/* ******** */
return cx;
}
@ -803,6 +897,12 @@ static _opengl_gfx_context_x11 _opengl_gfx_init_context_11(uint32_t width,
static void _opengl_gfx_send_events_wayland(_opengl_gfx_context_wayland *cx) {
wl_display_dispatch(cx->display);
// TODO: move this to present()
_gfx_context.gpu_glyphs.size = 0;
_gfx_context.gpu_ui_rects.size = 0;
_gfx_context.frame_func(cx->mouse_x, cx->mouse_y, cx->mouse_left_down,
cx->mouse_right_down);
}
static void _opengl_gfx_send_events_x11(_opengl_gfx_context_x11 *cx) {

View File

@ -203,8 +203,9 @@ void ed_frame(int mouse_x, int mouse_y, bool mouse_left_down,
int main(int argc, char *argv[]) {
/* curl_global_init(CURL_GLOBAL_ALL);
slack_client client = slack_init_client(_String("test token"), _String("Cookie: test_cookie=hello"));
_slack_debug_print_auth_test(&client, _String("test token"), _String("Cookie: test_cookie=hello"));
slack_client client = slack_init_client(_String("test token"),
_String("Cookie: test_cookie=hello")); _slack_debug_print_auth_test(&client,
_String("test token"), _String("Cookie: test_cookie=hello"));
curl_global_cleanup();
return 0;