Diff
Modified: trunk/Source/WebCore/ChangeLog (257462 => 257463)
--- trunk/Source/WebCore/ChangeLog 2020-02-26 11:50:04 UTC (rev 257462)
+++ trunk/Source/WebCore/ChangeLog 2020-02-26 12:35:11 UTC (rev 257463)
@@ -1,3 +1,47 @@
+2020-02-26 Víctor Manuel Jáquez Leal <[email protected]>
+
+ [GL][GStreamer] Instantiate GstGLContext when the shared GLContext is created
+ https://bugs.webkit.org/show_bug.cgi?id=200626
+
+ Reviewed by Carlos Garcia Campos.
+
+ This patch adds GstGLContext and GstGLDisplay as part of
+ PlatformDisplay.
+
+ Right now one GstGLContext is created per video tag, which is a
+ wrapper of the GL shared context. Every time this wrapper is
+ created the GL context has to be current in order to initialize
+ the wrapper's internal state.
+
+ A better approach would be to have a single GstGLContext per GL
+ context, to instantiate it when the GL context is created and
+ current. This GstGLContext would be used for all media players.
+
+ GstGLContext and GstGLDisplay are instantiated as singletons by
+ PlatformDisplay. When the media player request for the
+ GstGLContext a GL context is instantiated, if it wasn't before,
+ and wraps it. PlatformDisplay adds two getters, one for
+ GstGLContext object, and other for GstGLDisplay. Both are used to
+ configure the internal GStreamer GL context in the multimedia
+ pipeline.
+
+ No new tests are needed.
+
+ * platform/GStreamer.cmake:
+ * platform/graphics/PlatformDisplay.cpp:
+ (WebCore::PlatformDisplay::terminateEGLDisplay):
+ * platform/graphics/PlatformDisplay.h:
+ * platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp:
+ (requestGLContext):
+ (webKitGLVideoSinkChangeState):
+ (webKitGLVideoSinkProbePlatform):
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+ * platform/graphics/gstreamer/PlatformDisplayGStreamer.cpp: Added.
+ (createGstGLDisplay):
+ (PlatformDisplay::tryEnsureGstGLContext):
+ (PlatformDisplay::gstGLDisplay const):
+ (PlatformDisplay::gstGLContext const):
+
2020-02-26 Chris Dumez <[email protected]>
DocumentTimeline / CSSTransition objects are leaking on CNN.com
Modified: trunk/Source/WebCore/platform/GStreamer.cmake (257462 => 257463)
--- trunk/Source/WebCore/platform/GStreamer.cmake 2020-02-26 11:50:04 UTC (rev 257462)
+++ trunk/Source/WebCore/platform/GStreamer.cmake 2020-02-26 12:35:11 UTC (rev 257463)
@@ -117,6 +117,7 @@
${GSTREAMER_GL_LIBRARIES}
)
list(APPEND WebCore_SOURCES
+ platform/graphics/gstreamer/PlatformDisplayGStreamer.cpp
platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp
)
endif ()
Modified: trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp (257462 => 257463)
--- trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp 2020-02-26 11:50:04 UTC (rev 257462)
+++ trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp 2020-02-26 12:35:11 UTC (rev 257463)
@@ -231,6 +231,10 @@
void PlatformDisplay::terminateEGLDisplay()
{
+#if ENABLE(VIDEO) && USE(GSTREAMER_GL)
+ m_gstGLDisplay = nullptr;
+ m_gstGLContext = nullptr;
+#endif
m_sharingGLContext = nullptr;
ASSERT(m_eglDisplayInitialized);
if (m_eglDisplay == EGL_NO_DISPLAY)
Modified: trunk/Source/WebCore/platform/graphics/PlatformDisplay.h (257462 => 257463)
--- trunk/Source/WebCore/platform/graphics/PlatformDisplay.h 2020-02-26 11:50:04 UTC (rev 257462)
+++ trunk/Source/WebCore/platform/graphics/PlatformDisplay.h 2020-02-26 12:35:11 UTC (rev 257463)
@@ -33,6 +33,13 @@
typedef void *EGLDisplay;
#endif
+#if ENABLE(VIDEO) && USE(GSTREAMER_GL)
+#include "GRefPtrGStreamer.h"
+
+typedef struct _GstGLContext GstGLContext;
+typedef struct _GstGLDisplay GstGLDisplay;
+#endif // ENABLE(VIDEO) && USE(GSTREAMER_GL)
+
namespace WebCore {
class GLContext;
@@ -71,6 +78,11 @@
static void shutDownEglDisplays();
#endif
+#if ENABLE(VIDEO) && USE(GSTREAMER_GL)
+ GstGLDisplay* gstGLDisplay() const;
+ GstGLContext* gstGLContext() const;
+#endif
+
protected:
enum class NativeDisplayOwned { No, Yes };
explicit PlatformDisplay(NativeDisplayOwned);
@@ -99,6 +111,13 @@
int m_eglMajorVersion { 0 };
int m_eglMinorVersion { 0 };
#endif
+
+#if ENABLE(VIDEO) && USE(GSTREAMER_GL)
+ bool tryEnsureGstGLContext() const;
+
+ mutable GRefPtr<GstGLDisplay> m_gstGLDisplay;
+ mutable GRefPtr<GstGLContext> m_gstGLContext;
+#endif
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp (257462 => 257463)
--- trunk/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp 2020-02-26 11:50:04 UTC (rev 257462)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp 2020-02-26 12:35:11 UTC (rev 257463)
@@ -22,34 +22,13 @@
#if ENABLE(VIDEO) && USE(GSTREAMER_GL)
-#include "GLContext.h"
#include "GStreamerCommon.h"
#include "MediaPlayerPrivateGStreamer.h"
+#include "PlatformDisplay.h"
+
#include <gst/app/gstappsink.h>
#include <wtf/glib/WTFGType.h>
-#if USE(GLX)
-#include "GLContextGLX.h"
-#include <gst/gl/x11/gstgldisplay_x11.h>
-#endif
-
-#if USE(EGL)
-#include "GLContextEGL.h"
-#include <gst/gl/egl/gstgldisplay_egl.h>
-#endif
-
-#if PLATFORM(X11)
-#include "PlatformDisplayX11.h"
-#endif
-
-#if PLATFORM(WAYLAND)
-#include "PlatformDisplayWayland.h"
-#endif
-
-#if USE(WPE_RENDERER)
-#include "PlatformDisplayLibWPE.h"
-#endif
-
// gstglapi.h may include eglplatform.h and it includes X.h, which
// defines None, breaking MediaPlayer::None enum
#if PLATFORM(X11) && GST_GL_HAVE_PLATFORM_EGL
@@ -66,8 +45,6 @@
struct _WebKitGLVideoSinkPrivate {
GRefPtr<GstElement> appSink;
- GRefPtr<GstGLContext> glContext;
- GRefPtr<GstGLDisplay> glDisplay;
GRefPtr<GstContext> glDisplayElementContext;
GRefPtr<GstContext> glAppElementContext;
MediaPlayerPrivateGStreamer* mediaPlayerPrivate;
@@ -140,113 +117,16 @@
GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object));
}
-static bool ensureGstGLContext(WebKitGLVideoSink* sink)
+GRefPtr<GstContext> requestGLContext(const char* contextType)
{
- WebKitGLVideoSinkPrivate* priv = sink->priv;
-
- if (priv->glContext)
- return true;
-
auto& sharedDisplay = PlatformDisplay::sharedDisplayForCompositing();
+ auto* gstGLDisplay = sharedDisplay.gstGLDisplay();
+ auto* gstGLContext = sharedDisplay.gstGLContext();
+ ASSERT(gstGLDisplay && gstGLContext);
- // The floating ref removal support was added in https://bugzilla.gnome.org/show_bug.cgi?id=743062.
- bool shouldAdoptRef = webkitGstCheckVersion(1, 14, 0);
- if (!priv->glDisplay) {
-#if PLATFORM(X11)
-#if USE(GLX)
- if (is<PlatformDisplayX11>(sharedDisplay)) {
- GST_DEBUG_OBJECT(sink, "Creating X11 shared GL display");
- if (shouldAdoptRef)
- priv->glDisplay = adoptGRef(GST_GL_DISPLAY(gst_gl_display_x11_new_with_display(downcast<PlatformDisplayX11>(sharedDisplay).native())));
- else
- priv->glDisplay = GST_GL_DISPLAY(gst_gl_display_x11_new_with_display(downcast<PlatformDisplayX11>(sharedDisplay).native()));
- }
-#elif USE(EGL)
- if (is<PlatformDisplayX11>(sharedDisplay)) {
- GST_DEBUG_OBJECT(sink, "Creating X11 shared EGL display");
- if (shouldAdoptRef)
- priv->glDisplay = adoptGRef(GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayX11>(sharedDisplay).eglDisplay())));
- else
- priv->glDisplay = GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayX11>(sharedDisplay).eglDisplay()));
- }
-#endif
-#endif
-
-#if PLATFORM(WAYLAND)
- if (is<PlatformDisplayWayland>(sharedDisplay)) {
- GST_DEBUG_OBJECT(sink, "Creating Wayland shared display");
- if (shouldAdoptRef)
- priv->glDisplay = adoptGRef(GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayWayland>(sharedDisplay).eglDisplay())));
- else
- priv->glDisplay = GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayWayland>(sharedDisplay).eglDisplay()));
- }
-#endif
-
-#if USE(WPE_RENDERER)
- if (is<PlatformDisplayLibWPE>(sharedDisplay)) {
- GST_DEBUG_OBJECT(sink, "Creating WPE shared EGL display");
- if (shouldAdoptRef)
- priv->glDisplay = adoptGRef(GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayLibWPE>(sharedDisplay).eglDisplay())));
- else
- priv->glDisplay = GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayLibWPE>(sharedDisplay).eglDisplay()));
- }
-#endif
-
- ASSERT(priv->glDisplay);
- }
-
- GLContext* sharedContext = sharedDisplay.sharingGLContext();
- if (!sharedContext) {
- GST_ELEMENT_ERROR(GST_ELEMENT_CAST(sink), RESOURCE, NOT_FOUND, (("WebKit shared GL context unavailable")),
- ("The WebKit shared GL context somehow disappeared. Video textures rendering will fail."));
- return false;
- }
-
- // EGL and GLX are mutually exclusive, no need for ifdefs here.
- GstGLPlatform glPlatform = sharedContext->isEGLContext() ? GST_GL_PLATFORM_EGL : GST_GL_PLATFORM_GLX;
-
-#if USE(OPENGL_ES)
- GstGLAPI glAPI = GST_GL_API_GLES2;
-#elif USE(OPENGL)
- GstGLAPI glAPI = GST_GL_API_OPENGL;
-#else
- ASSERT_NOT_REACHED();
-#endif
-
- PlatformGraphicsContextGL contextHandle = sharedContext->platformContext();
- if (!contextHandle)
- return false;
-
- if (shouldAdoptRef)
- priv->glContext = adoptGRef(gst_gl_context_new_wrapped(priv->glDisplay.get(), reinterpret_cast<guintptr>(contextHandle), glPlatform, glAPI));
- else
- priv->glContext = gst_gl_context_new_wrapped(priv->glDisplay.get(), reinterpret_cast<guintptr>(contextHandle), glPlatform, glAPI);
-
- // Activate and fill the GStreamer wrapped context with the Webkit's shared one.
- auto* previousActiveContext = GLContext::current();
- sharedContext->makeContextCurrent();
- if (gst_gl_context_activate(priv->glContext.get(), TRUE)) {
- GUniqueOutPtr<GError> error;
- if (!gst_gl_context_fill_info(priv->glContext.get(), &error.outPtr()))
- GST_WARNING("Failed to fill in GStreamer context: %s", error->message);
- gst_gl_context_activate(priv->glContext.get(), FALSE);
- } else
- GST_WARNING("Failed to activate GStreamer context %" GST_PTR_FORMAT, priv->glContext.get());
- if (previousActiveContext)
- previousActiveContext->makeContextCurrent();
-
- return true;
-}
-
-GRefPtr<GstContext> requestGLContext(WebKitGLVideoSink* sink, const char* contextType)
-{
- WebKitGLVideoSinkPrivate* priv = sink->priv;
- if (!ensureGstGLContext(sink))
- return nullptr;
-
if (!g_strcmp0(contextType, GST_GL_DISPLAY_CONTEXT_TYPE)) {
GstContext* displayContext = gst_context_new(GST_GL_DISPLAY_CONTEXT_TYPE, TRUE);
- gst_context_set_gl_display(displayContext, priv->glDisplay.get());
+ gst_context_set_gl_display(displayContext, gstGLDisplay);
return adoptGRef(displayContext);
}
@@ -254,9 +134,9 @@
GstContext* appContext = gst_context_new("gst.gl.app_context", TRUE);
GstStructure* structure = gst_context_writable_structure(appContext);
#if GST_CHECK_VERSION(1, 12, 0)
- gst_structure_set(structure, "context", GST_TYPE_GL_CONTEXT, priv->glContext.get(), nullptr);
+ gst_structure_set(structure, "context", GST_TYPE_GL_CONTEXT, gstGLContext, nullptr);
#else
- gst_structure_set(structure, "context", GST_GL_TYPE_CONTEXT, priv->glContext.get(), nullptr);
+ gst_structure_set(structure, "context", GST_GL_TYPE_CONTEXT, gstGLContext, nullptr);
#endif
return adoptGRef(appContext);
}
@@ -278,13 +158,13 @@
case GST_STATE_CHANGE_READY_TO_READY:
case GST_STATE_CHANGE_READY_TO_PAUSED: {
if (!priv->glDisplayElementContext)
- priv->glDisplayElementContext = requestGLContext(sink, GST_GL_DISPLAY_CONTEXT_TYPE);
+ priv->glDisplayElementContext = requestGLContext(GST_GL_DISPLAY_CONTEXT_TYPE);
if (priv->glDisplayElementContext)
gst_element_set_context(GST_ELEMENT_CAST(sink), priv->glDisplayElementContext.get());
if (!priv->glAppElementContext)
- priv->glAppElementContext = requestGLContext(sink, "gst.gl.app_context");
+ priv->glAppElementContext = requestGLContext("gst.gl.app_context");
if (priv->glAppElementContext)
gst_element_set_context(GST_ELEMENT_CAST(sink), priv->glAppElementContext.get());
@@ -376,9 +256,7 @@
bool webKitGLVideoSinkProbePlatform()
{
- auto& sharedDisplay = PlatformDisplay::sharedDisplayForCompositing();
- GLContext* sharedContext = sharedDisplay.sharingGLContext();
- if (!sharedContext) {
+ if (!PlatformDisplay::sharedDisplayForCompositing().gstGLContext()) {
GST_WARNING("WebKit shared GL context is not available.");
return false;
}
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h (257462 => 257463)
--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h 2020-02-26 11:50:04 UTC (rev 257462)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h 2020-02-26 12:35:11 UTC (rev 257463)
@@ -82,8 +82,6 @@
typedef struct _GstStreamVolume GstStreamVolume;
typedef struct _GstVideoInfo GstVideoInfo;
-typedef struct _GstGLContext GstGLContext;
-typedef struct _GstGLDisplay GstGLDisplay;
#if USE(WPE_VIDEO_PLANE_DISPLAY_DMABUF)
struct wpe_video_plane_display_dmabuf_source;
Added: trunk/Source/WebCore/platform/graphics/gstreamer/PlatformDisplayGStreamer.cpp (0 => 257463)
--- trunk/Source/WebCore/platform/graphics/gstreamer/PlatformDisplayGStreamer.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/PlatformDisplayGStreamer.cpp 2020-02-26 12:35:11 UTC (rev 257463)
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2020 Igalia S.L
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * aint with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "PlatformDisplay.h"
+
+#include "GStreamerCommon.h"
+
+#if USE(GLX)
+#include "GLContextGLX.h"
+#include <gst/gl/x11/gstgldisplay_x11.h>
+#endif
+
+#if USE(EGL)
+#include "GLContextEGL.h"
+#include <gst/gl/egl/gstgldisplay_egl.h>
+#endif
+
+#if PLATFORM(X11)
+#include "PlatformDisplayX11.h"
+#endif
+
+#if PLATFORM(WAYLAND)
+#include "PlatformDisplayWayland.h"
+#endif
+
+#if USE(WPE_RENDERER)
+#include "PlatformDisplayLibWPE.h"
+#endif
+
+#define GST_USE_UNSTABLE_API
+#include <gst/gl/gl.h>
+#undef GST_USE_UNSTABLE_API
+
+GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
+#define GST_CAT_DEFAULT webkit_media_player_debug
+
+using namespace WebCore;
+
+static GstGLDisplay* createGstGLDisplay(const PlatformDisplay& sharedDisplay)
+{
+#if USE(WPE_RENDERER)
+ if (is<PlatformDisplayLibWPE>(sharedDisplay))
+ return GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayLibWPE>(sharedDisplay).eglDisplay()));
+#endif
+
+#if PLATFORM(X11)
+#if USE(GLX)
+ if (is<PlatformDisplayX11>(sharedDisplay))
+ return GST_GL_DISPLAY(gst_gl_display_x11_new_with_display(downcast<PlatformDisplayX11>(sharedDisplay).native()));
+#elif USE(EGL)
+ if (is<PlatformDisplayX11>(sharedDisplay))
+ return GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatfomDisplayX11>(sharedDisplay).eglDisplay()));
+#endif
+#endif
+
+#if PLATFORM(WAYLAND)
+ if (is<PlatformDisplayWayland>(sharedDisplay))
+ return GST_GL_DISPLAY(gst_gl_display_egl_new_with_egl_display(downcast<PlatformDisplayWayland>(sharedDisplay).eglDisplay()));
+#endif
+
+ return nullptr;
+}
+
+bool PlatformDisplay::tryEnsureGstGLContext() const
+{
+ if (m_gstGLDisplay && m_gstGLContext)
+ return true;
+
+#if USE(OPENGL_ES)
+ GstGLAPI glAPI = GST_GL_API_GLES2;
+#elif USE(OPENGL)
+ GstGLAPI glAPI = GST_GL_API_OPENGL;
+#else
+ return false;
+#endif
+
+ auto* sharedContext = const_cast<PlatformDisplay*>(this)->sharingGLContext();
+ if (!sharedContext)
+ return false;
+ PlatformGraphicsContextGL contextHandle = sharedContext->platformContext();
+ if (!contextHandle)
+ return false;
+
+ bool shouldAdoptRef = webkitGstCheckVersion(1, 14, 0);
+
+ if (shouldAdoptRef)
+ m_gstGLDisplay = adoptGRef(createGstGLDisplay(*this));
+ else
+ m_gstGLDisplay = createGstGLDisplay(*this);
+ if (!m_gstGLDisplay)
+ return false;
+
+ GstGLPlatform glPlatform = sharedContext->isEGLContext() ? GST_GL_PLATFORM_EGL : GST_GL_PLATFORM_GLX;
+
+ if (shouldAdoptRef)
+ m_gstGLContext = adoptGRef(gst_gl_context_new_wrapped(m_gstGLDisplay.get(), reinterpret_cast<guintptr>(contextHandle), glPlatform, glAPI));
+ else
+ m_gstGLContext = gst_gl_context_new_wrapped(m_gstGLDisplay.get(), reinterpret_cast<guintptr>(contextHandle), glPlatform, glAPI);
+
+ // Activate and fill the GStreamer wrapped context with the Webkit's shared one.
+ auto* previousActiveContext = GLContext::current();
+ sharedContext->makeContextCurrent();
+ if (gst_gl_context_activate(m_gstGLContext.get(), TRUE)) {
+ GUniqueOutPtr<GError> error;
+ if (!gst_gl_context_fill_info(m_gstGLContext.get(), &error.outPtr()))
+ GST_WARNING("Failed to fill in GStreamer context: %s", error->message);
+ } else
+ GST_WARNING("Failed to activate GStreamer context %" GST_PTR_FORMAT, m_gstGLContext.get());
+ if (previousActiveContext)
+ previousActiveContext->makeContextCurrent();
+
+ return true;
+}
+
+GstGLDisplay* PlatformDisplay::gstGLDisplay() const
+{
+ if (!tryEnsureGstGLContext())
+ return nullptr;
+ return m_gstGLDisplay.get();
+}
+
+GstGLContext* PlatformDisplay::gstGLContext() const
+{
+ if (!tryEnsureGstGLContext())
+ return nullptr;
+ return m_gstGLContext.get();
+}