render: replace EGL/OpenGL pipeline with wl_shm shared memory
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I15dbcca9d12b5c24ed8c82ecc375f4046a6a6964
This commit is contained in:
parent
7863890002
commit
5ba4407367
6 changed files with 323 additions and 739 deletions
4
Makefile
4
Makefile
|
|
@ -34,7 +34,7 @@ DEBUG_CFLAGS += -D_GNU_SOURCE -DCHROMA_VERSION=\"$(VERSION)-debug\"
|
|||
DEBUG_CFLAGS += -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer
|
||||
|
||||
# Libraries using pkg-config
|
||||
PKG_DEPS = wayland-client wayland-egl egl glesv2 wayland-protocols
|
||||
PKG_DEPS = wayland-client wayland-protocols
|
||||
CFLAGS += $(shell pkg-config --cflags $(PKG_DEPS))
|
||||
LDFLAGS += $(shell pkg-config --libs $(PKG_DEPS))
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ static: $(TARGET)
|
|||
# Check if required dependencies are available
|
||||
check-deps:
|
||||
@echo "Checking dependencies..."
|
||||
@pkg-config --exists $(PKG_DEPS) || (echo "Missing dependencies. Install: wayland-protocols libwayland-dev libegl1-mesa-dev libgl1-mesa-dev wayland-scanner" && exit 1)
|
||||
@pkg-config --exists $(PKG_DEPS) || (echo "Missing dependencies. Install: wayland-protocols libwayland-dev wayland-scanner" && exit 1)
|
||||
@which wayland-scanner >/dev/null || (echo "wayland-scanner not found. Please install wayland-scanner." && exit 1)
|
||||
@echo "All dependencies found."
|
||||
|
||||
|
|
|
|||
37
include/chroma.h
vendored
37
include/chroma.h
vendored
|
|
@ -3,14 +3,11 @@
|
|||
|
||||
#include "wlr-layer-shell-unstable-v1.h"
|
||||
#include "xdg-shell.h"
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-egl.h>
|
||||
|
||||
#include "chroma_version.h"
|
||||
|
||||
|
|
@ -73,6 +70,7 @@ typedef struct {
|
|||
int channels;
|
||||
char path[MAX_PATH_LEN];
|
||||
bool loaded;
|
||||
bool data_from_stbi; // true if data was allocated by stbi_load
|
||||
int ref_count; // Number of outputs using this image
|
||||
} chroma_image_t;
|
||||
|
||||
|
|
@ -94,10 +92,14 @@ typedef struct {
|
|||
// Rendering context
|
||||
struct wl_surface *surface;
|
||||
struct zwlr_layer_surface_v1 *layer_surface;
|
||||
struct wl_egl_window *egl_window;
|
||||
EGLSurface egl_surface;
|
||||
uint32_t configure_serial;
|
||||
|
||||
// Shared memory buffer
|
||||
struct wl_buffer *shm_buffer;
|
||||
void *shm_data;
|
||||
size_t shm_size;
|
||||
int shm_stride;
|
||||
|
||||
// Associated wallpaper
|
||||
chroma_image_t *image;
|
||||
|
||||
|
|
@ -108,15 +110,6 @@ typedef struct {
|
|||
float anchor_x; // custom X offset (0-100, 50=center)
|
||||
float anchor_y; // custom Y offset (0-100, 50=center)
|
||||
bool config_loaded;
|
||||
|
||||
// OpenGL resource cache
|
||||
GLuint texture_id;
|
||||
GLuint shader_program;
|
||||
GLuint vbo;
|
||||
GLuint ebo;
|
||||
bool gl_resources_initialized;
|
||||
bool texture_uploaded;
|
||||
bool vbo_dirty; // track VBO needs update
|
||||
bool configured; // track if initial configure received
|
||||
} chroma_output_t;
|
||||
|
||||
|
|
@ -159,14 +152,7 @@ typedef struct chroma_state {
|
|||
struct wl_registry *registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct zwlr_layer_shell_v1 *layer_shell;
|
||||
|
||||
// EGL context
|
||||
EGLDisplay egl_display;
|
||||
EGLContext egl_context;
|
||||
EGLConfig egl_config;
|
||||
|
||||
// Shared OpenGL resources
|
||||
GLuint shader_program;
|
||||
struct wl_shm *shm;
|
||||
|
||||
// Outputs
|
||||
chroma_output_t outputs[MAX_OUTPUTS];
|
||||
|
|
@ -221,13 +207,12 @@ void chroma_output_description(void *data, struct wl_output *output,
|
|||
const char *description);
|
||||
void chroma_output_done(void *data, struct wl_output *output);
|
||||
|
||||
// EGL and rendering
|
||||
int chroma_egl_init(chroma_state_t *state);
|
||||
void chroma_egl_cleanup(chroma_state_t *state);
|
||||
// Rendering and surface management
|
||||
int chroma_surface_create(chroma_state_t *state, chroma_output_t *output);
|
||||
void chroma_surface_destroy(chroma_output_t *output);
|
||||
int chroma_buffer_create(chroma_state_t *state, chroma_output_t *output);
|
||||
void chroma_buffer_destroy(chroma_output_t *output);
|
||||
int chroma_render_wallpaper(chroma_state_t *state, chroma_output_t *output);
|
||||
void chroma_output_invalidate_texture(chroma_output_t *output);
|
||||
|
||||
// Layer shell functions
|
||||
void chroma_layer_surface_configure(void *data,
|
||||
|
|
|
|||
23
src/core.c
23
src/core.c
|
|
@ -24,8 +24,6 @@ int chroma_init(chroma_state_t *state) {
|
|||
// Set initial state
|
||||
state->running = false;
|
||||
state->initialized = false;
|
||||
state->egl_display = EGL_NO_DISPLAY;
|
||||
state->egl_context = EGL_NO_CONTEXT;
|
||||
|
||||
// Initialize stb_image
|
||||
chroma_image_init_stb();
|
||||
|
|
@ -53,9 +51,6 @@ void chroma_cleanup(chroma_state_t *state) {
|
|||
// Clean up all images
|
||||
chroma_images_cleanup(state);
|
||||
|
||||
// Clean up EGL
|
||||
chroma_egl_cleanup(state);
|
||||
|
||||
// Clean up Wayland
|
||||
chroma_wayland_disconnect(state);
|
||||
|
||||
|
|
@ -104,24 +99,16 @@ static int assign_wallpaper_to_output(chroma_state_t *state,
|
|||
return CHROMA_ERROR_IMAGE;
|
||||
}
|
||||
|
||||
// Check if image changed and invalidate texture cache if neceessary
|
||||
// Check if image changed
|
||||
bool image_changed = (output->image != image);
|
||||
if (image_changed && output->image) {
|
||||
chroma_image_release(output->image);
|
||||
chroma_output_invalidate_texture(output);
|
||||
output->vbo_dirty = true; // VBO needs update for new image
|
||||
chroma_log("DEBUG", "Image changed for output %u, invalidated texture",
|
||||
output->id);
|
||||
chroma_log("DEBUG", "Image changed for output %u", output->id);
|
||||
}
|
||||
|
||||
// Assign image to output
|
||||
output->image = image;
|
||||
|
||||
// Mark VBO as dirty if image changed
|
||||
if (image_changed) {
|
||||
output->vbo_dirty = true;
|
||||
}
|
||||
|
||||
// Store old configuration values for comparison
|
||||
chroma_scale_mode_t old_scale_mode = output->scale_mode;
|
||||
chroma_filter_quality_t old_filter_quality = output->filter_quality;
|
||||
|
|
@ -144,16 +131,14 @@ static int assign_wallpaper_to_output(chroma_state_t *state,
|
|||
output->anchor, (double)output->anchor_x,
|
||||
(double)output->anchor_y);
|
||||
|
||||
// Check if configuration changed and invalidate texture if needed
|
||||
// Check if configuration changed
|
||||
if (had_config &&
|
||||
(old_scale_mode != output->scale_mode ||
|
||||
old_filter_quality != output->filter_quality ||
|
||||
old_anchor != output->anchor || old_anchor_x != output->anchor_x ||
|
||||
old_anchor_y != output->anchor_y)) {
|
||||
chroma_output_invalidate_texture(output);
|
||||
output->vbo_dirty = true; // VBO needs update for new scale mode
|
||||
chroma_log("DEBUG",
|
||||
"Configuration changed for output %u, invalidated texture",
|
||||
"Configuration changed for output %u",
|
||||
output->id);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
10
src/main.c
10
src/main.c
|
|
@ -178,16 +178,6 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
chroma_log_memory_stats("post-wayland-connect");
|
||||
|
||||
// Initialize EGL
|
||||
ret = chroma_egl_init(&state);
|
||||
if (ret != CHROMA_OK) {
|
||||
chroma_log("ERROR", "Failed to initialize EGL: %s",
|
||||
chroma_error_string(ret));
|
||||
chroma_cleanup(&state);
|
||||
return 1;
|
||||
}
|
||||
chroma_log_memory_stats("post-egl-init");
|
||||
|
||||
chroma_log("INFO", "Chroma daemon initialized successfully");
|
||||
chroma_log_memory_stats("pre-main-loop");
|
||||
|
||||
|
|
|
|||
1047
src/render.c
1047
src/render.c
File diff suppressed because it is too large
Load diff
|
|
@ -37,6 +37,13 @@ static void registry_global(void *data, struct wl_registry *registry,
|
|||
"TRACE",
|
||||
"wlr-layer-shell protocol available, wallpaper support enabled");
|
||||
}
|
||||
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||
state->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
if (!state->shm) {
|
||||
chroma_log("ERROR", "Failed to bind shm");
|
||||
} else {
|
||||
chroma_log("INFO", "Bound shm (version %u)", version);
|
||||
}
|
||||
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||
struct wl_output *output = wl_registry_bind(
|
||||
registry, id, &wl_output_interface, version < 4 ? version : 4);
|
||||
|
|
@ -91,7 +98,7 @@ static void layer_surface_configure(void *data,
|
|||
chroma_log("TRACE", "Sent configure acknowledgment for output %u serial %u",
|
||||
output->id, serial);
|
||||
|
||||
// Mark as configured - actual commit happens in render via eglSwapBuffers
|
||||
// Mark as configured - actual commit happens in render via wl_surface_commit
|
||||
output->configured = true;
|
||||
|
||||
chroma_log("DEBUG", "Acknowledged layer surface configure for output %u",
|
||||
|
|
@ -284,6 +291,13 @@ int chroma_wayland_connect(chroma_state_t *state) {
|
|||
return CHROMA_ERROR_WAYLAND;
|
||||
}
|
||||
|
||||
// Check if we got shm
|
||||
if (!state->shm) {
|
||||
chroma_log("ERROR", "No shm available");
|
||||
chroma_wayland_disconnect(state);
|
||||
return CHROMA_ERROR_WAYLAND;
|
||||
}
|
||||
|
||||
chroma_log("INFO", "Connected to Wayland display, found %d outputs",
|
||||
state->output_count);
|
||||
return CHROMA_OK;
|
||||
|
|
@ -316,6 +330,11 @@ void chroma_wayland_disconnect(chroma_state_t *state) {
|
|||
state->layer_shell = NULL;
|
||||
}
|
||||
|
||||
if (state->shm) {
|
||||
wl_shm_destroy(state->shm);
|
||||
state->shm = NULL;
|
||||
}
|
||||
|
||||
if (state->compositor) {
|
||||
wl_compositor_destroy(state->compositor);
|
||||
state->compositor = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue