From 55cd1534d09228f14bcea14848ef226b6d88edfd Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Mon, 16 Nov 2020 13:32:50 +0100 Subject: [PATCH 1/6] gtk(4): draw black before priv contexts are available --- ext/gtk/gtkgstglwidget.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c index 186144a1c..3d6fe05a2 100644 --- a/ext/gtk/gtkgstglwidget.c +++ b/ext/gtk/gtkgstglwidget.c @@ -225,6 +225,14 @@ _draw_black (GstGLContext * context) gl->Clear (GL_COLOR_BUFFER_BIT); } +static inline void +_draw_black_with_gdk (GdkGLContext * gdk_context) +{ + GST_DEBUG ("rendering empty frame with gdk context %p", gdk_context); + glClearColor (0.0, 0.0, 0.0, 1.0); + glClear (GL_COLOR_BUFFER_BIT); +} + static gboolean gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) { @@ -233,8 +241,13 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) GTK_GST_BASE_WIDGET_LOCK (widget); - if (!priv->context || !priv->other_context) + /* Draw black with GDK context when priv is not available yet. + GTK calls render with GDK context already active. */ + if (!priv->context || !priv->other_context) { + GdkGLContext *gdk_context = gtk_gl_area_get_context (widget); + _draw_black_with_gdk (gdk_context); goto done; + } gst_gl_context_activate (priv->other_context, TRUE); -- 2.26.2 From c477954dd41ff506b07fe89aa241769809efdeb8 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Mon, 16 Nov 2020 16:04:45 +0100 Subject: [PATCH 2/6] gtk(4): draw black when not initiated --- ext/gtk/gtkgstglwidget.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c index 3d6fe05a2..d1422f8bb 100644 --- a/ext/gtk/gtkgstglwidget.c +++ b/ext/gtk/gtkgstglwidget.c @@ -62,7 +62,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); struct _GtkGstGLWidgetPrivate { - gboolean initted; + gboolean initiated; GstGLDisplay *display; GdkGLContext *gdk_context; GstGLContext *other_context; @@ -159,7 +159,7 @@ gtk_gst_gl_widget_init_redisplay (GtkGstGLWidget * gst_widget) priv->overlay_compositor = gst_gl_overlay_compositor_new (priv->other_context); - priv->initted = TRUE; + priv->initiated = TRUE; } static void @@ -251,10 +251,10 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) gst_gl_context_activate (priv->other_context, TRUE); - if (!priv->initted) - gtk_gst_gl_widget_init_redisplay (GTK_GST_GL_WIDGET (widget)); + if (!priv->initiated || !base_widget->negotiated) { + if (!priv->initiated) + gtk_gst_gl_widget_init_redisplay (GTK_GST_GL_WIDGET (widget)); - if (!priv->initted || !base_widget->negotiated) { _draw_black (priv->other_context); goto done; } -- 2.26.2 From eb407306f30e13e7a6ada116e8b4b5812da67b72 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Mon, 16 Nov 2020 22:13:46 +0100 Subject: [PATCH 3/6] gtk(4): add ignore textures property for glsink --- ext/gtk/gstgtkbasesink.c | 18 ++++++++++++++++++ ext/gtk/gstgtkbasesink.h | 10 +++++++--- ext/gtk/gtkgstbasewidget.c | 14 ++++++++++++++ ext/gtk/gtkgstbasewidget.h | 1 + ext/gtk/gtkgstglwidget.c | 3 ++- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/ext/gtk/gstgtkbasesink.c b/ext/gtk/gstgtkbasesink.c index ea11bec40..666bbef54 100644 --- a/ext/gtk/gstgtkbasesink.c +++ b/ext/gtk/gstgtkbasesink.c @@ -39,6 +39,7 @@ GST_DEBUG_CATEGORY (gst_debug_gtk_base_sink); #define DEFAULT_PAR_N 0 #define DEFAULT_PAR_D 1 #define DEFAULT_IGNORE_ALPHA TRUE +#define DEFAULT_IGNORE_TEXTURES FALSE static void gst_gtk_base_sink_finalize (GObject * object); static void gst_gtk_base_sink_set_property (GObject * object, guint prop_id, @@ -70,6 +71,7 @@ enum PROP_FORCE_ASPECT_RATIO, PROP_PIXEL_ASPECT_RATIO, PROP_IGNORE_ALPHA, + PROP_IGNORE_TEXTURES, }; #define gst_gtk_base_sink_parent_class parent_class @@ -123,6 +125,11 @@ gst_gtk_base_sink_class_init (GstGtkBaseSinkClass * klass) DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #endif + g_object_class_install_property (gobject_class, PROP_IGNORE_TEXTURES, + g_param_spec_boolean ("ignore-textures", "Ignore Textures", + "When enabled, textures will be ignored and not drawn", + DEFAULT_IGNORE_TEXTURES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gobject_class->finalize = gst_gtk_base_sink_finalize; gstelement_class->change_state = gst_gtk_base_sink_change_state; @@ -143,6 +150,7 @@ gst_gtk_base_sink_init (GstGtkBaseSink * gtk_sink) gtk_sink->par_n = DEFAULT_PAR_N; gtk_sink->par_d = DEFAULT_PAR_D; gtk_sink->ignore_alpha = DEFAULT_IGNORE_ALPHA; + gtk_sink->ignore_textures = DEFAULT_IGNORE_TEXTURES; } static void @@ -202,6 +210,10 @@ gst_gtk_base_sink_get_widget (GstGtkBaseSink * gtk_sink) "ignore-alpha", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); #endif + gtk_sink->bind_ignore_textures = + g_object_bind_property (gtk_sink, "ignore-textures", gtk_sink->widget, + "ignore-textures", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + /* back pointer */ gtk_gst_base_widget_set_element (GTK_GST_BASE_WIDGET (gtk_sink->widget), GST_ELEMENT (gtk_sink)); @@ -242,6 +254,9 @@ gst_gtk_base_sink_get_property (GObject * object, guint prop_id, case PROP_IGNORE_ALPHA: g_value_set_boolean (value, gtk_sink->ignore_alpha); break; + case PROP_IGNORE_TEXTURES: + g_value_set_boolean (value, gtk_sink->ignore_textures); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -265,6 +280,9 @@ gst_gtk_base_sink_set_property (GObject * object, guint prop_id, case PROP_IGNORE_ALPHA: gtk_sink->ignore_alpha = g_value_get_boolean (value); break; + case PROP_IGNORE_TEXTURES: + gtk_sink->ignore_textures = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/ext/gtk/gstgtkbasesink.h b/ext/gtk/gstgtkbasesink.h index f2668fabc..a13729f7b 100644 --- a/ext/gtk/gstgtkbasesink.h +++ b/ext/gtk/gstgtkbasesink.h @@ -1,6 +1,7 @@ /* * GStreamer * Copyright (C) 2015 Matthew Waters + * Copyright (C) 2020 Rafał Dzięgiel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -61,13 +62,16 @@ struct _GstGtkBaseSink gboolean force_aspect_ratio; GBinding *bind_aspect_ratio; - gint par_n; - gint par_d; + gint par_n; + gint par_d; GBinding *bind_pixel_aspect_ratio; - gboolean ignore_alpha; + gboolean ignore_alpha; GBinding *bind_ignore_alpha; + gboolean ignore_textures; + GBinding *bind_ignore_textures; + GtkWidget *window; gulong window_destroy_id; }; diff --git a/ext/gtk/gtkgstbasewidget.c b/ext/gtk/gtkgstbasewidget.c index 5335478cb..91fc1105f 100644 --- a/ext/gtk/gtkgstbasewidget.c +++ b/ext/gtk/gtkgstbasewidget.c @@ -34,6 +34,7 @@ GST_DEBUG_CATEGORY (gst_debug_gtk_base_widget); #define DEFAULT_PAR_N 0 #define DEFAULT_PAR_D 1 #define DEFAULT_IGNORE_ALPHA TRUE +#define DEFAULT_IGNORE_TEXTURES FALSE enum { @@ -41,6 +42,7 @@ enum PROP_FORCE_ASPECT_RATIO, PROP_PIXEL_ASPECT_RATIO, PROP_IGNORE_ALPHA, + PROP_IGNORE_TEXTURES, }; static void @@ -108,6 +110,9 @@ gtk_gst_base_widget_set_property (GObject * object, guint prop_id, case PROP_IGNORE_ALPHA: gtk_widget->ignore_alpha = g_value_get_boolean (value); break; + case PROP_IGNORE_TEXTURES: + gtk_widget->ignore_textures = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -130,6 +135,9 @@ gtk_gst_base_widget_get_property (GObject * object, guint prop_id, case PROP_IGNORE_ALPHA: g_value_set_boolean (value, gtk_widget->ignore_alpha); break; + case PROP_IGNORE_TEXTURES: + g_value_set_boolean (value, gtk_widget->ignore_textures); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -468,6 +476,11 @@ gtk_gst_base_widget_class_init (GtkGstBaseWidgetClass * klass) "When enabled, alpha will be ignored and converted to black", DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_klass, PROP_IGNORE_TEXTURES, + g_param_spec_boolean ("ignore-textures", "Ignore Textures", + "When enabled, textures will be ignored and not drawn", + DEFAULT_IGNORE_TEXTURES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + #if defined(BUILD_FOR_GTK4) widget_klass->measure = gtk_gst_base_widget_measure; #else @@ -494,6 +507,7 @@ gtk_gst_base_widget_init (GtkGstBaseWidget * widget) widget->par_n = DEFAULT_PAR_N; widget->par_d = DEFAULT_PAR_D; widget->ignore_alpha = DEFAULT_IGNORE_ALPHA; + widget->ignore_textures = DEFAULT_IGNORE_TEXTURES; gst_video_info_init (&widget->v_info); gst_video_info_init (&widget->pending_v_info); diff --git a/ext/gtk/gtkgstbasewidget.h b/ext/gtk/gtkgstbasewidget.h index 640a1c742..651999a55 100644 --- a/ext/gtk/gtkgstbasewidget.h +++ b/ext/gtk/gtkgstbasewidget.h @@ -57,6 +57,7 @@ struct _GtkGstBaseWidget gint display_width; gint display_height; + gboolean ignore_textures; gboolean negotiated; GstBuffer *pending_buffer; GstBuffer *buffer; diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c index d1422f8bb..1553a5255 100644 --- a/ext/gtk/gtkgstglwidget.c +++ b/ext/gtk/gtkgstglwidget.c @@ -243,8 +243,9 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) /* Draw black with GDK context when priv is not available yet. GTK calls render with GDK context already active. */ - if (!priv->context || !priv->other_context) { + if (!priv->context || !priv->other_context || base_widget->ignore_textures) { GdkGLContext *gdk_context = gtk_gl_area_get_context (widget); + _draw_black_with_gdk (gdk_context); goto done; } -- 2.26.2 From ec8a37b4d7723af564d4e790ff38279c1e2ea531 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Tue, 17 Nov 2020 11:42:45 +0100 Subject: [PATCH 4/6] gtk(4): do not reconnect signal handlers when already connected --- ext/gtk/gstgtkglsink.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ext/gtk/gstgtkglsink.c b/ext/gtk/gstgtkglsink.c index 3b0059906..2c92f8574 100644 --- a/ext/gtk/gstgtkglsink.c +++ b/ext/gtk/gstgtkglsink.c @@ -186,15 +186,19 @@ gst_gtk_gl_sink_start (GstBaseSink * bsink) gst_widget = GTK_GST_GL_WIDGET (base_sink->widget); #if !defined(BUILD_FOR_GTK4) - /* Track the allocation size */ - gtk_sink->size_allocate_sig_handler = - g_signal_connect (gst_widget, "size-allocate", - G_CALLBACK (_size_changed_cb), gtk_sink); + if (!gtk_sink->size_allocate_sig_handler) { + /* Track the allocation size */ + gtk_sink->size_allocate_sig_handler = + g_signal_connect (gst_widget, "size-allocate", + G_CALLBACK (_size_changed_cb), gtk_sink); + } #endif - gtk_sink->widget_destroy_sig_handler = - g_signal_connect (gst_widget, "destroy", G_CALLBACK (destroy_cb), - gtk_sink); + if (!gtk_sink->widget_destroy_sig_handler) { + gtk_sink->widget_destroy_sig_handler = + g_signal_connect (gst_widget, "destroy", G_CALLBACK (destroy_cb), + gtk_sink); + } if (!gtk_gst_gl_widget_init_winsys (gst_widget)) { GST_ELEMENT_ERROR (bsink, RESOURCE, NOT_FOUND, ("%s", -- 2.26.2 From fe243f7bff2b223fcbeaf2171f47bc4fce0aff78 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Tue, 17 Nov 2020 11:44:06 +0100 Subject: [PATCH 5/6] gtk(4): use context passed to render vfunc for debug log --- ext/gtk/gtkgstglwidget.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c index 1553a5255..09d709091 100644 --- a/ext/gtk/gtkgstglwidget.c +++ b/ext/gtk/gtkgstglwidget.c @@ -220,7 +220,7 @@ _draw_black (GstGLContext * context) { const GstGLFuncs *gl = context->gl_vtable; - gst_gl_insert_debug_marker (context, "no buffer. rendering black"); + gst_gl_insert_debug_marker (context, "rendering black"); gl->ClearColor (0.0, 0.0, 0.0, 0.0); gl->Clear (GL_COLOR_BUFFER_BIT); } @@ -244,9 +244,8 @@ gtk_gst_gl_widget_render (GtkGLArea * widget, GdkGLContext * context) /* Draw black with GDK context when priv is not available yet. GTK calls render with GDK context already active. */ if (!priv->context || !priv->other_context || base_widget->ignore_textures) { - GdkGLContext *gdk_context = gtk_gl_area_get_context (widget); + _draw_black_with_gdk (context); - _draw_black_with_gdk (gdk_context); goto done; } -- 2.26.2 From 78945426ee3976dc75d6761fd67b756af33c0302 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Tue, 17 Nov 2020 13:16:38 +0100 Subject: [PATCH 6/6] gtk(4): always clear color to black --- ext/gtk/gtkgstglwidget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/gtk/gtkgstglwidget.c b/ext/gtk/gtkgstglwidget.c index 09d709091..638c80588 100644 --- a/ext/gtk/gtkgstglwidget.c +++ b/ext/gtk/gtkgstglwidget.c @@ -173,7 +173,7 @@ _redraw_texture (GtkGstGLWidget * gst_widget, guint tex) GstVideoRectangle src, dst, result; gint widget_width, widget_height, widget_scale; - gl->ClearColor (0.0, 0.0, 0.0, 0.0); + gl->ClearColor (0.0, 0.0, 0.0, 1.0); gl->Clear (GL_COLOR_BUFFER_BIT); widget_scale = gtk_widget_get_scale_factor ((GtkWidget *) gst_widget); @@ -221,7 +221,7 @@ _draw_black (GstGLContext * context) const GstGLFuncs *gl = context->gl_vtable; gst_gl_insert_debug_marker (context, "rendering black"); - gl->ClearColor (0.0, 0.0, 0.0, 0.0); + gl->ClearColor (0.0, 0.0, 0.0, 1.0); gl->Clear (GL_COLOR_BUFFER_BIT); } -- 2.26.2