summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrootavish <[email protected]>2014-08-06 17:22:34 +0530
committerrootavish <[email protected]>2014-08-06 17:22:34 +0530
commit683022d92b63bea1544e8d19bc57d47ef84f5fff (patch)
tree3b88ec7ac949efb3faa2fd8c065dc7f6854b12b9
parent56880392a6678ccec12bbec016939597acd49b07 (diff)
downloadatril-683022d92b63bea1544e8d19bc57d47ef84f5fff.tar.bz2
atril-683022d92b63bea1544e8d19bc57d47ef84f5fff.tar.xz
Redesigned the thumbnail code for ePub
No more crashes when searching with the sidebar open, will probably add a pixbuf cache as well to speed it up even further. The process which I earlier thought was not possible without separate jobs, work just fine as a single job, if I change the run mode of the thumbnail job, and incorporate a trylock() in case of epub.
-rw-r--r--libview/ev-jobs.c187
-rw-r--r--libview/ev-jobs.h23
-rw-r--r--shell/ev-sidebar-thumbnails.c5
3 files changed, 61 insertions, 154 deletions
diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c
index 3a7dfd27..e7f0ba35 100644
--- a/libview/ev-jobs.c
+++ b/libview/ev-jobs.c
@@ -67,8 +67,6 @@ static void ev_job_page_data_init (EvJobPageData *job);
static void ev_job_page_data_class_init (EvJobPageDataClass *class);
static void ev_job_thumbnail_init (EvJobThumbnail *job);
static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class);
-static void ev_job_web_thumbnail_init (EvJobWebThumbnail *job);
-static void ev_job_web_thumbnail_class_init (EvJobWebThumbnailClass *class);
static void ev_job_load_init (EvJobLoad *job);
static void ev_job_load_class_init (EvJobLoadClass *class);
static void ev_job_save_init (EvJobSave *job);
@@ -112,7 +110,6 @@ G_DEFINE_TYPE (EvJobAnnots, ev_job_annots, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobPageData, ev_job_page_data, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
-G_DEFINE_TYPE (EvJobWebThumbnail, ev_job_web_thumbnail, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
@@ -793,6 +790,32 @@ ev_job_thumbnail_dispose (GObject *object)
(* G_OBJECT_CLASS (ev_job_thumbnail_parent_class)->dispose) (object);
}
+static void
+web_thumbnail_get_screenshot_cb(WebKitWebView *webview,
+ WebKitWebFrame *webframe,
+ EvJobThumbnail *job_thumb)
+{
+ if (webkit_web_view_get_load_status(webview) != WEBKIT_LOAD_FINISHED) {
+ return;
+ }
+ EvPage *page = ev_document_get_page (EV_JOB(job_thumb)->document, job_thumb->page);
+ job_thumb->surface = webkit_web_view_get_snapshot (WEBKIT_WEB_VIEW(webview));
+ EvRenderContext *rc = ev_render_context_new (page, job_thumb->rotation, job_thumb->scale);
+ EvPage *screenshotpage;
+ screenshotpage = ev_page_new(job_thumb->page);
+ screenshotpage->backend_page = (EvBackendPage)job_thumb->surface;
+ screenshotpage->backend_destroy_func = (EvBackendPageDestroyFunc)cairo_surface_destroy ;
+ ev_render_context_set_page(rc,screenshotpage);
+
+ job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (EV_JOB(job_thumb)->document),
+ rc, TRUE);
+ g_object_unref(screenshotpage);
+ g_object_unref(rc);
+
+ ev_document_doc_mutex_unlock();
+ ev_job_succeeded(EV_JOB(job_thumb));
+}
+
static gboolean
ev_job_thumbnail_run (EvJob *job)
{
@@ -802,7 +825,14 @@ ev_job_thumbnail_run (EvJob *job)
ev_debug_message (DEBUG_JOBS, "%d (%p)", job_thumb->page, job);
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
- ev_document_doc_mutex_lock ();
+ if (job->document->iswebdocument) {
+ /* Do not block the main loop */
+ if (!ev_document_doc_mutex_trylock ())
+ return TRUE;
+ }
+ else {
+ ev_document_doc_mutex_lock ();
+ }
page = ev_document_get_page (job->document, job_thumb->page);
if (job->document->iswebdocument == TRUE ) {
@@ -814,38 +844,34 @@ ev_job_thumbnail_run (EvJob *job)
g_object_unref (page);
if (job->document->iswebdocument == TRUE) {
- gboolean completed = FALSE;
- cairo_surface_t *surface = NULL ;
- EvJobWebThumbnail *web_thumb_job =
- EV_JOB_WEB_THUMBNAIL(ev_job_web_thumbnail_new(job->document, &completed, (gchar*)rc->page->backend_page,&surface));
-
- ev_job_scheduler_push_job (EV_JOB (web_thumb_job), EV_JOB_PRIORITY_HIGH);
-
- while (completed == FALSE) {
- /* Let the job complete*/
- }
- /* For the purpose of thumbnails only, we make the page a cairo surface, instead of the uri's we are passing around*/
- EvPage *screenshotpage;
- screenshotpage = ev_page_new(rc->page->index);
- screenshotpage->backend_page = (EvBackendPage)surface;
- screenshotpage->backend_destroy_func = (EvBackendPageDestroyFunc)cairo_surface_destroy ;
- ev_render_context_set_page(rc,screenshotpage);
-
- job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (job->document),
- rc, TRUE);
-
- g_object_unref(web_thumb_job);
- g_object_unref(screenshotpage);
+ if (!webview) {
+ webview = webkit_web_view_new();
+ }
+
+ if (!offscreenwindow) {
+ offscreenwindow = gtk_offscreen_window_new();
+
+ gtk_container_add(GTK_CONTAINER(offscreenwindow),GTK_WIDGET(webview));
+
+ gtk_window_set_default_size (GTK_WINDOW(offscreenwindow),800,1080);
+
+ gtk_widget_show_all(offscreenwindow);
+ }
+
+ webkit_web_view_load_uri(WEBKIT_WEB_VIEW(webview),(gchar*)rc->page->backend_page);
+ g_signal_connect(WEBKIT_WEB_VIEW(webview),"notify::load-status",
+ G_CALLBACK(web_thumbnail_get_screenshot_cb),
+ g_object_ref(job_thumb));
}
else {
job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (job->document),
rc, TRUE);
+ ev_document_doc_mutex_unlock ();
+
+ ev_job_succeeded (job);
}
g_object_unref (rc);
- ev_document_doc_mutex_unlock ();
-
- ev_job_succeeded (job);
-
+
return FALSE;
}
@@ -879,107 +905,6 @@ ev_job_thumbnail_new (EvDocument *document,
return EV_JOB (job);
}
-/* This job is a part of thumbnails, but will run as a thread and call the otherwise main loop job on a signal*/
-/* EvJobWebThumbnail */
-static void
-ev_job_web_thumbnail_init (EvJobWebThumbnail *job)
-{
- EV_JOB (job)->run_mode = EV_JOB_RUN_MAIN_LOOP;
-}
-
-static void
-ev_job_web_thumbnail_dispose (GObject *object)
-{
- EvJobWebThumbnail *job;
-
- job = EV_JOB_WEB_THUMBNAIL (object);
-
- ev_debug_message (DEBUG_JOBS, "%s (%p)", job->page, job);
-
- if(job->page) {
- g_free(job->page);
- job->page = NULL;
- }
-
- (* G_OBJECT_CLASS (ev_job_web_thumbnail_parent_class)->dispose) (object);
-}
-
-static void
-web_thumbnail_get_screenshot_cb(WebKitWebView *webview,
- WebKitWebFrame *webframe,
- EvJobWebThumbnail *web_thumb_job)
-{
- *(web_thumb_job->surface) = webkit_web_view_get_snapshot (WEBKIT_WEB_VIEW(webview));
- if (*(web_thumb_job->surface)) {
- //TODO : what if you don't get one?
- *(web_thumb_job->completed) = TRUE;
- }
-}
-
-static gboolean
-ev_job_web_thumbnail_run (EvJob *job)
-{
- EvJobWebThumbnail *web_thumb_job = EV_JOB_WEB_THUMBNAIL(job);
- if (!webview) {
- webview = webkit_web_view_new();
- }
-
- if (!offscreenwindow) {
- offscreenwindow = gtk_offscreen_window_new();
-
- gtk_container_add(GTK_CONTAINER(offscreenwindow),GTK_WIDGET(webview));
-
- gtk_window_set_default_size (GTK_WINDOW(offscreenwindow),800,1080);
-
- gtk_widget_show_all(offscreenwindow);
- }
-
- ev_debug_message (DEBUG_JOBS, "%s (%p)", web_thumb_job->page, job);
-
-#ifdef EV_ENABLE_DEBUG
- /* We use the #ifdef in this case because of the if */
- if (web_thumb_job->surface == NULL)
- ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-#endif
-
- webkit_web_view_load_uri(WEBKIT_WEB_VIEW(webview),web_thumb_job->page);
- g_signal_connect(WEBKIT_WEB_VIEW(webview),"document-load-finished",G_CALLBACK(web_thumbnail_get_screenshot_cb),EV_JOB_WEB_THUMBNAIL(job));
- ev_job_succeeded (EV_JOB(web_thumb_job));
- return FALSE;
-}
-
-static void
-ev_job_web_thumbnail_class_init (EvJobWebThumbnailClass *class)
-{
- GObjectClass *oclass = G_OBJECT_CLASS (class);
- EvJobClass *job_class = EV_JOB_CLASS (class);
-
- oclass->dispose = ev_job_web_thumbnail_dispose;
- job_class->run = ev_job_web_thumbnail_run;
-}
-
-EvJob *
-ev_job_web_thumbnail_new (EvDocument *document,
- gboolean *completed,
- gchar *webpage,
- cairo_surface_t **surface)
-{
- EvJobWebThumbnail *job;
-
- ev_debug_message (DEBUG_JOBS, "%s", webpage);
-
- job = g_object_new (EV_TYPE_JOB_WEB_THUMBNAIL, NULL);
-
- EV_JOB (job)->document = g_object_ref (document);
-
- job->completed = completed;
-
- job->surface = surface;
- job->page = g_strdup(webpage);
-
- return EV_JOB (job);
-}
-
/* EvJobFonts */
static void
ev_job_fonts_init (EvJobFonts *job)
diff --git a/libview/ev-jobs.h b/libview/ev-jobs.h
index 87365672..fdc23bae 100644
--- a/libview/ev-jobs.h
+++ b/libview/ev-jobs.h
@@ -292,6 +292,7 @@ struct _EvJobThumbnail
gint page;
gint rotation;
gdouble scale;
+ cairo_surface_t *surface;
GdkPixbuf *thumbnail;
};
@@ -300,22 +301,6 @@ struct _EvJobThumbnailClass
EvJobClass parent_class;
};
-struct _EvJobWebThumbnail
-{
- EvJob parent;
- GtkWidget *webview;
- GtkWidget *offscreenwindow;
- gboolean *completed;
- GRWLock screenlock;
- cairo_surface_t **surface;
- gchar* page;
-};
-
-struct _EvJobWebThumbnailClass
-{
- EvJobClass parent_class;
-};
-
struct _EvJobFonts
{
EvJob parent;
@@ -474,12 +459,6 @@ EvJob *ev_job_thumbnail_new (EvDocument *document,
gint rotation,
gdouble scale);
-/* EvJobWebThumbnail */
-GType ev_job_web_thumbnail_get_type (void) G_GNUC_CONST;
-EvJob *ev_job_web_thumbnail_new (EvDocument *document,
- gboolean *completed,
- gchar *webpage,
- cairo_surface_t **surface);
/* EvJobFonts */
GType ev_job_fonts_get_type (void) G_GNUC_CONST;
EvJob *ev_job_fonts_new (EvDocument *document);
diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c
index 5c4cb4be..a6102355 100644
--- a/shell/ev-sidebar-thumbnails.c
+++ b/shell/ev-sidebar-thumbnails.c
@@ -442,7 +442,6 @@ add_range (EvSidebarThumbnails *sidebar_thumbnails,
result && page <= end_page;
result = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->list_store), &iter), page ++) {
EvJob *job;
-
gboolean thumbnail_set;
gtk_tree_model_get (GTK_TREE_MODEL (priv->list_store), &iter,
@@ -455,6 +454,10 @@ add_range (EvSidebarThumbnails *sidebar_thumbnails,
page, priv->rotation,
get_scale_for_page (sidebar_thumbnails, page));
+ if (priv->document->iswebdocument) {
+ ev_job_set_run_mode(job, EV_JOB_RUN_MAIN_LOOP);
+ }
+
ev_job_scheduler_push_job (EV_JOB (job), EV_JOB_PRIORITY_HIGH);
g_object_set_data_full (G_OBJECT (job), "tree_iter",