From 1da42dc3c0cb80b4f08655cbacc55095158a607c Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Thu, 17 Aug 2023 12:08:32 +0200 Subject: [PATCH] cogl: Port Context away from CoglObject Part-of: --- cogl/cogl-pango/cogl-pango-fontmap.c | 4 +- cogl/cogl-pango/cogl-pango-pipeline-cache.c | 4 +- cogl/cogl-pango/cogl-pango-render.c | 20 +- cogl/cogl/cogl-attribute.c | 2 +- cogl/cogl/cogl-bitmap.c | 12 +- cogl/cogl/cogl-context-private.h | 2 +- cogl/cogl/cogl-context.c | 211 ++++++++++---------- cogl/cogl/cogl-context.h | 29 +-- cogl/cogl/cogl-framebuffer.c | 14 +- 9 files changed, 147 insertions(+), 151 deletions(-) diff --git a/cogl/cogl-pango/cogl-pango-fontmap.c b/cogl/cogl-pango/cogl-pango-fontmap.c index 7a9f43675..086c9b7f5 100644 --- a/cogl/cogl-pango/cogl-pango-fontmap.c +++ b/cogl/cogl-pango/cogl-pango-fontmap.c @@ -56,7 +56,7 @@ free_priv (gpointer data) { CoglPangoFontMapPriv *priv = data; - cogl_object_unref (priv->ctx); + g_object_unref (priv->ctx); g_object_unref (priv->renderer); g_free (priv); @@ -70,7 +70,7 @@ cogl_pango_font_map_new (void) _COGL_GET_CONTEXT (context, NULL); - priv->ctx = cogl_object_ref (context); + priv->ctx = g_object_ref (context); /* XXX: The public pango api doesn't let us sub-class * PangoCairoFontMap so we attach our own private data using qdata diff --git a/cogl/cogl-pango/cogl-pango-pipeline-cache.c b/cogl/cogl-pango/cogl-pango-pipeline-cache.c index eb31e4c01..0aa7e0db8 100644 --- a/cogl/cogl-pango/cogl-pango-pipeline-cache.c +++ b/cogl/cogl-pango/cogl-pango-pipeline-cache.c @@ -78,7 +78,7 @@ _cogl_pango_pipeline_cache_new (CoglContext *ctx, { CoglPangoPipelineCache *cache = g_new (CoglPangoPipelineCache, 1); - cache->ctx = cogl_object_ref (ctx); + cache->ctx = g_object_ref (ctx); /* The key is the pipeline pointer. A reference is taken when the pipeline is used as a key so we should unref it again in the @@ -234,7 +234,7 @@ _cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache) g_hash_table_destroy (cache->hash_table); - cogl_object_unref (cache->ctx); + g_object_unref (cache->ctx); g_free (cache); } diff --git a/cogl/cogl-pango/cogl-pango-render.c b/cogl/cogl-pango/cogl-pango-render.c index 937bd00b8..0e96822a1 100644 --- a/cogl/cogl-pango/cogl-pango-render.c +++ b/cogl/cogl-pango/cogl-pango-render.c @@ -238,18 +238,17 @@ _cogl_pango_renderer_constructed (GObject *gobject) } static void -cogl_pango_renderer_set_property (GObject *object, - unsigned int prop_id, +cogl_pango_renderer_set_property (GObject *object, + unsigned int prop_id, const GValue *value, - GParamSpec *pspec) + GParamSpec *pspec) { CoglPangoRenderer *renderer = COGL_PANGO_RENDERER (object); switch (prop_id) { case PROP_COGL_CONTEXT: - renderer->ctx = g_value_get_pointer (value); - cogl_object_ref (renderer->ctx); + renderer->ctx = g_value_get_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -269,10 +268,11 @@ cogl_pango_renderer_class_init (CoglPangoRendererClass *klass) object_class->dispose = cogl_pango_renderer_dispose; object_class->finalize = cogl_pango_renderer_finalize; - pspec = g_param_spec_pointer ("context", NULL, NULL, - G_PARAM_WRITABLE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); + pspec = g_param_spec_object ("context", NULL, NULL, + COGL_TYPE_CONTEXT, + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_COGL_CONTEXT, pspec); @@ -286,7 +286,7 @@ cogl_pango_renderer_dispose (GObject *object) { CoglPangoRenderer *priv = COGL_PANGO_RENDERER (object); - cogl_clear_object (&priv->ctx); + g_clear_object (&priv->ctx); G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->dispose (object); } diff --git a/cogl/cogl/cogl-attribute.c b/cogl/cogl/cogl-attribute.c index 363c6ff19..b3f6e92d4 100644 --- a/cogl/cogl/cogl-attribute.c +++ b/cogl/cogl/cogl-attribute.c @@ -259,7 +259,7 @@ _cogl_attribute_new_const (CoglContext *context, attribute->is_buffered = FALSE; attribute->normalized = FALSE; - attribute->d.constant.context = cogl_object_ref (context); + attribute->d.constant.context = g_object_ref (context); attribute->d.constant.boxed.v.array = NULL; diff --git a/cogl/cogl/cogl-bitmap.c b/cogl/cogl/cogl-bitmap.c index 4f1d7442f..d55bab833 100644 --- a/cogl/cogl/cogl-bitmap.c +++ b/cogl/cogl/cogl-bitmap.c @@ -166,16 +166,16 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, } CoglBitmap * -cogl_bitmap_new_for_data (CoglContext *context, - int width, - int height, +cogl_bitmap_new_for_data (CoglContext *context, + int width, + int height, CoglPixelFormat format, - int rowstride, - uint8_t *data) + int rowstride, + uint8_t *data) { CoglBitmap *bmp; - g_return_val_if_fail (cogl_is_context (context), NULL); + g_return_val_if_fail (COGL_IS_CONTEXT (context), NULL); g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); /* Rowstride from width if not given */ diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h index 502dda72b..40f40ff0d 100644 --- a/cogl/cogl/cogl-context-private.h +++ b/cogl/cogl/cogl-context-private.h @@ -68,7 +68,7 @@ struct _CoglTimestampQuery struct _CoglContext { - CoglObject _parent; + GObject parent_instance; CoglDisplay *display; diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index 915bef119..c397bdad9 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -53,22 +53,8 @@ #include #include -static void _cogl_context_free (CoglContext *context); +G_DEFINE_TYPE (CoglContext, cogl_context, G_TYPE_OBJECT); -COGL_OBJECT_DEFINE (Context, context); -COGL_GTYPE_DEFINE_CLASS (Context, context); - -extern void -_cogl_create_context_driver (CoglContext *context); - -static CoglContext *_cogl_context = NULL; - -static void -_cogl_init_feature_overrides (CoglContext *ctx) -{ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS))) - COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_PBOS, FALSE); -} const CoglWinsysVtable * _cogl_context_get_winsys (CoglContext *context) @@ -82,6 +68,109 @@ _cogl_context_get_driver (CoglContext *context) return context->driver_vtable; } +static void +cogl_context_dispose (GObject *object) +{ + CoglContext *context = COGL_CONTEXT (object); + const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); + const CoglDriverVtable *driver = _cogl_context_get_driver (context); + + winsys->context_deinit (context); + + if (context->default_gl_texture_2d_tex) + cogl_object_unref (context->default_gl_texture_2d_tex); + + if (context->opaque_color_pipeline) + cogl_object_unref (context->opaque_color_pipeline); + + if (context->blit_texture_pipeline) + cogl_object_unref (context->blit_texture_pipeline); + + if (context->swap_callback_closures) + g_hash_table_destroy (context->swap_callback_closures); + + if (context->journal_flush_attributes_array) + g_array_free (context->journal_flush_attributes_array, TRUE); + if (context->journal_clip_bounds) + g_array_free (context->journal_clip_bounds, TRUE); + + if (context->rectangle_byte_indices) + cogl_object_unref (context->rectangle_byte_indices); + if (context->rectangle_short_indices) + cogl_object_unref (context->rectangle_short_indices); + + if (context->default_pipeline) + cogl_object_unref (context->default_pipeline); + + if (context->dummy_layer_dependant) + cogl_object_unref (context->dummy_layer_dependant); + if (context->default_layer_n) + cogl_object_unref (context->default_layer_n); + if (context->default_layer_0) + cogl_object_unref (context->default_layer_0); + + if (context->current_clip_stack_valid) + _cogl_clip_stack_unref (context->current_clip_stack); + + g_slist_free (context->atlases); + g_hook_list_clear (&context->atlas_reorganize_callbacks); + + _cogl_bitmask_destroy (&context->enabled_custom_attributes); + _cogl_bitmask_destroy (&context->enable_custom_attributes_tmp); + _cogl_bitmask_destroy (&context->changed_bits_tmp); + + if (context->current_modelview_entry) + cogl_matrix_entry_unref (context->current_modelview_entry); + if (context->current_projection_entry) + cogl_matrix_entry_unref (context->current_projection_entry); + + _cogl_pipeline_cache_free (context->pipeline_cache); + + _cogl_sampler_cache_free (context->sampler_cache); + + g_ptr_array_free (context->uniform_names, TRUE); + g_hash_table_destroy (context->uniform_name_hash); + + g_hash_table_destroy (context->attribute_name_states_hash); + g_array_free (context->attribute_name_index_map, TRUE); + + g_byte_array_free (context->buffer_map_fallback_array, TRUE); + + driver->context_deinit (context); + + g_object_unref (context->display); + + g_hash_table_remove_all (context->named_pipelines); + g_hash_table_destroy (context->named_pipelines); + + G_OBJECT_CLASS (cogl_context_parent_class)->dispose (object); +} + +static void +cogl_context_init (CoglContext *info) +{ +} + +static void +cogl_context_class_init (CoglContextClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = cogl_context_dispose; +} + +extern void +_cogl_create_context_driver (CoglContext *context); + +static CoglContext *_cogl_context = NULL; + +static void +_cogl_init_feature_overrides (CoglContext *ctx) +{ + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS))) + COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_PBOS, FALSE); +} + /* For reference: There was some deliberation over whether to have a * constructor that could throw an exception but looking at standard * practices with several high level OO languages including python, C++, @@ -120,12 +209,7 @@ cogl_context_new (CoglDisplay *display, #endif /* Allocate context memory */ - context = g_malloc0 (sizeof (CoglContext)); - - /* Convert the context into an object immediately in case any of the - code below wants to verify that the context pointer is a valid - object */ - _cogl_context_object_new (context); + context = g_object_new (COGL_TYPE_CONTEXT, NULL); /* XXX: Gross hack! * Currently everything in Cogl just assumes there is a default @@ -147,12 +231,12 @@ cogl_context_new (CoglDisplay *display, if (!cogl_renderer_connect (renderer, error)) { cogl_object_unref (renderer); - g_free (context); + g_object_unref (context); return NULL; } display = cogl_display_new (renderer, NULL); - cogl_object_unref(renderer); + cogl_object_unref (renderer); } else g_object_ref (display); @@ -160,7 +244,7 @@ cogl_context_new (CoglDisplay *display, if (!cogl_display_setup (display, error)) { g_object_unref (display); - g_free (context); + g_object_unref (context); return NULL; } @@ -190,7 +274,7 @@ cogl_context_new (CoglDisplay *display, if (!context->driver_vtable->context_init (context)) { g_object_unref (display); - g_free (context); + g_object_unref (context); g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to initialize context"); return NULL; @@ -323,83 +407,6 @@ cogl_context_new (CoglDisplay *display, return context; } -static void -_cogl_context_free (CoglContext *context) -{ - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - const CoglDriverVtable *driver = _cogl_context_get_driver (context); - - winsys->context_deinit (context); - - if (context->default_gl_texture_2d_tex) - cogl_object_unref (context->default_gl_texture_2d_tex); - - if (context->opaque_color_pipeline) - cogl_object_unref (context->opaque_color_pipeline); - - if (context->blit_texture_pipeline) - cogl_object_unref (context->blit_texture_pipeline); - - if (context->swap_callback_closures) - g_hash_table_destroy (context->swap_callback_closures); - - if (context->journal_flush_attributes_array) - g_array_free (context->journal_flush_attributes_array, TRUE); - if (context->journal_clip_bounds) - g_array_free (context->journal_clip_bounds, TRUE); - - if (context->rectangle_byte_indices) - cogl_object_unref (context->rectangle_byte_indices); - if (context->rectangle_short_indices) - cogl_object_unref (context->rectangle_short_indices); - - if (context->default_pipeline) - cogl_object_unref (context->default_pipeline); - - if (context->dummy_layer_dependant) - cogl_object_unref (context->dummy_layer_dependant); - if (context->default_layer_n) - cogl_object_unref (context->default_layer_n); - if (context->default_layer_0) - cogl_object_unref (context->default_layer_0); - - if (context->current_clip_stack_valid) - _cogl_clip_stack_unref (context->current_clip_stack); - - g_slist_free (context->atlases); - g_hook_list_clear (&context->atlas_reorganize_callbacks); - - _cogl_bitmask_destroy (&context->enabled_custom_attributes); - _cogl_bitmask_destroy (&context->enable_custom_attributes_tmp); - _cogl_bitmask_destroy (&context->changed_bits_tmp); - - if (context->current_modelview_entry) - cogl_matrix_entry_unref (context->current_modelview_entry); - if (context->current_projection_entry) - cogl_matrix_entry_unref (context->current_projection_entry); - - _cogl_pipeline_cache_free (context->pipeline_cache); - - _cogl_sampler_cache_free (context->sampler_cache); - - g_ptr_array_free (context->uniform_names, TRUE); - g_hash_table_destroy (context->uniform_name_hash); - - g_hash_table_destroy (context->attribute_name_states_hash); - g_array_free (context->attribute_name_index_map, TRUE); - - g_byte_array_free (context->buffer_map_fallback_array, TRUE); - - driver->context_deinit (context); - - g_object_unref (context->display); - - g_hash_table_remove_all (context->named_pipelines); - g_hash_table_destroy (context->named_pipelines); - - g_free (context); -} - CoglContext * _cogl_context_get_default (void) { diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h index 8ad691420..d36d596e5 100644 --- a/cogl/cogl/cogl-context.h +++ b/cogl/cogl/cogl-context.h @@ -52,8 +52,9 @@ typedef struct _CoglTimestampQuery CoglTimestampQuery; G_BEGIN_DECLS /** - * SECTION:cogl-context - * @short_description: The top level application context. + * CoglContext: + * + * The top level application context. * * A #CoglContext is the top most sandbox of Cogl state for an * application or toolkit. Its main purpose is to act as a sandbox @@ -93,15 +94,14 @@ G_BEGIN_DECLS * context. */ -#define COGL_CONTEXT(OBJECT) ((CoglContext *)OBJECT) +#define COGL_TYPE_CONTEXT (cogl_context_get_type ()) -/** - * cogl_context_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ COGL_EXPORT -GType cogl_context_get_gtype (void); +G_DECLARE_FINAL_TYPE (CoglContext, + cogl_context, + COGL, + CONTEXT, + GObject) /** * cogl_context_new: (constructor) (skip) @@ -150,17 +150,6 @@ cogl_context_get_display (CoglContext *context); COGL_EXPORT CoglRenderer * cogl_context_get_renderer (CoglContext *context); -/** - * cogl_is_context: - * @object: An object or %NULL - * - * Gets whether the given object references an existing context object. - * - * Return value: %TRUE if the @object references a #CoglContext, - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_is_context (void *object); /* XXX: not guarded by the EXPERIMENTAL_API defines to avoid * upsetting glib-mkenums, but this can still be considered implicitly diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c index 4c165bf1e..a8bf473c0 100644 --- a/cogl/cogl/cogl-framebuffer.c +++ b/cogl/cogl/cogl-framebuffer.c @@ -173,7 +173,7 @@ cogl_framebuffer_get_property (GObject *object, switch (prop_id) { case PROP_CONTEXT: - g_value_set_boxed (value, priv->context); + g_value_set_object (value, priv->context); break; case PROP_DRIVER_CONFIG: g_value_set_pointer (value, &priv->driver_config); @@ -203,7 +203,7 @@ cogl_framebuffer_set_property (GObject *object, switch (prop_id) { case PROP_CONTEXT: - priv->context = g_value_get_boxed (value); + priv->context = g_value_get_object (value); break; case PROP_DRIVER_CONFIG: driver_config = g_value_get_pointer (value); @@ -381,11 +381,11 @@ cogl_framebuffer_class_init (CoglFramebufferClass *klass) object_class->set_property = cogl_framebuffer_set_property; obj_props[PROP_CONTEXT] = - g_param_spec_boxed ("context", NULL, NULL, - COGL_TYPE_HANDLE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); + g_param_spec_object ("context", NULL, NULL, + COGL_TYPE_CONTEXT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); obj_props[PROP_DRIVER_CONFIG] = g_param_spec_pointer ("driver-config", NULL, NULL, G_PARAM_READWRITE |