From 7eda2f82ee66cec9988338e17da5d6fba42451ed Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Wed, 3 Jun 2020 16:39:31 +0100 Subject: [PATCH] Tmp fix #397: GPU acceleration https://github.com/BestImageViewer/geeqie/issues/397 This is a quick-fix just to provide something that works. For that reason some code is merely commented out rather than removed. The code must be re-written to remove deprecated functions and to use clutter effects where appropriate. --- src/preferences.c | 2 +- src/renderer-clutter.c | 278 ++++++++++++++++++++++++++--------------- 2 files changed, 181 insertions(+), 99 deletions(-) diff --git a/src/preferences.c b/src/preferences.c index 040537e4..e298cc8b 100644 --- a/src/preferences.c +++ b/src/preferences.c @@ -2184,7 +2184,7 @@ static void config_tab_image(GtkWidget *notebook) add_quality_menu(table, 0, 0, _("Quality:"), options->image.zoom_quality, &c_options->image.zoom_quality); #ifdef HAVE_CLUTTER - pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library"), + pref_checkbox_new_int(group, _("Use GPU acceleration via Clutter library (Requires restart)"), options->image.use_clutter_renderer, &c_options->image.use_clutter_renderer); #endif diff --git a/src/renderer-clutter.c b/src/renderer-clutter.c index e0fd9590..6b9bd198 100644 --- a/src/renderer-clutter.c +++ b/src/renderer-clutter.c @@ -115,6 +115,8 @@ struct _RendererClutter gboolean clut_updated; gint64 last_pixbuf_change; + + GdkPixbuf *display_pixbuf; }; typedef struct _RendererClutterAreaParam RendererClutterAreaParam; @@ -215,73 +217,75 @@ static void rc_prepare_post_process_lut(RendererClutter *rc) CoglHandle material; CoglHandle tex3d; - DEBUG_3("%s clut start", get_exec_time()); - - for (r = 0; r < CLUT_SIZE; r++) - { - for (g = 0; g < CLUT_SIZE; g++) - { - for (b = 0; b < CLUT_SIZE; b++) - { - guchar *ptr = clut + ((b * CLUT_SIZE + g) * CLUT_SIZE + r) * 3; - ptr[0] = floor ((double) r / (CLUT_SIZE - 1) * 255.0 + 0.5); - ptr[1] = floor ((double) g / (CLUT_SIZE - 1) * 255.0 + 0.5); - ptr[2] = floor ((double) b / (CLUT_SIZE - 1) * 255.0 + 0.5); - } - } - } - tmp_pixbuf = gdk_pixbuf_new_from_data(clut, GDK_COLORSPACE_RGB, FALSE, 8, - CLUT_SIZE * CLUT_SIZE, - CLUT_SIZE, - CLUT_SIZE * CLUT_SIZE * 3, - NULL, NULL); - if (pr->func_post_process) - { - pr->func_post_process(pr, &tmp_pixbuf, 0, 0, CLUT_SIZE * CLUT_SIZE, CLUT_SIZE, pr->post_process_user_data); - } - g_object_unref(tmp_pixbuf); - - DEBUG_3("%s clut upload start", get_exec_time()); -#if COGL_VERSION_CHECK(1,18,2) - { - CoglContext *ctx = clutter_backend_get_cogl_context(clutter_get_default_backend ()); - - tex3d = cogl_texture_3d_new_from_data(ctx, - CLUT_SIZE, CLUT_SIZE, CLUT_SIZE, - COGL_PIXEL_FORMAT_RGB_888, - CLUT_SIZE * 3, - CLUT_SIZE * CLUT_SIZE * 3, - clut, - NULL); - } -#elif COGL_VERSION_CHECK(1,10,4) - { - CoglContext *ctx = clutter_backend_get_cogl_context(clutter_get_default_backend ()); - - tex3d = cogl_texture_3d_new_from_data(ctx, - CLUT_SIZE, CLUT_SIZE, CLUT_SIZE, - COGL_PIXEL_FORMAT_RGB_888, - COGL_PIXEL_FORMAT_RGB_888, - CLUT_SIZE * 3, - CLUT_SIZE * CLUT_SIZE * 3, - clut, - NULL); - } -#else - tex3d = cogl_texture_3d_new_from_data(CLUT_SIZE, CLUT_SIZE, CLUT_SIZE, - COGL_TEXTURE_NONE, - COGL_PIXEL_FORMAT_RGB_888, - COGL_PIXEL_FORMAT_RGB_888, - CLUT_SIZE * 3, - CLUT_SIZE * CLUT_SIZE * 3, - clut, - NULL); -#endif - material = clutter_texture_get_cogl_material(CLUTTER_TEXTURE(rc->texture)); - cogl_material_set_layer(material, 1, tex3d); - cogl_handle_unref(tex3d); - DEBUG_3("%s clut end", get_exec_time()); - rc->clut_updated = TRUE; + return; //FIXME + + //~ DEBUG_3("%s clut start", get_exec_time()); + + //~ for (r = 0; r < CLUT_SIZE; r++) + //~ { + //~ for (g = 0; g < CLUT_SIZE; g++) + //~ { + //~ for (b = 0; b < CLUT_SIZE; b++) + //~ { + //~ guchar *ptr = clut + ((b * CLUT_SIZE + g) * CLUT_SIZE + r) * 3; + //~ ptr[0] = floor ((double) r / (CLUT_SIZE - 1) * 255.0 + 0.5); + //~ ptr[1] = floor ((double) g / (CLUT_SIZE - 1) * 255.0 + 0.5); + //~ ptr[2] = floor ((double) b / (CLUT_SIZE - 1) * 255.0 + 0.5); + //~ } + //~ } + //~ } + //~ tmp_pixbuf = gdk_pixbuf_new_from_data(clut, GDK_COLORSPACE_RGB, FALSE, 8, + //~ CLUT_SIZE * CLUT_SIZE, + //~ CLUT_SIZE, + //~ CLUT_SIZE * CLUT_SIZE * 3, + //~ NULL, NULL); + //~ if (pr->func_post_process) + //~ { + //~ pr->func_post_process(pr, &tmp_pixbuf, 0, 0, CLUT_SIZE * CLUT_SIZE, CLUT_SIZE, pr->post_process_user_data); + //~ } + //~ g_object_unref(tmp_pixbuf); + + //~ DEBUG_3("%s clut upload start", get_exec_time()); +//~ #if COGL_VERSION_CHECK(1,18,2) + //~ { + //~ CoglContext *ctx = clutter_backend_get_cogl_context(clutter_get_default_backend ()); + + //~ tex3d = cogl_texture_3d_new_from_data(ctx, + //~ CLUT_SIZE, CLUT_SIZE, CLUT_SIZE, + //~ COGL_PIXEL_FORMAT_RGB_888, + //~ CLUT_SIZE * 3, + //~ CLUT_SIZE * CLUT_SIZE * 3, + //~ clut, + //~ NULL); + //~ } +//~ #elif COGL_VERSION_CHECK(1,10,4) + //~ { + //~ CoglContext *ctx = clutter_backend_get_cogl_context(clutter_get_default_backend ()); + + //~ tex3d = cogl_texture_3d_new_from_data(ctx, + //~ CLUT_SIZE, CLUT_SIZE, CLUT_SIZE, + //~ COGL_PIXEL_FORMAT_RGB_888, + //~ COGL_PIXEL_FORMAT_RGB_888, + //~ CLUT_SIZE * 3, + //~ CLUT_SIZE * CLUT_SIZE * 3, + //~ clut, + //~ NULL); + //~ } +//~ #else + //~ tex3d = cogl_texture_3d_new_from_data(CLUT_SIZE, CLUT_SIZE, CLUT_SIZE, + //~ COGL_TEXTURE_NONE, + //~ COGL_PIXEL_FORMAT_RGB_888, + //~ COGL_PIXEL_FORMAT_RGB_888, + //~ CLUT_SIZE * 3, + //~ CLUT_SIZE * CLUT_SIZE * 3, + //~ clut, + //~ NULL); +//~ #endif + //~ material = clutter_texture_get_cogl_material(CLUTTER_TEXTURE(rc->texture)); + //~ cogl_material_set_layer(material, 1, tex3d); + //~ cogl_handle_unref(tex3d); + //~ DEBUG_3("%s clut end", get_exec_time()); + //~ rc->clut_updated = TRUE; } @@ -412,6 +416,8 @@ static void rc_schedule_texture_upload(RendererClutter *rc) } } +static void update_display_pixbuf(RendererClutter *rc); + static gboolean rc_area_changed_cb(gpointer data) { RendererClutter *rc = (RendererClutter *)data; @@ -423,6 +429,12 @@ static gboolean rc_area_changed_cb(gpointer data) if (h == 0) h = 1; if (h > par->h) h = par->h; + update_display_pixbuf(rc); + + if (pr->func_post_process) + { + pr->func_post_process(pr, &rc->display_pixbuf, 0, 0, gdk_pixbuf_get_width(pr->pixbuf), gdk_pixbuf_get_height(pr->pixbuf), pr->post_process_user_data); + } DEBUG_3("%s upload start", get_exec_time()); if (pr->pixbuf) @@ -438,9 +450,9 @@ static gboolean rc_area_changed_cb(gpointer data) h, par->w, h, - gdk_pixbuf_get_has_alpha(pr->pixbuf) ? COGL_PIXEL_FORMAT_BGRA_8888 : COGL_PIXEL_FORMAT_BGR_888, + gdk_pixbuf_get_has_alpha(pr->pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_rowstride(pr->pixbuf), - gdk_pixbuf_get_pixels(pr->pixbuf)); + gdk_pixbuf_get_pixels(rc->display_pixbuf)); } DEBUG_3("%s upload end", get_exec_time()); rc_area_clip_add(rc, par->x, par->y, par->w, h); @@ -514,6 +526,63 @@ static void rc_remove_pending_updates(RendererClutter *rc) } } +static void update_display_pixbuf(RendererClutter *rc) +{ + PixbufRenderer *pr = rc->pr; + GdkPixbuf* tmppixbuf = NULL; + + if (pr->pixbuf) + { + if (rc->display_pixbuf) + { + g_object_unref(rc->display_pixbuf); + } + + if (!gdk_pixbuf_get_has_alpha(pr->pixbuf)) + { + rc->display_pixbuf = gdk_pixbuf_copy(pr->pixbuf); + } + else + { + if (pr->ignore_alpha) + { + tmppixbuf = gdk_pixbuf_add_alpha(pr->pixbuf, FALSE, 0, 0, 0); + + pixbuf_ignore_alpha_rect(tmppixbuf, 0, 0, gdk_pixbuf_get_width(pr->pixbuf), gdk_pixbuf_get_height(pr->pixbuf)); + + rc->display_pixbuf = gdk_pixbuf_composite_color_simple (tmppixbuf, + gdk_pixbuf_get_width(pr->pixbuf), + gdk_pixbuf_get_height(pr->pixbuf), + GDK_INTERP_HYPER, + 255, + PR_ALPHA_CHECK_SIZE, + ((options->image.alpha_color_1.red << 8 & 0x00FF0000) + + (options->image.alpha_color_1.green & 0x00FF00) + + (options->image.alpha_color_1.blue >> 8 & 0x00FF)), + ((options->image.alpha_color_2.red << 8 & 0x00FF0000) + + (options->image.alpha_color_2.green & 0x00FF00) + + (options->image.alpha_color_2.blue >> 8 & 0x00FF))); + g_object_unref(tmppixbuf); + } + else + { + rc->display_pixbuf = gdk_pixbuf_composite_color_simple (pr->pixbuf, + gdk_pixbuf_get_width(pr->pixbuf), + gdk_pixbuf_get_height(pr->pixbuf), + GDK_INTERP_HYPER, + 255, + PR_ALPHA_CHECK_SIZE, + ((options->image.alpha_color_1.red << 8 & 0x00FF0000) + + (options->image.alpha_color_1.green & 0x00FF00) + + (options->image.alpha_color_1.blue >> 8 & 0x00FF)), + ((options->image.alpha_color_2.red << 8 & 0x00FF0000) + + (options->image.alpha_color_2.green & 0x00FF00) + + (options->image.alpha_color_2.blue >> 8 & 0x00FF))); + } + } + } +} + static void rc_update_pixbuf(void *renderer, gboolean lazy) { RendererClutter *rc = (RendererClutter *)renderer; @@ -521,6 +590,7 @@ static void rc_update_pixbuf(void *renderer, gboolean lazy) DEBUG_3("rc_update_pixbuf"); + update_display_pixbuf(rc); rc_remove_pending_updates(rc); rc->last_pixbuf_change = g_get_monotonic_time(); @@ -528,43 +598,48 @@ static void rc_update_pixbuf(void *renderer, gboolean lazy) if (pr->pixbuf) { - gint width = gdk_pixbuf_get_width(pr->pixbuf); - gint height = gdk_pixbuf_get_height(pr->pixbuf); + if (pr->func_post_process) + { + pr->func_post_process(pr, &rc->display_pixbuf, 0, 0, gdk_pixbuf_get_width(pr->pixbuf), gdk_pixbuf_get_height(pr->pixbuf), pr->post_process_user_data); + } - DEBUG_3("pixbuf size %d x %d (%d)", width, height, gdk_pixbuf_get_has_alpha(pr->pixbuf) ? 32 : 24); + gint width = gdk_pixbuf_get_width(pr->pixbuf); + gint height = gdk_pixbuf_get_height(pr->pixbuf); - gint prev_width, prev_height; + DEBUG_3("pixbuf size %d x %d (%d)", width, height, gdk_pixbuf_get_has_alpha(pr->pixbuf) ? 32 : 24); - if (pr->stereo_data == STEREO_PIXBUF_SBS || pr->stereo_data == STEREO_PIXBUF_CROSS) - { - width /= 2; - } + gint prev_width, prev_height; + if (pr->stereo_data == STEREO_PIXBUF_SBS || pr->stereo_data == STEREO_PIXBUF_CROSS) + { + width /= 2; + } - clutter_texture_get_base_size(CLUTTER_TEXTURE(rc->texture), &prev_width, &prev_height); - if (width != prev_width || height != prev_height) - { - /* FIXME use CoglMaterial with multiple textures for background, color management, anaglyph, ... */ - CoglHandle texture = cogl_texture_new_with_size(width, - height, - COGL_TEXTURE_NO_AUTO_MIPMAP | COGL_TEXTURE_NO_SLICING, - gdk_pixbuf_get_has_alpha(pr->pixbuf) ? COGL_PIXEL_FORMAT_BGRA_8888 : COGL_PIXEL_FORMAT_BGR_888); + clutter_texture_get_base_size(CLUTTER_TEXTURE(rc->texture), &prev_width, &prev_height); - if (texture != COGL_INVALID_HANDLE) + if (width != prev_width || height != prev_height) { - clutter_texture_set_cogl_texture(CLUTTER_TEXTURE(rc->texture), texture); - cogl_handle_unref(texture); + /* FIXME use CoglMaterial with multiple textures for background, color management, anaglyph, ... */ + CoglHandle texture = cogl_texture_new_with_size(width, + height, + COGL_TEXTURE_NO_AUTO_MIPMAP, + gdk_pixbuf_get_has_alpha(pr->pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888); + + if (texture != COGL_INVALID_HANDLE) + { + clutter_texture_set_cogl_texture(CLUTTER_TEXTURE(rc->texture), texture); + cogl_handle_unref(texture); + } + } + clutter_actor_set_clip(rc->texture, 0, 0, 0, 0); /* visible area is extended as area_changed events arrive */ + if (!lazy) + { + rc_area_changed(renderer, GET_RIGHT_PIXBUF_OFFSET(rc), 0, width, height); } - } - clutter_actor_set_clip(rc->texture, 0, 0, 0, 0); /* visible area is extended as area_changed events arrive */ - if (!lazy) - { - rc_area_changed(renderer, GET_RIGHT_PIXBUF_OFFSET(rc), 0, width, height); - } - } - rc->clut_updated = FALSE; + rc->clut_updated = FALSE; + } } @@ -742,7 +817,7 @@ static gboolean rc_overlay_get(void *renderer, gint id, GdkPixbuf **pixbuf, gint static void rc_update_viewport(void *renderer) { RendererClutter *rc = (RendererClutter *)renderer; - ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; + ClutterColor stage_color = { rc->pr->color.red / 256, rc->pr->color.green / 256, rc->pr->color.blue / 256, 0xff }; rc->stereo_off_x = 0; rc->stereo_off_y = 0; @@ -813,6 +888,11 @@ static void rc_free(void *renderer) RendererClutter *rc = (RendererClutter *)renderer; GtkWidget *widget = gtk_bin_get_child(GTK_BIN(rc->pr)); + if (rc->display_pixbuf) + { + g_object_unref(rc->display_pixbuf); + } + rc_remove_pending_updates(rc); rc_overlay_free_all(rc); @@ -876,6 +956,8 @@ RendererFuncs *renderer_clutter_new(PixbufRenderer *pr) rc->idle_update = 0; rc->pending_updates = NULL; + rc->display_pixbuf = NULL; + rc->widget = gtk_bin_get_child(GTK_BIN(rc->pr)); if (rc->widget) @@ -903,7 +985,7 @@ RendererFuncs *renderer_clutter_new(PixbufRenderer *pr) rc->texture = clutter_texture_new (); clutter_container_add_actor(CLUTTER_CONTAINER(rc->group), rc->texture); - renderer_clutter_init_checker_shader(rc); + //~ renderer_clutter_init_checker_shader(rc); //FIXME g_object_ref(G_OBJECT(rc->widget)); gtk_widget_show(rc->widget); -- 2.20.1