render: replace EGL/OpenGL pipeline with wl_shm shared memory
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: If73c9ac16c2a31e211c2cda2b0ce2c586a6a6964
This commit is contained in:
parent
58861c1ea5
commit
a838f86731
3 changed files with 42 additions and 30 deletions
1
include/chroma.h
vendored
1
include/chroma.h
vendored
|
|
@ -212,6 +212,7 @@ 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);
|
||||
void chroma_buffer_unmap(chroma_output_t *output);
|
||||
int chroma_render_wallpaper(chroma_state_t *state, chroma_output_t *output);
|
||||
|
||||
// Layer shell functions
|
||||
|
|
|
|||
|
|
@ -137,9 +137,7 @@ static int assign_wallpaper_to_output(chroma_state_t *state,
|
|||
old_filter_quality != output->filter_quality ||
|
||||
old_anchor != output->anchor || old_anchor_x != output->anchor_x ||
|
||||
old_anchor_y != output->anchor_y)) {
|
||||
chroma_log("DEBUG",
|
||||
"Configuration changed for output %u",
|
||||
output->id);
|
||||
chroma_log("DEBUG", "Configuration changed for output %u", output->id);
|
||||
}
|
||||
} else {
|
||||
output->config_loaded = false;
|
||||
|
|
@ -158,8 +156,8 @@ static int assign_wallpaper_to_output(chroma_state_t *state,
|
|||
// Render wallpaper
|
||||
int ret = chroma_render_wallpaper(state, output);
|
||||
if (ret != CHROMA_OK) {
|
||||
chroma_log("ERROR", "Failed to render wallpaper for output %u: %s", output->id,
|
||||
chroma_error_string(ret));
|
||||
chroma_log("ERROR", "Failed to render wallpaper for output %u: %s",
|
||||
output->id, chroma_error_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
63
src/render.c
63
src/render.c
|
|
@ -33,6 +33,22 @@ void chroma_buffer_destroy(chroma_output_t *output) {
|
|||
}
|
||||
}
|
||||
|
||||
// Unmap client-side memory while keeping the wl_buffer proxy alive.
|
||||
// The compositor retains its own fd reference and mapping, so the
|
||||
// wallpaper remains visible after this call.
|
||||
void chroma_buffer_unmap(chroma_output_t *output) {
|
||||
if (!output || !output->shm_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (munmap(output->shm_data, output->shm_size) < 0) {
|
||||
chroma_log("WARN", "munmap failed: %s", strerror(errno));
|
||||
}
|
||||
output->shm_data = NULL;
|
||||
output->shm_size = 0;
|
||||
output->shm_stride = 0;
|
||||
}
|
||||
|
||||
// Create shared memory buffer for an output
|
||||
int chroma_buffer_create(chroma_state_t *state, chroma_output_t *output) {
|
||||
if (!state || !output || !state->shm) {
|
||||
|
|
@ -80,8 +96,7 @@ int chroma_buffer_create(chroma_state_t *state, chroma_output_t *output) {
|
|||
// Fill with black
|
||||
memset(data, 0, size);
|
||||
|
||||
struct wl_shm_pool *pool =
|
||||
wl_shm_create_pool(state->shm, fd, (int32_t)size);
|
||||
struct wl_shm_pool *pool = wl_shm_create_pool(state->shm, fd, (int32_t)size);
|
||||
if (!pool) {
|
||||
chroma_log("ERROR", "wl_shm_create_pool failed");
|
||||
munmap(data, size);
|
||||
|
|
@ -109,8 +124,7 @@ int chroma_buffer_create(chroma_state_t *state, chroma_output_t *output) {
|
|||
}
|
||||
|
||||
// Sample a pixel from image data (grayscale, grayscale+alpha, RGB, or RGBA)
|
||||
static inline uint32_t sample_pixel(const chroma_image_t *image, int x,
|
||||
int y) {
|
||||
static inline uint32_t sample_pixel(const chroma_image_t *image, int x, int y) {
|
||||
if (!image || !image->data || x < 0 || y < 0 || x >= image->width ||
|
||||
y >= image->height) {
|
||||
return 0xFF000000; // black with full alpha
|
||||
|
|
@ -147,8 +161,7 @@ static inline uint32_t sample_pixel(const chroma_image_t *image, int x,
|
|||
}
|
||||
|
||||
// Draw scaled image into the shared memory buffer
|
||||
static void draw_scaled_image(chroma_output_t *output,
|
||||
chroma_image_t *image) {
|
||||
static void draw_scaled_image(chroma_output_t *output, chroma_image_t *image) {
|
||||
if (!output || !image || !output->shm_data) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -263,10 +276,8 @@ static void draw_scaled_image(chroma_output_t *output,
|
|||
default: {
|
||||
if (img_w <= out_w && img_h <= out_h) {
|
||||
// Image fits entirely - position with anchor
|
||||
float offset_x =
|
||||
(anchor_x / 100.0f) * ((float)out_w - (float)img_w);
|
||||
float offset_y =
|
||||
(anchor_y / 100.0f) * ((float)out_h - (float)img_h);
|
||||
float offset_x = (anchor_x / 100.0f) * ((float)out_w - (float)img_w);
|
||||
float offset_y = (anchor_y / 100.0f) * ((float)out_h - (float)img_h);
|
||||
|
||||
for (int y = 0; y < img_h; y++) {
|
||||
for (int x = 0; x < img_w; x++) {
|
||||
|
|
@ -279,10 +290,8 @@ static void draw_scaled_image(chroma_output_t *output,
|
|||
}
|
||||
} else {
|
||||
// Image is larger than output - clip with anchor
|
||||
float src_offset_x =
|
||||
(anchor_x / 100.0f) * ((float)img_w - (float)out_w);
|
||||
float src_offset_y =
|
||||
(anchor_y / 100.0f) * ((float)img_h - (float)out_h);
|
||||
float src_offset_x = (anchor_x / 100.0f) * ((float)img_w - (float)out_w);
|
||||
float src_offset_y = (anchor_y / 100.0f) * ((float)img_h - (float)out_h);
|
||||
|
||||
if (src_offset_x < 0)
|
||||
src_offset_x = 0;
|
||||
|
|
@ -333,19 +342,16 @@ int chroma_surface_create(chroma_state_t *state, chroma_output_t *output) {
|
|||
}
|
||||
|
||||
// Configure layer surface
|
||||
zwlr_layer_surface_v1_set_size(output->layer_surface,
|
||||
(uint32_t)output->width,
|
||||
zwlr_layer_surface_v1_set_size(output->layer_surface, (uint32_t)output->width,
|
||||
(uint32_t)output->height);
|
||||
zwlr_layer_surface_v1_set_anchor(
|
||||
output->layer_surface,
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
|
||||
zwlr_layer_surface_v1_set_anchor(output->layer_surface,
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1);
|
||||
zwlr_layer_surface_v1_set_keyboard_interactivity(
|
||||
output->layer_surface,
|
||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE);
|
||||
output->layer_surface, ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE);
|
||||
|
||||
// Add layer surface listener
|
||||
zwlr_layer_surface_v1_add_listener(
|
||||
|
|
@ -417,11 +423,18 @@ int chroma_render_wallpaper(chroma_state_t *state, chroma_output_t *output) {
|
|||
wl_surface_damage_buffer(output->surface, 0, 0, output->width,
|
||||
output->height);
|
||||
wl_surface_commit(output->surface);
|
||||
wl_display_flush(state->display);
|
||||
if (wl_display_flush(state->display) < 0) {
|
||||
chroma_log("ERROR", "Failed to flush Wayland display for output %u: %s",
|
||||
output->id, strerror(errno));
|
||||
return CHROMA_ERROR_WAYLAND;
|
||||
}
|
||||
|
||||
chroma_log("INFO", "Rendered wallpaper to output %u (%dx%d)", output->id,
|
||||
output->width, output->height);
|
||||
|
||||
// Unmap client-side memory; compositor keeps its own fd reference
|
||||
chroma_buffer_unmap(output);
|
||||
|
||||
// Release image reference and free CPU data if no longer needed
|
||||
if (output->image) {
|
||||
chroma_image_t *image = output->image;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue