From 55eaca8ec7bb9135d33f75afd216d690a0124e46 Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Mon, 24 Jan 2011 19:43:39 +0800 Subject: [PATCH] Render thread --- callbacks.c | 4 ++- render.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++--- render.h | 18 +++++++++- zathura.c | 11 ++++++ zathura.h | 6 ++++ 5 files changed, 131 insertions(+), 6 deletions(-) diff --git a/callbacks.c b/callbacks.c index 8fab8ab..820a053 100644 --- a/callbacks.c +++ b/callbacks.c @@ -16,6 +16,8 @@ cb_destroy(GtkWidget* widget, gpointer data) girara_session_destroy(Zathura.UI.session); } + document_close(); + return TRUE; } @@ -62,7 +64,7 @@ cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data) || ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* end of the page is in viewport */ || ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* begin of the page is in viewport */ ) { - page_render(Zathura.document->pages[page_id]); + render_page(Zathura.Sync.render_thread, Zathura.document->pages[page_id]); } } } diff --git a/render.c b/render.c index 2597251..eed5d7d 100644 --- a/render.c +++ b/render.c @@ -1,27 +1,117 @@ #include "render.h" #include "zathura.h" -bool page_render(zathura_page_t* page) +void* search(void* data); +bool render(zathura_page_t* page); + +void* +search(void* data) +{ + render_thread_t* render_thread = (render_thread_t*) data; + + while(true) { + g_static_mutex_lock(&(render_thread->lock)); + + if(girara_list_size(render_thread->list) <= 0) { + g_static_mutex_unlock(&(render_thread->lock)); + g_thread_yield(); + continue; + } + + zathura_page_t* page = (zathura_page_t*) girara_list_nth(render_thread->list, 0); + girara_list_remove(render_thread->list, page); + g_static_mutex_unlock(&(render_thread->lock)); + + printf("Rendered %d\n", page->number); + + render(page); + } + + return NULL; +} + +render_thread_t* +render_init(void) +{ + render_thread_t* render_thread = malloc(sizeof(render_thread_t)); + + if(!render_thread) { + goto error_ret; + } + + render_thread->list = girara_list_new(); + + if(!render_thread->list) { + goto error_free; + } + + render_thread->thread = g_thread_create(search, render_thread, TRUE, NULL); + + if(!render_thread->thread) { + goto error_free; + } + + g_static_mutex_init(&(render_thread->lock)); + + return render_thread; + +error_free: + + free(render_thread); + +error_ret: + + return NULL; +} + +void +render_free(render_thread_t* render_thread) +{ + if(!render_thread) { + return; + } + + girara_list_free(render_thread->list); + g_static_mutex_free(&(render_thread->lock)); +} + +bool +render_page(render_thread_t* render_thread, zathura_page_t* page) +{ + if(!render_thread || !page || !render_thread->list) { + return false; + } + + g_static_mutex_lock(&(render_thread->lock)); + if(!girara_list_contains(render_thread->list, page)) { + girara_list_append(render_thread->list, page); + } + g_static_mutex_unlock(&(render_thread->lock)); + + return true; +} + +bool +render(zathura_page_t* page) { g_static_mutex_lock(&(page->lock)); GtkWidget* image = zathura_page_render(page); - g_static_mutex_unlock(&(page->lock)); if(!image) { + g_static_mutex_unlock(&(page->lock)); printf("error: rendering failed\n"); return false; } /* add new page */ - g_static_mutex_lock(&(page->lock)); GList* list = gtk_container_get_children(GTK_CONTAINER(Zathura.UI.page_view)); GtkWidget* widget = (GtkWidget*) g_list_nth_data(list, page->number); g_list_free(list); if(!widget) { + g_static_mutex_unlock(&(page->lock)); printf("error: page container does not exist\n"); g_object_unref(image); - g_static_mutex_unlock(&(page->lock)); return false; } diff --git a/render.h b/render.h index e162f91..f1961fe 100644 --- a/render.h +++ b/render.h @@ -1,7 +1,23 @@ /* See LICENSE file for license and copyright information */ +#ifndef RENDER_H +#define RENDER_H + #include +#include +#include #include "ft/document.h" -bool page_render(zathura_page_t* page); +typedef struct render_thread_s +{ + girara_list_t* list; + GThread* thread; + GStaticMutex lock; +} render_thread_t; + +render_thread_t* render_init(void); +void render_free(render_thread_t* render_thread); +bool render_page(render_thread_t* render_thread, zathura_page_t* page); + +#endif // RENDER_H diff --git a/zathura.c b/zathura.c index a3fc688..473e2fa 100644 --- a/zathura.c +++ b/zathura.c @@ -117,6 +117,13 @@ document_open(const char* path, const char* password) girara_set_view(Zathura.UI.session, Zathura.UI.page_view); + /* threads */ + Zathura.Sync.render_thread = render_init(); + + if(!Zathura.Sync.render_thread) { + goto error_free; + } + /* first page */ if(!page_set(0)) { goto error_free; @@ -140,6 +147,10 @@ document_close() return false; } + if(Zathura.Sync.render_thread) { + render_free(Zathura.Sync.render_thread); + } + zathura_document_free(Zathura.document); return true; diff --git a/zathura.h b/zathura.h index b5d781a..7c9827c 100644 --- a/zathura.h +++ b/zathura.h @@ -5,6 +5,7 @@ #include #include +#include #include "ft/document.h" @@ -40,6 +41,11 @@ struct GtkWidget *page_view; } UI; + struct + { + render_thread_t* render_thread; + } Sync; + zathura_document_t* document; /**> The current document */ } Zathura;