From a5fa286732b08b832ea642347963cb0456c1e19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 9 Jul 2019 11:13:09 +0200 Subject: [PATCH 01/28] cogl: Use autopointers to free structs on return This is a potential leak discovered by static analysis, in fact if _COGL_GET_CONTEXT returns, the newly allocated struct isn't released. https://gitlab.gnome.org/GNOME/mutter/merge_requests/682 --- cogl/cogl-pango/cogl-pango-fontmap.c | 4 ++-- cogl/cogl/cogl-onscreen.c | 4 +++- cogl/cogl/cogl-pipeline-cache.c | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cogl/cogl-pango/cogl-pango-fontmap.c b/cogl/cogl-pango/cogl-pango-fontmap.c index 145f3b9e8..3ec64eee6 100644 --- a/cogl/cogl-pango/cogl-pango-fontmap.c +++ b/cogl/cogl-pango/cogl-pango-fontmap.c @@ -49,72 +49,72 @@ #include #include "cogl-pango.h" #include "cogl-pango-private.h" #include "cogl-util.h" #include "cogl/cogl-context-private.h" static GQuark cogl_pango_font_map_get_priv_key (void) G_GNUC_CONST; typedef struct _CoglPangoFontMapPriv { CoglContext *ctx; PangoRenderer *renderer; } CoglPangoFontMapPriv; static void free_priv (gpointer data) { CoglPangoFontMapPriv *priv = data; cogl_object_unref (priv->ctx); cogl_object_unref (priv->renderer); g_free (priv); } PangoFontMap * cogl_pango_font_map_new (void) { PangoFontMap *fm = pango_cairo_font_map_new (); - CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1); + g_autofree CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1); _COGL_GET_CONTEXT (context, NULL); priv->ctx = cogl_object_ref (context); /* XXX: The public pango api doesn't let us sub-class * PangoCairoFontMap so we attach our own private data using qdata * for now. */ g_object_set_qdata_full (G_OBJECT (fm), cogl_pango_font_map_get_priv_key (), - priv, + g_steal_pointer (&priv), free_priv); return fm; } PangoContext * cogl_pango_font_map_create_context (CoglPangoFontMap *fm) { _COGL_RETURN_VAL_IF_FAIL (COGL_PANGO_IS_FONT_MAP (fm), NULL); #if PANGO_VERSION_CHECK (1, 22, 0) /* We can just directly use the pango context from the Cairo font map */ return pango_font_map_create_context (PANGO_FONT_MAP (fm)); #else return pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fm)); #endif } static CoglPangoFontMapPriv * _cogl_pango_font_map_get_priv (CoglPangoFontMap *fm) { return g_object_get_qdata (G_OBJECT (fm), cogl_pango_font_map_get_priv_key ()); } PangoRenderer * _cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm) { CoglPangoFontMapPriv *priv = _cogl_pango_font_map_get_priv (fm); diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index e766e59d0..fcf7f4168 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -72,64 +72,66 @@ COGL_GTYPE_DEFINE_BOXED (FrameClosure, frame_closure, cogl_dummy_free); COGL_GTYPE_DEFINE_BOXED (OnscreenResizeClosure, onscreen_resize_closure, cogl_dummy_copy, cogl_dummy_free); COGL_GTYPE_DEFINE_BOXED (OnscreenDirtyClosure, onscreen_dirty_closure, cogl_dummy_copy, cogl_dummy_free); static void _cogl_onscreen_init_from_template (CoglOnscreen *onscreen, CoglOnscreenTemplate *onscreen_template) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); _cogl_list_init (&onscreen->frame_closures); _cogl_list_init (&onscreen->resize_closures); _cogl_list_init (&onscreen->dirty_closures); framebuffer->config = onscreen_template->config; cogl_object_ref (framebuffer->config.swap_chain); } /* XXX: While we still have backend in Clutter we need a dummy object * to represent the CoglOnscreen framebuffer that the backend * creates... */ CoglOnscreen * _cogl_onscreen_new (void) { - CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1); + g_autofree CoglOnscreen *onscreen_ptr = g_new0 (CoglOnscreen, 1); + CoglOnscreen *onscreen; _COGL_GET_CONTEXT (ctx, NULL); + onscreen = g_steal_pointer (&onscreen_ptr); _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen), ctx, COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0x1eadbeef, /* width */ 0x1eadbeef); /* height */ /* NB: make sure to pass positive width/height numbers here * because otherwise we'll hit input validation assertions!*/ _cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template); COGL_FRAMEBUFFER (onscreen)->allocated = TRUE; /* XXX: Note we don't initialize onscreen->winsys in this case. */ return _cogl_onscreen_object_new (onscreen); } CoglOnscreen * cogl_onscreen_new (CoglContext *ctx, int width, int height) { CoglOnscreen *onscreen; /* FIXME: We are assuming onscreen buffers will always be premultiplied so we'll set the premult flag on the bitmap format. This will usually be correct because the result of the default blending operations for Cogl ends up with premultiplied data in the framebuffer. However it is possible for the framebuffer to be in whatever format depending on what CoglPipeline is used to render to it. Eventually we may want to add a way for an application to inform Cogl that the framebuffer diff --git a/cogl/cogl/cogl-pipeline-cache.c b/cogl/cogl/cogl-pipeline-cache.c index 62b372406..4267d2ccb 100644 --- a/cogl/cogl/cogl-pipeline-cache.c +++ b/cogl/cogl/cogl-pipeline-cache.c @@ -25,91 +25,91 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * * Authors: * Neil Roberts * Robert Bragg */ #ifdef HAVE_CONFIG_H #include "cogl-config.h" #endif #include #include "cogl-context-private.h" #include "cogl-pipeline-private.h" #include "cogl-pipeline-cache.h" #include "cogl-pipeline-hash-table.h" struct _CoglPipelineCache { CoglPipelineHashTable fragment_hash; CoglPipelineHashTable vertex_hash; CoglPipelineHashTable combined_hash; }; CoglPipelineCache * _cogl_pipeline_cache_new (void) { - CoglPipelineCache *cache = g_new (CoglPipelineCache, 1); + g_autofree CoglPipelineCache *cache = g_new (CoglPipelineCache, 1); unsigned long vertex_state; unsigned long layer_vertex_state; unsigned int fragment_state; unsigned int layer_fragment_state; _COGL_GET_CONTEXT (ctx, 0); vertex_state = _cogl_pipeline_get_state_for_vertex_codegen (ctx); layer_vertex_state = COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN; fragment_state = _cogl_pipeline_get_state_for_fragment_codegen (ctx); layer_fragment_state = _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx); _cogl_pipeline_hash_table_init (&cache->vertex_hash, vertex_state, layer_vertex_state, "vertex shaders"); _cogl_pipeline_hash_table_init (&cache->fragment_hash, fragment_state, layer_fragment_state, "fragment shaders"); _cogl_pipeline_hash_table_init (&cache->combined_hash, vertex_state | fragment_state, layer_vertex_state | layer_fragment_state, "programs"); - return cache; + return g_steal_pointer (&cache); } void _cogl_pipeline_cache_free (CoglPipelineCache *cache) { _cogl_pipeline_hash_table_destroy (&cache->fragment_hash); _cogl_pipeline_hash_table_destroy (&cache->vertex_hash); _cogl_pipeline_hash_table_destroy (&cache->combined_hash); g_free (cache); } CoglPipelineCacheEntry * _cogl_pipeline_cache_get_fragment_template (CoglPipelineCache *cache, CoglPipeline *key_pipeline) { return _cogl_pipeline_hash_table_get (&cache->fragment_hash, key_pipeline); } CoglPipelineCacheEntry * _cogl_pipeline_cache_get_vertex_template (CoglPipelineCache *cache, CoglPipeline *key_pipeline) { return _cogl_pipeline_hash_table_get (&cache->vertex_hash, key_pipeline); } CoglPipelineCacheEntry * _cogl_pipeline_cache_get_combined_template (CoglPipelineCache *cache, CoglPipeline *key_pipeline) -- 2.26.2