diff --git a/wayland.c b/wayland.c index cf40a7c..9317537 100644 --- a/wayland.c +++ b/wayland.c @@ -63,6 +63,105 @@ struct client_state { /// Starting values. int width = 700, height = 700; +static void egl_init(struct client_state *state) { + EGLint config_attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT | EGL_OPENGL_BIT, + EGL_MIN_SWAP_INTERVAL, 0, // make sure that swapping buffers don't block the thread + EGL_NONE + }; + + static const EGLint context_attribs[] = { + //EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_MAJOR_VERSION, 4, + EGL_CONTEXT_MINOR_VERSION, 6, + EGL_CONTEXT_OPENGL_PROFILE_MASK, + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + EGL_NONE + }; + + state->egl_display = eglGetDisplay((EGLNativeDisplayType) state->wl_display); + + if (state->egl_display == EGL_NO_DISPLAY) { + fprintf(stderr, "Can't create egl display\n"); + exit(1); + } else { + fprintf(stderr, "Created egl display\n"); + } + + EGLint major, minor; + if (eglInitialize(state->egl_display, &major, &minor) != EGL_TRUE) { + fprintf(stderr, "Can't initialise egl display\n"); + exit(1); + } + printf("EGL major: %d, minor %d\n", major, minor); + + // Desktop GL? + if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) { + printf("eglBindAPI failed\n"); + exit(1); + } + + EGLint count; + eglGetConfigs(state->egl_display, NULL, 0, &count); + printf("EGL has %d configs\n", count); + + EGLConfig *configs = calloc(count, sizeof *configs); + + EGLint n; + eglChooseConfig(state->egl_display, config_attribs, + configs, count, &n); + + for (int i = 0; i < n; i++) { + EGLint size; + eglGetConfigAttrib(state->egl_display, + configs[i], EGL_BUFFER_SIZE, &size); + printf("Buffer size for config %d is %d\n", i, size); + eglGetConfigAttrib(state->egl_display, + configs[i], EGL_RED_SIZE, &size); + printf("Red size for config %d is %d\n", i, size); + // just choose the first one + state->egl_config = configs[i]; + break; + } + + state->egl_context = + eglCreateContext(state->egl_display, + state->egl_config, + EGL_NO_CONTEXT, context_attribs); + if (state->egl_context == EGL_NO_CONTEXT) { + printf("Failed to create EGL context\n"); + exit(1); + } +} + +void egl_init_surface(struct client_state *state, struct surface *surface) { + printf("Creating egl window of size: %dx%d\n", surface->width, surface->height); + surface->egl_window = wl_egl_window_create(surface->wl_surface, + surface->width, surface->height); + if (surface->egl_window == EGL_NO_SURFACE) { + fprintf(stderr, "Can't create egl window\n"); + exit(1); + } else { + fprintf(stderr, "Created egl window\n"); + } + + surface->egl_surface = + eglCreateWindowSurface(state->egl_display, + state->egl_config, + (unsigned long) surface->egl_window, NULL); + + if (eglMakeCurrent(state->egl_display, surface->egl_surface, + surface->egl_surface, state->egl_context)) { + fprintf(stderr, "Made current\n"); + } else { + fprintf(stderr, "Made current failed\n"); + } +} + static void wl_buffer_release(void *data, struct wl_buffer *wl_buffer) { /* Sent by the compositor when it's no longer using this buffer */ wl_buffer_destroy(wl_buffer); @@ -291,6 +390,7 @@ static void registry_handle_global( // frame callback struct wl_callback *cb = wl_surface_frame(wl_surface); wl_callback_add_listener(cb, &wl_surface_frame_listener, &state->surface_list->data); + egl_init_surface(state, &state->surface_list->data); } if ((strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) && (state->output_type == OUTPUT_LAYER)) { state->zwlr_layer_shell_v1 = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 4); @@ -343,6 +443,7 @@ static void registry_handle_global( // frame callback struct wl_callback *cb = wl_surface_frame(wl_surface); wl_callback_add_listener(cb, &wl_surface_frame_listener, surface_location); + egl_init_surface(state, surface_location); } } @@ -359,109 +460,6 @@ static const struct wl_registry_listener wl_registry_listener = { .global_remove = registry_handle_global_remove, }; -static void egl_init(struct client_state *state) { - EGLint config_attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT | EGL_OPENGL_BIT, - EGL_MIN_SWAP_INTERVAL, 0, // make sure that swapping buffers don't block the thread - EGL_NONE - }; - - static const EGLint context_attribs[] = { - //EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_CONTEXT_MAJOR_VERSION, 4, - EGL_CONTEXT_MINOR_VERSION, 6, - EGL_CONTEXT_OPENGL_PROFILE_MASK, - EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, - EGL_NONE - }; - - state->egl_display = eglGetDisplay((EGLNativeDisplayType) state->wl_display); - - if (state->egl_display == EGL_NO_DISPLAY) { - fprintf(stderr, "Can't create egl display\n"); - exit(1); - } else { - fprintf(stderr, "Created egl display\n"); - } - - EGLint major, minor; - if (eglInitialize(state->egl_display, &major, &minor) != EGL_TRUE) { - fprintf(stderr, "Can't initialise egl display\n"); - exit(1); - } - printf("EGL major: %d, minor %d\n", major, minor); - - // Desktop GL? - if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) { - printf("eglBindAPI failed\n"); - exit(1); - } - - EGLint count; - eglGetConfigs(state->egl_display, NULL, 0, &count); - printf("EGL has %d configs\n", count); - - EGLConfig *configs = calloc(count, sizeof *configs); - - EGLint n; - eglChooseConfig(state->egl_display, config_attribs, - configs, count, &n); - - for (int i = 0; i < n; i++) { - EGLint size; - eglGetConfigAttrib(state->egl_display, - configs[i], EGL_BUFFER_SIZE, &size); - printf("Buffer size for config %d is %d\n", i, size); - eglGetConfigAttrib(state->egl_display, - configs[i], EGL_RED_SIZE, &size); - printf("Red size for config %d is %d\n", i, size); - // just choose the first one - state->egl_config = configs[i]; - break; - } - - state->egl_context = - eglCreateContext(state->egl_display, - state->egl_config, - EGL_NO_CONTEXT, context_attribs); - if (state->egl_context == EGL_NO_CONTEXT) { - printf("Failed to create EGL context\n"); - exit(1); - } - - // EGL window - struct surface_list *next = state->surface_list; - while (next != NULL) { - printf("Creating egl window of size: %dx%d\n", next->data.width, next->data.height); - next->data.egl_window = wl_egl_window_create(next->data.wl_surface, - next->data.width, next->data.height); - if (next->data.egl_window == EGL_NO_SURFACE) { - fprintf(stderr, "Can't create egl window\n"); - exit(1); - } else { - fprintf(stderr, "Created egl window\n"); - } - - next->data.egl_surface = - eglCreateWindowSurface(state->egl_display, - state->egl_config, - (unsigned long) next->data.egl_window, NULL); - - if (eglMakeCurrent(state->egl_display, next->data.egl_surface, - next->data.egl_surface, state->egl_context)) { - fprintf(stderr, "Made current\n"); - } else { - fprintf(stderr, "Made current failed\n"); - } - - next = next->next; - } -} - /// Initializes wayland and creates an opengl context struct client_state* wayland_init(int output_type) { struct client_state *state = malloc(sizeof(struct client_state)); @@ -471,6 +469,7 @@ struct client_state* wayland_init(int output_type) { state->wl_registry = wl_display_get_registry(state->wl_display); state->surface_list = NULL; state->surface_list_next = NULL; + egl_init(state); wl_registry_add_listener(state->wl_registry, &wl_registry_listener, state); wl_display_roundtrip(state->wl_display); @@ -482,7 +481,6 @@ struct client_state* wayland_init(int output_type) { next = next->next; } - egl_init(state); return state; }