Compare commits

..

No commits in common. "731e377b6e7fb6d61e1860b3936ddedac399f6db" and "17c9d088cc1765054b3e234c1a608c4f61d2d888" have entirely different histories.

7 changed files with 21 additions and 156 deletions

View File

@ -21,7 +21,7 @@
* @file gds-tree-checker.c * @file gds-tree-checker.c
* @brief Checking functions of a cell tree * @brief Checking functions of a cell tree
* *
* This file contains checking functions for the GDS cell tree. * This file contains cehcking functions for the GDS cell tree.
* These functions include checks if all child references could be resolved, * These functions include checks if all child references could be resolved,
* and if the cell tree contains loops. * and if the cell tree contains loops.
* *

View File

@ -106,14 +106,12 @@ const char *gds_output_renderer_get_output_file(GdsOutputRenderer *renderer);
* @brief Get layer settings * @brief Get layer settings
* *
* This is a convenience function for getting the * This is a convenience function for getting the
* "layer-settings" property. This also references it. * "layer-settings" property
* This is to prevent race conditions with another thread that might
* alter the layer settings before they are read out.
* *
* @param renderer Renderer * @param renderer Renderer
* @return Layer settings object * @return Layer settings object
*/ */
LayerSettings *gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer *renderer); LayerSettings *gds_output_renderer_get_layer_settings(GdsOutputRenderer *renderer);
/** /**
* @brief Set layer settings * @brief Set layer settings
@ -129,21 +127,6 @@ LayerSettings *gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer
*/ */
void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSettings *settings); void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSettings *settings);
/**
* @brief Render output asynchronously
*
* This function will render in a separate thread.
* To wait for the completion of the rendering process.
*
* @note A second async thread cannot be spawned.
*
* @param renderer Output renderer
* @param cell Cell to render
* @param scale Scale
* @return 0 if successful. In case no thread can be spawned < 0
*/
int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale);
G_END_DECLS G_END_DECLS
#endif /* _GDS_OUTPUT_RENDERER_H_ */ #endif /* _GDS_OUTPUT_RENDERER_H_ */

View File

@ -35,7 +35,6 @@ struct _ColorPalette {
/** @brief The length of the _ColorPalette::color_array array */ /** @brief The length of the _ColorPalette::color_array array */
unsigned int color_array_length; unsigned int color_array_length;
/* Dummy bytes to ensure ABI compatibility in future versions */
gpointer dummy[4]; gpointer dummy[4];
}; };
@ -117,8 +116,8 @@ static int color_palette_fill_with_resource(ColorPalette *palette, char *resourc
palette->color_array = (GdkRGBA *)malloc(sizeof(GdkRGBA) * (unsigned int)lines); palette->color_array = (GdkRGBA *)malloc(sizeof(GdkRGBA) * (unsigned int)lines);
/* Setup regex for hexadecimal RGB colors like 'A0CB3F' */ /* Setup regex for hexadecimal RGB colors like 'A0CB3F' */
regex = g_regex_new("^(?<red>[0-9A-Fa-f][0-9A-Fa-f])(?<green>[0-9A-Fa-f][0-9A-Fa-f])(?<blue>[0-9A-Fa-f][0-9A-Fa-f])$", regex = g_regex_new("^(?<red>[0-9A-Fa-f][0-9A-Fa-f])(?<green>[0-9A-Fa-f][0-9A-Fa-f])(?<blue>[0-9A-Fa-f][0-9A-Fa-f])$", 0, 0, NULL);
0, 0, NULL);
/* Reset line */ /* Reset line */
line_idx = 0; line_idx = 0;
@ -228,27 +227,11 @@ unsigned int color_palette_get_color_count(ColorPalette *palette)
return return_val; return return_val;
} }
static void color_palette_dispose(GObject *gobj)
{
ColorPalette *palette;
palette = GDS_RENDER_COLOR_PALETTE(gobj);
if (palette->color_array)
{
palette->color_array_length = 0;
free(palette->color_array);
}
/* Chain up to parent class */
G_OBJECT_CLASS(color_palette_parent_class)->dispose(gobj);
}
static void color_palette_class_init(ColorPaletteClass *klass) static void color_palette_class_init(ColorPaletteClass *klass)
{ {
GObjectClass *gclass; (void)klass;
/* Nothing to do for now */
gclass = G_OBJECT_CLASS(klass); return;
gclass->dispose = color_palette_dispose;
} }
static void color_palette_init(ColorPalette *self) static void color_palette_init(ColorPalette *self)

View File

@ -74,7 +74,7 @@ static void revert_inherited_transform(struct cairo_layer *layers)
* @param origin Origin translation * @param origin Origin translation
* @param magnification Scaling * @param magnification Scaling
* @param flipping Mirror image on x-axis before rotating * @param flipping Mirror image on x-axis before rotating
* @param rotation Rotation in degrees * @param rotation Rotattion in degrees
* @param scale Scale the image down by. Only used for sclaing origin coordinates. Not applied to layer. * @param scale Scale the image down by. Only used for sclaing origin coordinates. Not applied to layer.
*/ */
static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers, static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers,
@ -140,9 +140,7 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
/* Get layer renderer */ /* Get layer renderer */
if (gfx->layer >= MAX_LAYERS) if (gfx->layer >= MAX_LAYERS)
continue; continue;
if ((cr = layers[gfx->layer].cr) == NULL)
cr = layers[gfx->layer].cr;
if (cr == NULL)
continue; continue;
/* Apply settings */ /* Apply settings */
@ -169,6 +167,7 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
cairo_move_to(cr, vertex->x/scale, vertex->y/scale); cairo_move_to(cr, vertex->x/scale, vertex->y/scale);
else else
cairo_line_to(cr, vertex->x/scale, vertex->y/scale); cairo_line_to(cr, vertex->x/scale, vertex->y/scale);
} }
/* Create graphics object */ /* Create graphics object */
@ -184,7 +183,9 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
cairo_fill(cr); cairo_fill(cr);
break; break;
} }
} /* for gfx list */
}
} }
/** /**
@ -376,13 +377,12 @@ static int cairo_renderer_render_output(GdsOutputRenderer *renderer,
LayerSettings *settings; LayerSettings *settings;
GList *layer_infos = NULL; GList *layer_infos = NULL;
const char *output_file; const char *output_file;
int ret;
if (!c_renderer) if (!c_renderer)
return -2000; return -2000;
output_file = gds_output_renderer_get_output_file(renderer); output_file = gds_output_renderer_get_output_file(renderer);
settings = gds_output_renderer_get_and_ref_layer_settings(renderer); settings = gds_output_renderer_get_layer_settings(renderer);
/* Set layer info list. In case of failure it remains NULL */ /* Set layer info list. In case of failure it remains NULL */
if (settings) if (settings)
@ -393,12 +393,7 @@ static int cairo_renderer_render_output(GdsOutputRenderer *renderer,
else else
pdf_file = output_file; pdf_file = output_file;
ret = cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale); return cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale);
if (settings)
g_object_unref(settings);
return ret;
} }
static void cairo_renderer_class_init(CairoRendererClass *klass) static void cairo_renderer_class_init(CairoRendererClass *klass)

View File

@ -105,20 +105,15 @@ static int external_renderer_render_output(GdsOutputRenderer *renderer,
LayerSettings *settings; LayerSettings *settings;
GList *layer_infos = NULL; GList *layer_infos = NULL;
const char *output_file; const char *output_file;
int ret;
output_file = gds_output_renderer_get_output_file(renderer); output_file = gds_output_renderer_get_output_file(renderer);
settings = gds_output_renderer_get_and_ref_layer_settings(renderer); settings = gds_output_renderer_get_layer_settings(renderer);
/* Set layer info list. In case of failure it remains NULL */ /* Set layer info list. In case of failure it remains NULL */
if (settings) if (settings)
layer_infos = layer_settings_get_layer_info_list(settings); layer_infos = layer_settings_get_layer_info_list(settings);
ret = external_renderer_render_cell(cell, layer_infos, output_file, scale, ext_renderer->shared_object_path); return external_renderer_render_cell(cell, layer_infos, output_file, scale, ext_renderer->shared_object_path);
if (settings)
g_object_unref(settings);
return ret;
} }
static void external_renderer_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec) static void external_renderer_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec)

View File

@ -33,18 +33,9 @@
#include <gds-render/output-renderers/gds-output-renderer.h> #include <gds-render/output-renderers/gds-output-renderer.h>
#include <gds-render/layer/layer-info.h> #include <gds-render/layer/layer-info.h>
struct renderer_params {
struct gds_cell *cell;
double scale;
};
typedef struct { typedef struct {
gchar *output_file; gchar *output_file;
LayerSettings *layer_settings; LayerSettings *layer_settings;
GMutex settings_lock;
gboolean mutex_init_status;
GThread *thread;
struct renderer_params async_params;
gpointer padding[11]; gpointer padding[11];
} GdsOutputRendererPrivate; } GdsOutputRendererPrivate;
@ -56,9 +47,6 @@ 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 {THREAD_JOINED = 0, 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,
struct gds_cell *cell, struct gds_cell *cell,
double scale) double scale)
@ -77,15 +65,6 @@ static void gds_output_renderer_dispose(GObject *self_obj)
GdsOutputRendererPrivate *priv; GdsOutputRendererPrivate *priv;
priv = gds_output_renderer_get_instance_private(renderer); priv = gds_output_renderer_get_instance_private(renderer);
if (priv->mutex_init_status) {
/* Try locking the mutex, to test if it's free */
g_mutex_lock(&priv->settings_lock);
g_mutex_unlock(&priv->settings_lock);
g_mutex_clear(&priv->settings_lock);
priv->mutex_init_status = FALSE;
}
if (priv->output_file) if (priv->output_file)
g_free(priv->output_file); g_free(priv->output_file);
@ -124,18 +103,14 @@ static void gds_output_renderer_set_property(GObject *obj, guint property_id, co
switch (property_id) { switch (property_id) {
case PROP_OUTPUT_FILE: case PROP_OUTPUT_FILE:
g_mutex_lock(&priv->settings_lock);
if (priv->output_file) if (priv->output_file)
g_free(priv->output_file); g_free(priv->output_file);
priv->output_file = g_strdup(g_value_get_string(value)); priv->output_file = g_strdup(g_value_get_string(value));
g_mutex_unlock(&priv->settings_lock);
break; break;
case PROP_LAYER_SETTINGS: case PROP_LAYER_SETTINGS:
g_mutex_lock(&priv->settings_lock);
g_clear_object(&priv->layer_settings); g_clear_object(&priv->layer_settings);
priv->layer_settings = g_value_get_object(value); priv->layer_settings = g_value_get_object(value);
g_object_ref(priv->layer_settings); g_object_ref(priv->layer_settings);
g_mutex_unlock(&priv->settings_lock);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
@ -164,18 +139,6 @@ static void gds_output_renderer_class_init(GdsOutputRendererClass *klass)
"Object containing the layer rendering information", "Object containing the layer rendering information",
GDS_RENDER_TYPE_LAYER_SETTINGS, G_PARAM_READWRITE); GDS_RENDER_TYPE_LAYER_SETTINGS, G_PARAM_READWRITE);
g_object_class_install_properties(oclass, N_PROPERTIES, gds_output_renderer_properties); g_object_class_install_properties(oclass, N_PROPERTIES, gds_output_renderer_properties);
/* Setup output signals */
gds_output_renderer_signals[THREAD_JOINED] =
g_signal_newv("thread-joined", GDS_RENDER_TYPE_OUTPUT_RENDERER,
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
NULL,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0,
NULL);
} }
void gds_output_renderer_init(GdsOutputRenderer *self) void gds_output_renderer_init(GdsOutputRenderer *self)
@ -184,12 +147,7 @@ void gds_output_renderer_init(GdsOutputRenderer *self)
priv = gds_output_renderer_get_instance_private(self); priv = gds_output_renderer_get_instance_private(self);
priv->layer_settings = NULL;
priv->output_file = NULL; priv->output_file = NULL;
priv->thread = NULL;
priv->mutex_init_status = TRUE;
g_mutex_init(&priv->settings_lock);
return; return;
} }
@ -224,23 +182,11 @@ const char *gds_output_renderer_get_output_file(GdsOutputRenderer *renderer)
return file; return file;
} }
LayerSettings *gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer *renderer) LayerSettings *gds_output_renderer_get_layer_settings(GdsOutputRenderer *renderer)
{ {
LayerSettings *ret = NULL; LayerSettings *ret = NULL;
GdsOutputRendererPrivate *priv;
priv = gds_output_renderer_get_instance_private(renderer);
/* Acquire settings lock */
g_mutex_lock(&priv->settings_lock);
g_object_get(renderer, "layer-settings", &ret, NULL); g_object_get(renderer, "layer-settings", &ret, NULL);
/* Reference it, so it is not cleared by another thread overwriting the property */
g_object_ref(ret);
/* It is now safe to clear the lock */
g_mutex_unlock(&priv->settings_lock);
return ret; return ret;
} }
@ -253,7 +199,6 @@ void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSe
int gds_output_renderer_render_output(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale) int gds_output_renderer_render_output(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
{ {
int ret;
GdsOutputRendererClass *klass; GdsOutputRendererClass *klass;
GdsOutputRendererPrivate *priv = gds_output_renderer_get_instance_private(renderer); GdsOutputRendererPrivate *priv = gds_output_renderer_get_instance_private(renderer);
@ -283,40 +228,8 @@ int gds_output_renderer_render_output(GdsOutputRenderer *renderer, struct gds_ce
return GDS_OUTPUT_RENDERER_GEN_ERR; return GDS_OUTPUT_RENDERER_GEN_ERR;
} }
ret = klass->render_output(renderer, cell, scale); return klass->render_output(renderer, cell, scale);
return ret;
} }
static int gds_output_renderer_async_wrapper(gpointer data)
{
GdsOutputRenderer *renderer;
GdsOutputRendererPrivate *priv;
int ret;
renderer = GDS_RENDER_OUTPUT_RENDERER(data);
priv = gds_output_renderer_get_instance_private(renderer);
if (!priv)
return -1000;
if(!priv->mutex_init_status)
return -1001;
g_mutex_lock(&priv->settings_lock);
ret = gds_output_renderer_render_output(renderer, priv->async_params.cell, priv->async_params.scale);
g_mutex_unlock(&priv->settings_lock);
return ret;
}
int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
{
GdsOutputRendererPrivate *priv;
int ret = -1;
priv = gds_output_renderer_get_instance_private(renderer);
return ret;
}
/** @} */ /** @} */

View File

@ -335,7 +335,7 @@ static int latex_renderer_render_output(GdsOutputRenderer *renderer,
const char *output_file; const char *output_file;
output_file = gds_output_renderer_get_output_file(renderer); output_file = gds_output_renderer_get_output_file(renderer);
settings = gds_output_renderer_get_and_ref_layer_settings(renderer); settings = gds_output_renderer_get_layer_settings(renderer);
/* Set layer info list. In case of failure it remains NULL */ /* Set layer info list. In case of failure it remains NULL */
if (settings) if (settings)
@ -350,10 +350,6 @@ static int latex_renderer_render_output(GdsOutputRenderer *renderer,
g_error("Could not open LaTeX output file"); g_error("Could not open LaTeX output file");
} }
if (settings) {
g_object_unref(settings);
}
return ret; return ret;
} }