Compare commits

..

No commits in common. "a10c09c674642fce7dba31ca3b0c92792a5e4701" and "32b8c4ccd35d621eb0d42adb233eade3be5a1c28" have entirely different histories.

5 changed files with 11 additions and 124 deletions

View File

@ -293,15 +293,6 @@ static void async_rendering_finished_callback(GdsOutputRenderer *renderer, gpoin
g_object_unref(renderer); g_object_unref(renderer);
} }
static void async_rendering_status_update_callback(GdsOutputRenderer *renderer, const char *status_message, gpointer data)
{
GdsRenderGui *gui;
(void)renderer;
gui = RENDERER_GUI(data);
activity_bar_set_busy(gui->activity_status_bar, status_message);
}
/** /**
* @brief Convert button callback * @brief Convert button callback
* @param button * @param button
@ -435,9 +426,6 @@ static void on_convert_clicked(gpointer button, gpointer user)
activity_bar_set_busy(self->activity_status_bar, "Rendering cell..."); activity_bar_set_busy(self->activity_status_bar, "Rendering cell...");
/* TODO: Replace this with asynchronous rendering. However, this fixes issue #19 */ /* TODO: Replace this with asynchronous rendering. However, this fixes issue #19 */
g_signal_connect(render_engine, "progress-changed",
G_CALLBACK(async_rendering_status_update_callback), self);
gds_output_renderer_render_output_async(render_engine, cell_to_render, sett->scale); gds_output_renderer_render_output_async(render_engine, cell_to_render, sett->scale);

View File

@ -144,16 +144,6 @@ void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSe
*/ */
int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale); int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale);
/**
* @brief This function emits the 'progress-changed' in the thread/context that triggered an asynchronous rendering
*
* If the rendering is not asynchronous, this function has no effect.
*
* @param renderer GdsOutputrenderer object
* @param status Status to supply to signal emission
*/
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status);
G_END_DECLS G_END_DECLS
#endif /* _GDS_OUTPUT_RENDERER_H_ */ #endif /* _GDS_OUTPUT_RENDERER_H_ */

View File

@ -400,7 +400,6 @@ static int cairo_renderer_render_output(GdsOutputRenderer *renderer,
else else
pdf_file = output_file; pdf_file = output_file;
gds_output_renderer_update_gui_status_from_async(renderer, "Rendering Cairo Output...");
ret = cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale); ret = cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale);
if (settings) if (settings)

View File

@ -38,20 +38,13 @@ struct renderer_params {
double scale; double scale;
}; };
struct idle_function_params {
GMutex message_lock;
char *status_message;
};
typedef struct { typedef struct {
gchar *output_file; gchar *output_file;
LayerSettings *layer_settings; LayerSettings *layer_settings;
GMutex settings_lock; GMutex settings_lock;
gboolean mutex_init_status; gboolean mutex_init_status;
GTask *task; GTask *task;
GMainContext *main_context;
struct renderer_params async_params; struct renderer_params async_params;
struct idle_function_params idle_function_parameters;
gpointer padding[11]; gpointer padding[11];
} GdsOutputRendererPrivate; } GdsOutputRendererPrivate;
@ -63,7 +56,7 @@ enum {
G_DEFINE_TYPE_WITH_PRIVATE(GdsOutputRenderer, gds_output_renderer, G_TYPE_OBJECT) G_DEFINE_TYPE_WITH_PRIVATE(GdsOutputRenderer, gds_output_renderer, G_TYPE_OBJECT)
enum gds_output_renderer_signal_ids {ASYNC_FINISHED = 0, ASYNC_PROGRESS_CHANGED, GDS_OUTPUT_RENDERER_SIGNAL_COUNT}; enum gds_output_renderer_signal_ids {ASYNC_FINISHED = 0, ASYNC_PROGRESS_UPDATE, GDS_OUTPUT_RENDERER_SIGNAL_COUNT};
static guint gds_output_renderer_signals[GDS_OUTPUT_RENDERER_SIGNAL_COUNT]; static guint gds_output_renderer_signals[GDS_OUTPUT_RENDERER_SIGNAL_COUNT];
static int gds_output_renderer_render_dummy(GdsOutputRenderer *renderer, static int gds_output_renderer_render_dummy(GdsOutputRenderer *renderer,
@ -90,11 +83,6 @@ static void gds_output_renderer_dispose(GObject *self_obj)
g_mutex_lock(&priv->settings_lock); g_mutex_lock(&priv->settings_lock);
g_mutex_unlock(&priv->settings_lock); g_mutex_unlock(&priv->settings_lock);
g_mutex_clear(&priv->settings_lock); g_mutex_clear(&priv->settings_lock);
g_mutex_lock(&priv->idle_function_parameters.message_lock);
g_mutex_unlock(&priv->idle_function_parameters.message_lock);
g_mutex_clear(&priv->idle_function_parameters.message_lock);
priv->mutex_init_status = FALSE; priv->mutex_init_status = FALSE;
} }
@ -162,7 +150,6 @@ static GParamSpec *gds_output_renderer_properties[N_PROPERTIES] = {NULL};
static void gds_output_renderer_class_init(GdsOutputRendererClass *klass) static void gds_output_renderer_class_init(GdsOutputRendererClass *klass)
{ {
GObjectClass *oclass = G_OBJECT_CLASS(klass); GObjectClass *oclass = G_OBJECT_CLASS(klass);
GType progress_changed_param_types[1] = {G_TYPE_POINTER};
klass->render_output = gds_output_renderer_render_dummy; klass->render_output = gds_output_renderer_render_dummy;
@ -170,7 +157,6 @@ static void gds_output_renderer_class_init(GdsOutputRendererClass *klass)
oclass->set_property = gds_output_renderer_set_property; oclass->set_property = gds_output_renderer_set_property;
oclass->get_property = gds_output_renderer_get_property; oclass->get_property = gds_output_renderer_get_property;
/* Setup properties */ /* Setup properties */
gds_output_renderer_properties[PROP_OUTPUT_FILE] = gds_output_renderer_properties[PROP_OUTPUT_FILE] =
g_param_spec_string("output-file", "output file", "Output file for renderer", g_param_spec_string("output-file", "output file", "Output file for renderer",
@ -192,16 +178,16 @@ static void gds_output_renderer_class_init(GdsOutputRendererClass *klass)
G_TYPE_NONE, G_TYPE_NONE,
0, 0,
NULL); NULL);
gds_output_renderer_signals[ASYNC_PROGRESS_CHANGED] = gds_output_renderer_signals[ASYNC_PROGRESS_UPDATE] =
g_signal_newv("progress-changed", GDS_RENDER_TYPE_OUTPUT_RENDERER, g_signal_newv("progress-update", GDS_RENDER_TYPE_OUTPUT_RENDERER,
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
G_TYPE_NONE, G_TYPE_NONE,
1, 0,
progress_changed_param_types); NULL);
} }
void gds_output_renderer_init(GdsOutputRenderer *self) void gds_output_renderer_init(GdsOutputRenderer *self)
@ -214,10 +200,7 @@ void gds_output_renderer_init(GdsOutputRenderer *self)
priv->output_file = NULL; priv->output_file = NULL;
priv->task = NULL; priv->task = NULL;
priv->mutex_init_status = TRUE; priv->mutex_init_status = TRUE;
priv->main_context = NULL;
priv->idle_function_parameters.status_message = NULL;
g_mutex_init(&priv->settings_lock); g_mutex_init(&priv->settings_lock);
g_mutex_init(&priv->idle_function_parameters.message_lock);
return; return;
} }
@ -351,13 +334,8 @@ static void gds_output_renderer_async_finished(GObject *src_obj, GAsyncResult *r
priv = gds_output_renderer_get_instance_private(GDS_RENDER_OUTPUT_RENDERER(src_obj)); priv = gds_output_renderer_get_instance_private(GDS_RENDER_OUTPUT_RENDERER(src_obj));
priv->main_context = NULL;
g_signal_emit(src_obj, gds_output_renderer_signals[ASYNC_FINISHED], 0); g_signal_emit(src_obj, gds_output_renderer_signals[ASYNC_FINISHED], 0);
g_clear_object(&priv->task); g_clear_object(&priv->task);
/* Clear reference set in gds_output_renderer_render_output_async() */
g_object_unref(src_obj);
} }
int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale) int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
@ -375,73 +353,11 @@ int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct
g_mutex_lock(&priv->settings_lock); g_mutex_lock(&priv->settings_lock);
priv->async_params.cell = cell; priv->async_params.cell = cell;
priv->async_params.scale = scale; priv->async_params.scale = scale;
priv->main_context = g_main_context_default();
g_mutex_unlock(&priv->settings_lock); g_mutex_unlock(&priv->settings_lock);
/* Self reference. This could end up being nasty... */
g_object_ref(renderer);
/* Do the magic */
g_task_run_in_thread(priv->task, gds_output_renderer_async_wrapper); g_task_run_in_thread(priv->task, gds_output_renderer_async_wrapper);
return ret; return ret;
} }
static gboolean idle_event_processor_callback(gpointer user_data)
{
GdsOutputRenderer *renderer;
GdsOutputRendererPrivate *priv;
char *status_message;
/* If the rendering is finished before the mainloop gets to this point
* the renderer is already disposed. Catch this!
*/
if (!GDS_RENDER_IS_OUTPUT_RENDERER(user_data))
return FALSE;
renderer = GDS_RENDER_OUTPUT_RENDERER(user_data);
priv = gds_output_renderer_get_instance_private(renderer);
if (g_mutex_trylock(&priv->idle_function_parameters.message_lock)) {
status_message = priv->idle_function_parameters.status_message;
g_signal_emit(renderer, gds_output_renderer_signals[ASYNC_PROGRESS_CHANGED], 0, status_message);
g_free(priv->idle_function_parameters.status_message);
priv->idle_function_parameters.status_message = NULL;
g_mutex_unlock(&priv->idle_function_parameters.message_lock);
} else {
return TRUE;
}
return FALSE;
}
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status)
{
GSource *idle_event_processor;
GdsOutputRendererPrivate *priv;
g_return_if_fail(GDS_RENDER_IS_OUTPUT_RENDERER(renderer));
if (!status)
return;
priv = gds_output_renderer_get_instance_private(renderer);
/* If rendering is not async */
if (!priv->main_context)
return;
g_mutex_lock(&priv->idle_function_parameters.message_lock);
if (priv->idle_function_parameters.status_message)
g_free(priv->idle_function_parameters.status_message);
priv->idle_function_parameters.status_message = g_strdup(status);
g_mutex_unlock(&priv->idle_function_parameters.message_lock);
idle_event_processor = g_idle_source_new();
g_source_set_callback(idle_event_processor, idle_event_processor_callback, (gpointer)renderer, NULL);
g_source_attach(idle_event_processor, priv->main_context);
}
/** @} */ /** @} */

View File

@ -227,18 +227,12 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
* @param buffer Working buffer * @param buffer Working buffer
* @param scale Scale output down by this value * @param scale Scale output down by this value
*/ */
static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer, double scale, static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer, double scale)
GdsOutputRenderer *renderer)
{ {
GString *status;
GList *list_child; GList *list_child;
struct gds_cell_instance *inst; struct gds_cell_instance *inst;
status = g_string_new(NULL);
g_string_printf(status, "Generating cell %s", cell->name);
gds_output_renderer_update_gui_status_from_async(renderer, status->str);
g_string_free(status, TRUE);
/* Draw polygons of current cell */ /* Draw polygons of current cell */
generate_graphics(tex_file, cell->graphic_objs, layer_infos, buffer, scale); generate_graphics(tex_file, cell->graphic_objs, layer_infos, buffer, scale);
@ -262,7 +256,7 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
inst->magnification); inst->magnification);
WRITEOUT_BUFFER(buffer); WRITEOUT_BUFFER(buffer);
render_cell(inst->cell_ref, layer_infos, tex_file, buffer, scale, renderer); render_cell(inst->cell_ref, layer_infos, tex_file, buffer, scale);
g_string_printf(buffer, "\\end{scope}\n"); g_string_printf(buffer, "\\end{scope}\n");
WRITEOUT_BUFFER(buffer); WRITEOUT_BUFFER(buffer);
@ -277,7 +271,7 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
} }
static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale, static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
gboolean create_pdf_layers, gboolean standalone_document, GdsOutputRenderer *renderer) gboolean create_pdf_layers, gboolean standalone_document)
{ {
GString *working_line; GString *working_line;
@ -310,7 +304,7 @@ static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos,
WRITEOUT_BUFFER(working_line); WRITEOUT_BUFFER(working_line);
/* Generate graphics output */ /* Generate graphics output */
render_cell(cell, layer_infos, tex_file, working_line, scale, renderer); render_cell(cell, layer_infos, tex_file, working_line, scale);
g_string_printf(working_line, "\\end{tikzpicture}\n"); g_string_printf(working_line, "\\end{tikzpicture}\n");
@ -350,7 +344,7 @@ static int latex_renderer_render_output(GdsOutputRenderer *renderer,
tex_file = fopen(output_file, "w"); tex_file = fopen(output_file, "w");
if (tex_file) { if (tex_file) {
ret = latex_render_cell_to_code(cell, layer_infos, tex_file, scale, ret = latex_render_cell_to_code(cell, layer_infos, tex_file, scale,
l_renderer->pdf_layers, l_renderer->tex_standalone, renderer); l_renderer->pdf_layers, l_renderer->tex_standalone);
fclose(tex_file); fclose(tex_file);
} else { } else {
g_error("Could not open LaTeX output file"); g_error("Could not open LaTeX output file");