parallelize the drawing system

This commit is contained in:
Felix Kratz 2024-02-29 16:22:21 +01:00
parent dcf6658cd4
commit e7a54130e9
5 changed files with 42 additions and 3 deletions

View file

@ -5,6 +5,17 @@
#include "misc/helpers.h"
#include "window.h"
#define MAX_RENDER_THREADS 10
static pthread_t g_render_threads[MAX_RENDER_THREADS];
static uint32_t g_used_threads = 0;
void join_render_threads() {
for (int i = 0; i < g_used_threads; i++)
pthread_join(g_render_threads[i], NULL);
g_used_threads = 0;
}
bool bar_draws_item(struct bar* bar, struct bar_item* bar_item) {
if (!bar_item->drawing || !bar->shown || bar->hidden) return false;
@ -187,9 +198,25 @@ void bar_draw(struct bar* bar, bool forced) {
}
windows_freeze();
CGContextClearRect(window->context, window->frame);
bar_item_draw(bar_item, window->context);
CGContextFlush(window->context);
if (g_used_threads < MAX_RENDER_THREADS) {
uint32_t thread_id = g_used_threads++;
struct draw_item_payload {
struct window* window;
struct bar_item bar_item;
}* context = malloc(sizeof(struct draw_item_payload));
// We need to perform a shallow copy of the item here because
// the cached bounds will be invalidated when drawing the next bar.
context->bar_item = *bar_item;
context->window = window;
pthread_create(&g_render_threads[thread_id],
NULL,
draw_item_proc,
context );
} else {
CGContextClearRect(window->context, window->frame);
bar_item_draw(bar_item, window->context);
CGContextFlush(window->context);
}
}
if (g_bar_manager.bar_needs_update) CGContextFlush(bar->window.context);

View file

@ -30,3 +30,4 @@ bool bar_draws_item(struct bar* bar, struct bar_item* bar_item);
void bar_change_space(struct bar* bar, uint64_t dsid);
void context_set_font_smoothing(CGContextRef context, bool smoothing);
void join_render_threads();

View file

@ -697,6 +697,15 @@ void bar_item_clip_bar(struct bar_item* bar_item, int offset, struct bar* bar) {
background_clip_bar(&bar_item->label.background, offset, bar);
}
void* draw_item_proc(void* context) {
struct { struct window* window; struct bar_item bar_item; }* info = context;
CGContextClearRect(info->window->context, info->window->frame);
bar_item_draw(&info->bar_item, info->window->context);
CGContextFlush(info->window->context);
free(context);
return NULL;
}
void bar_item_draw(struct bar_item* bar_item, CGContextRef context) {
background_draw(&bar_item->background, context);
if (bar_item->type == BAR_COMPONENT_GROUP) return;

View file

@ -132,6 +132,7 @@ void bar_item_remove_window(struct bar_item* bar_item, uint32_t adid);
CGPoint bar_item_calculate_shadow_offsets(struct bar_item* bar_item);
uint32_t bar_item_calculate_bounds(struct bar_item* bar_item, uint32_t bar_height, uint32_t x, uint32_t y);
void* draw_item_proc(void* context);
void bar_item_draw(struct bar_item* bar_item, CGContextRef context);
bool bar_item_clip_needs_update_for_bar(struct bar_item* bar_item, struct bar* bar);
void bar_item_clip_bar(struct bar_item* bar_item, int offset, struct bar* bar);

View file

@ -429,6 +429,7 @@ void bar_manager_refresh(struct bar_manager* bar_manager, bool forced) {
}
bar_manager_clear_needs_update(bar_manager);
join_render_threads();
}
void bar_manager_resize(struct bar_manager* bar_manager) {