From cd2d4116a78ef055ea5dacfbb9a38bc77618b329 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Mon, 14 Apr 2008 18:37:14 +0000 Subject: Create the render context needed for rendering a page in the render thread 2008-04-14 Carlos Garcia Campos * shell/ev-jobs.[ch]: (ev_job_render_dispose), (ev_job_render_new), (ev_job_render_set_selection_info), (ev_job_render_run): * shell/ev-pixbuf-cache.c: (job_page_ready_cb), (job_finished_cb), (check_job_size_and_unref), (copy_job_page_and_selection_to_job_info), (copy_job_to_job_info), (add_job), (ev_pixbuf_cache_get_selection_surface): Create the render context needed for rendering a page in the render thread so that we don't block the main thread. Simplify EvJobRender API. svn path=/trunk/; revision=3005 --- diff --git a/ChangeLog b/ChangeLog index 79c0003..568aa5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2008-04-14 Carlos Garcia Campos + * shell/ev-jobs.[ch]: (ev_job_render_dispose), + (ev_job_render_new), (ev_job_render_set_selection_info), + (ev_job_render_run): + * shell/ev-pixbuf-cache.c: (job_page_ready_cb), (job_finished_cb), + (check_job_size_and_unref), + (copy_job_page_and_selection_to_job_info), (copy_job_to_job_info), + (add_job), (ev_pixbuf_cache_get_selection_surface): + + Create the render context needed for rendering a page in the render + thread so that we don't block the main thread. Simplify + EvJobRender API. + +2008-04-14 Carlos Garcia Campos + * libdocument/Makefile.am: * libdocument/ev-page.[ch]: * libdocument/ev-render-context.[ch]: (ev_render_context_dispose), diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index 7a642a2..8c0472a 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -128,16 +128,16 @@ ev_job_render_dispose (GObject *object) job = EV_JOB_RENDER (object); + if (job->ev_page) { + g_object_unref (job->ev_page); + job->ev_page = NULL; + } + if (job->surface) { cairo_surface_destroy (job->surface); job->surface = NULL; } - if (job->rc) { - g_object_unref (job->rc); - job->rc = NULL; - } - if (job->selection) { cairo_surface_destroy (job->selection); job->selection = NULL; @@ -267,45 +267,26 @@ ev_job_links_run (EvJobLinks *job) ev_document_doc_mutex_unlock (); } - EvJob * -ev_job_render_new (EvDocument *document, - EvRenderContext *rc, - gint width, - gint height, - EvRectangle *selection_points, - EvSelectionStyle selection_style, - GdkColor *text, - GdkColor *base, - gboolean include_forms, - gboolean include_links, - gboolean include_images, - gboolean include_text, - gboolean include_selection) +ev_job_render_new (EvDocument *document, + gint page, + gint rotation, + gdouble scale, + gint width, + gint height, + EvRenderFlags flags) { EvJobRender *job; - g_return_val_if_fail (EV_IS_RENDER_CONTEXT (rc), NULL); - if (include_selection) - g_return_val_if_fail (selection_points != NULL, NULL); - job = g_object_new (EV_TYPE_JOB_RENDER, NULL); EV_JOB (job)->document = g_object_ref (document); - job->rc = g_object_ref (rc); + job->page = page; + job->rotation = rotation; + job->scale = scale; job->target_width = width; job->target_height = height; - job->selection_style = selection_style; - job->text = *text; - job->base = *base; - job->include_forms = include_forms; - job->include_links = include_links; - job->include_images = include_images; - job->include_text = include_text; - job->include_selection = include_selection; - - if (include_selection) - job->selection_points = *selection_points; + job->flags = flags; if (EV_IS_ASYNC_RENDERER (document)) { EV_JOB (job)->async = TRUE; @@ -314,6 +295,21 @@ ev_job_render_new (EvDocument *document, return EV_JOB (job); } +void +ev_job_render_set_selection_info (EvJobRender *job, + EvRectangle *selection_points, + EvSelectionStyle selection_style, + GdkColor *text, + GdkColor *base) +{ + job->flags |= EV_RENDER_INCLUDE_SELECTION; + + job->selection_points = *selection_points; + job->selection_style = selection_style; + job->text = *text; + job->base = *base; +} + static void render_finished_cb (EvDocument *document, GdkPixbuf *pixbuf, @@ -322,7 +318,6 @@ render_finished_cb (EvDocument *document, g_signal_handlers_disconnect_by_func (EV_JOB (job)->document, render_finished_cb, job); - /* FIXME: ps backend should be ported to cairo */ job->surface = ev_document_misc_surface_from_pixbuf (pixbuf); job->page_ready = TRUE; g_signal_emit (job, job_render_signals[PAGE_READY], 0); @@ -357,17 +352,23 @@ ev_job_render_run (EvJobRender *job) if (EV_JOB (job)->async) { EvAsyncRenderer *renderer = EV_ASYNC_RENDERER (EV_JOB (job)->document); - ev_async_renderer_render_pixbuf (renderer, job->rc->page->index, job->rc->scale, - job->rc->rotation); + ev_async_renderer_render_pixbuf (renderer, job->page, job->scale, + job->rotation); g_signal_connect (EV_JOB (job)->document, "render_finished", G_CALLBACK (render_finished_cb), job); } else { + EvRenderContext *rc; + ev_document_fc_mutex_lock (); + + job->ev_page = ev_document_get_page (EV_JOB (job)->document, job->page); + + rc = ev_render_context_new (job->ev_page, job->rotation, job->scale); - job->surface = ev_document_render (EV_JOB (job)->document, job->rc); - if (job->include_selection && EV_IS_SELECTION (EV_JOB (job)->document)) { + job->surface = ev_document_render (EV_JOB (job)->document, rc); + if ((job->flags & EV_RENDER_INCLUDE_SELECTION) && EV_IS_SELECTION (EV_JOB (job)->document)) { ev_selection_render_selection (EV_SELECTION (EV_JOB (job)->document), - job->rc, + rc, &(job->selection), &(job->selection_points), NULL, @@ -375,7 +376,7 @@ ev_job_render_run (EvJobRender *job) &(job->text), &(job->base)); job->selection_region = ev_selection_get_selection_region (EV_SELECTION (EV_JOB (job)->document), - job->rc, + rc, job->selection_style, &(job->selection_points)); } @@ -384,22 +385,22 @@ ev_job_render_run (EvJobRender *job) ev_document_fc_mutex_unlock (); - if (job->include_text && EV_IS_SELECTION (EV_JOB (job)->document)) + if ((job->flags & EV_RENDER_INCLUDE_TEXT) && EV_IS_SELECTION (EV_JOB (job)->document)) job->text_mapping = - ev_selection_get_selection_map (EV_SELECTION (EV_JOB (job)->document), - job->rc); - if (job->include_links && EV_IS_DOCUMENT_LINKS (EV_JOB (job)->document)) + ev_selection_get_selection_map (EV_SELECTION (EV_JOB (job)->document), rc); + if ((job->flags & EV_RENDER_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (EV_JOB (job)->document)) job->link_mapping = - ev_document_links_get_links (EV_DOCUMENT_LINKS (EV_JOB (job)->document), - job->rc->page->index); - if (job->include_forms && EV_IS_DOCUMENT_FORMS (EV_JOB (job)->document)) + ev_document_links_get_links (EV_DOCUMENT_LINKS (EV_JOB (job)->document), job->page); + if ((job->flags & EV_RENDER_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (EV_JOB (job)->document)) job->form_field_mapping = ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (EV_JOB (job)->document), - job->rc->page); - if (job->include_images && EV_IS_DOCUMENT_IMAGES (EV_JOB (job)->document)) + job->ev_page); + if ((job->flags & EV_RENDER_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (EV_JOB (job)->document)) job->image_mapping = ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (EV_JOB (job)->document), - job->rc->page->index); + job->page); + g_object_unref (rc); + EV_JOB (job)->finished = TRUE; } diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index 1647154..c63a32c 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -123,11 +123,25 @@ struct _EvJobLinksClass EvJobClass parent_class; }; +typedef enum { + EV_RENDER_INCLUDE_NONE = 0, + EV_RENDER_INCLUDE_LINKS = 1 << 0, + EV_RENDER_INCLUDE_TEXT = 1 << 1, + EV_RENDER_INCLUDE_SELECTION = 1 << 2, + EV_RENDER_INCLUDE_IMAGES = 1 << 3, + EV_RENDER_INCLUDE_FORMS = 1 << 4, + EV_RENDER_INCLUDE_ALL = (1 << 5) - 1 +} EvRenderFlags; + struct _EvJobRender { EvJob parent; - EvRenderContext *rc; + gint page; + gint rotation; + gdouble scale; + + EvPage *ev_page; gboolean page_ready; gint target_width; gint target_height; @@ -145,11 +159,7 @@ struct _EvJobRender GdkColor base; GdkColor text; - gint include_forms : 1; - gint include_links : 1; - gint include_text : 1; - gint include_selection : 1; - gint include_images : 1; + EvRenderFlags flags; }; struct _EvJobRenderClass @@ -251,18 +261,17 @@ void ev_job_links_run (EvJobLinks *thumbnail); /* EvJobRender */ GType ev_job_render_get_type (void) G_GNUC_CONST; EvJob *ev_job_render_new (EvDocument *document, - EvRenderContext *rc, + gint page, + gint rotation, + gdouble scale, gint width, gint height, + EvRenderFlags flags); +void ev_job_render_set_selection_info (EvJobRender *job, EvRectangle *selection_points, EvSelectionStyle selection_style, GdkColor *text, - GdkColor *base, - gboolean include_forms, - gboolean include_links, - gboolean include_images, - gboolean include_text, - gboolean include_selection); + GdkColor *base); void ev_job_render_run (EvJobRender *thumbnail); /* EvJobThumbnail */ diff --git a/shell/ev-pixbuf-cache.c b/shell/ev-pixbuf-cache.c index 4710dfe..25b6f2c 100644 --- a/shell/ev-pixbuf-cache.c +++ b/shell/ev-pixbuf-cache.c @@ -250,13 +250,13 @@ job_page_ready_cb (EvJob *job, EvJobRender *job_render = EV_JOB_RENDER (job); /* If the job is outside of our interest, we silently discard it */ - if ((job_render->rc->page->index < (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size)) || - (job_render->rc->page->index > (pixbuf_cache->end_page + pixbuf_cache->preload_cache_size))) { + if ((job_render->page < (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size)) || + (job_render->page > (pixbuf_cache->end_page + pixbuf_cache->preload_cache_size))) { g_object_unref (job); return; } - job_info = find_job_cache (pixbuf_cache, job_render->rc->page->index); + job_info = find_job_cache (pixbuf_cache, job_render->page); copy_job_page_and_selection_to_job_info (job_render, job_info, pixbuf_cache); g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region); @@ -270,13 +270,13 @@ job_finished_cb (EvJob *job, EvJobRender *job_render = EV_JOB_RENDER (job); /* If the job is outside of our interest, we silently discard it */ - if ((job_render->rc->page->index < (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size)) || - (job_render->rc->page->index > (pixbuf_cache->end_page + pixbuf_cache->preload_cache_size))) { + if ((job_render->page < (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size)) || + (job_render->page > (pixbuf_cache->end_page + pixbuf_cache->preload_cache_size))) { g_object_unref (job); return; } - job_info = find_job_cache (pixbuf_cache, job_render->rc->page->index); + job_info = find_job_cache (pixbuf_cache, job_render->page); copy_job_to_job_info (job_render, job_info, pixbuf_cache); } @@ -298,8 +298,8 @@ check_job_size_and_unref (EvPixbufCache *pixbuf_cache, return; ev_page_cache_get_size (page_cache, - EV_JOB_RENDER (job_info->job)->rc->page->index, - EV_JOB_RENDER (job_info->job)->rc->rotation, + EV_JOB_RENDER (job_info->job)->page, + EV_JOB_RENDER (job_info->job)->rotation, scale, &width, &height); @@ -454,18 +454,23 @@ copy_job_page_and_selection_to_job_info (EvJobRender *job_render, CacheJobInfo *job_info, EvPixbufCache *pixbuf_cache) { + if (job_info->rc == NULL) { + job_info->rc = ev_render_context_new (job_render->ev_page, + job_render->rotation, + job_render->scale); + } else { + ev_render_context_set_page (job_info->rc, job_render->ev_page); + ev_render_context_set_rotation (job_info->rc, job_render->rotation); + ev_render_context_set_scale (job_info->rc, job_render->scale); + } + if (job_info->surface) { cairo_surface_destroy (job_info->surface); } job_info->surface = cairo_surface_reference (job_render->surface); - if (job_info->rc) { - g_object_unref (G_OBJECT (job_info->rc)); - } - job_info->rc = g_object_ref (job_render->rc); - job_info->points_set = FALSE; - if (job_render->include_selection) { + if (job_render->flags & EV_RENDER_INCLUDE_SELECTION) { if (job_info->selection) { cairo_surface_destroy (job_info->selection); job_info->selection = NULL; @@ -496,25 +501,25 @@ copy_job_to_job_info (EvJobRender *job_render, CacheJobInfo *job_info, EvPixbufCache *pixbuf_cache) { - if (job_render->include_links) { + if (job_render->flags & EV_RENDER_INCLUDE_LINKS) { if (job_info->link_mapping) ev_link_mapping_free (job_info->link_mapping); job_info->link_mapping = job_render->link_mapping; } - if (job_render->include_images) { + if (job_render->flags & EV_RENDER_INCLUDE_IMAGES) { if (job_info->image_mapping) ev_image_mapping_free (job_info->image_mapping); job_info->image_mapping = job_render->image_mapping; } - if (job_render->include_forms) { + if (job_render->flags & EV_RENDER_INCLUDE_FORMS) { if (job_info->form_field_mapping) ev_form_field_mapping_free (job_info->form_field_mapping); job_info->form_field_mapping = job_render->form_field_mapping; } - if (job_render->include_text) { + if (job_render->flags & EV_RENDER_INCLUDE_TEXT) { if (job_info->text_mapping) gdk_region_destroy (job_info->text_mapping); job_info->text_mapping = job_render->text_mapping; @@ -608,63 +613,40 @@ add_job (EvPixbufCache *pixbuf_cache, gfloat scale, EvJobPriority priority) { - EvPage *ev_page; - gboolean include_links = FALSE; - gboolean include_text = FALSE; - gboolean include_selection = FALSE; - gboolean include_images = FALSE; - gboolean include_forms = FALSE; - GdkColor *text, *base; + EvRenderFlags flags = 0; job_info->page_ready = FALSE; - /* FIXME: we shouldn't lock here */ - ev_document_doc_mutex_lock (); - ev_page = ev_document_get_page (pixbuf_cache->document, page); - ev_document_doc_mutex_unlock (); - - if (job_info->rc == NULL) { - job_info->rc = ev_render_context_new (ev_page, rotation, scale); - } else { - ev_render_context_set_page (job_info->rc, ev_page); - ev_render_context_set_rotation (job_info->rc, rotation); - ev_render_context_set_scale (job_info->rc, scale); - } - - g_object_unref (ev_page); - if (job_info->region) gdk_region_destroy (job_info->region); job_info->region = region ? gdk_region_copy (region) : NULL; /* Figure out what else we need for this job */ if (job_info->link_mapping == NULL) - include_links = TRUE; + flags |= EV_RENDER_INCLUDE_LINKS; if (job_info->image_mapping == NULL) - include_images = TRUE; + flags |= EV_RENDER_INCLUDE_IMAGES; if (job_info->form_field_mapping == NULL) - include_forms = TRUE; + flags |= EV_RENDER_INCLUDE_FORMS; if (job_info->text_mapping == NULL) - include_text = TRUE; - if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) { - include_selection = TRUE; - } - - gtk_widget_ensure_style (pixbuf_cache->view); - - get_selection_colors (pixbuf_cache->view, &text, &base); + flags |= EV_RENDER_INCLUDE_TEXT; job_info->job = ev_job_render_new (pixbuf_cache->document, - job_info->rc, + page, rotation, scale, width, height, - &(job_info->target_points), - job_info->selection_style, - text, base, - include_forms, - include_links, - include_images, - include_text, - include_selection); + flags); + + if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) { + GdkColor *text, *base; + + gtk_widget_ensure_style (pixbuf_cache->view); + get_selection_colors (pixbuf_cache->view, &text, &base); + ev_job_render_set_selection_info (EV_JOB_RENDER (job_info->job), + &(job_info->target_points), + job_info->selection_style, + text, base); + } + ev_job_queue_add_job (job_info->job, priority); g_signal_connect (G_OBJECT (job_info->job), "page-ready", G_CALLBACK (job_page_ready_cb), @@ -864,9 +846,9 @@ ev_pixbuf_cache_get_form_field_mapping (EvPixbufCache *pixbuf_cache, static gboolean new_selection_surface_needed (EvPixbufCache *pixbuf_cache, - CacheJobInfo *job_info, - gint page, - gfloat scale) + CacheJobInfo *job_info, + gint page, + gfloat scale) { EvPageCache *page_cache; @@ -1003,7 +985,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache, /* If we have a running job, we just return what we have under the * assumption that it'll be updated later and we can scale it as need * be */ - if (job_info->job && EV_JOB_RENDER (job_info->job)->include_selection) + if (job_info->job && (EV_JOB_RENDER (job_info->job)->flags & EV_RENDER_INCLUDE_SELECTION)) return job_info->selection; /* Now, lets see if we need to resize the image. If we do, we clear the -- cgit v0.9.1