From f54fcb0349e4732641302c6ca058294cd62e135b Mon Sep 17 00:00:00 2001 From: Haihua Hu Date: Tue, 10 Jan 2017 16:54:48 +0800 Subject: [PATCH] qmlglsrc: use glBlitFramebuffer to copy texture for GLES3.0 If support glBlitFrameBuffer, use it for texture copy instead of glCopyTexImage2D https://bugzilla.gnome.org/show_bug.cgi?id=777078 --- ext/qt/qtwindow.cc | 50 +++++++++++++++++++++++++++++++++++++++++++++- ext/qt/qtwindow.h | 1 + 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/ext/qt/qtwindow.cc b/ext/qt/qtwindow.cc index 362a173b2c..92c5834c1d 100644 --- a/ext/qt/qtwindow.cc +++ b/ext/qt/qtwindow.cc @@ -67,6 +67,8 @@ struct _QtGLWindowPrivate GstGLDisplay *display; GstGLContext *other_context; + GLuint fbo; + /* frames that qmlview rendered in its gl thread */ quint64 frames_rendered; quint64 start; @@ -121,6 +123,8 @@ QtGLWindow::QtGLWindow ( QWindow * parent, QQuickWindow *src ) : else connect (source, SIGNAL(sceneGraphInitialized()), this, SLOT(onSceneGraphInitialized()), Qt::DirectConnection); + connect (source, SIGNAL(sceneGraphInvalidated()), this, SLOT(onSceneGraphInvalidated()), Qt::DirectConnection); + GST_DEBUG ("%p init Qt Window", this->priv->display); } @@ -224,7 +228,23 @@ QtGLWindow::afterRendering() this->source->renderTargetId(), dst_tex, width,height); gl->BindTexture (GL_TEXTURE_2D, dst_tex); - gl->CopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0); + if (gl->BlitFramebuffer) { + gl->BindFramebuffer (GL_DRAW_FRAMEBUFFER, this->priv->fbo); + gl->FramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, dst_tex, 0); + + ret = gst_gl_context_check_framebuffer_status (context); + if (!ret) { + GST_ERROR ("FBO errors"); + goto errors; + } + gl->ReadBuffer (GL_COLOR_ATTACHMENT0); + gl->BlitFramebuffer (0, 0, width, height, + 0, 0, width, height, + GL_COLOR_BUFFER_BIT, GL_LINEAR); + } else { + gl->CopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0); + } GST_DEBUG ("rendering finished"); @@ -268,10 +288,38 @@ QtGLWindow::onSceneGraphInitialized() this->priv->initted = gst_qt_get_gl_wrapcontext (this->priv->display, &this->priv->other_context, NULL); + if (this->priv->initted && this->priv->other_context) { + const GstGLFuncs *gl; + + gst_gl_context_activate (this->priv->other_context, TRUE); + gl = this->priv->other_context->gl_vtable; + + gl->GenFramebuffers (1, &this->priv->fbo); + + gst_gl_context_activate (this->priv->other_context, FALSE); + } + GST_DEBUG ("%p created wrapped GL context %" GST_PTR_FORMAT, this, this->priv->other_context); } +void +QtGLWindow::onSceneGraphInvalidated() +{ + GST_DEBUG ("scene graph invalidated"); + + if (this->priv->fbo && this->priv->other_context) { + const GstGLFuncs *gl; + + gst_gl_context_activate (this->priv->other_context, TRUE); + gl = this->priv->other_context->gl_vtable; + + gl->DeleteFramebuffers (1, &this->priv->fbo); + + gst_gl_context_activate (this->priv->other_context, FALSE); + } +} + bool QtGLWindow::getGeometry(int * width, int * height) { diff --git a/ext/qt/qtwindow.h b/ext/qt/qtwindow.h index a617c076a9..697f3897a5 100644 --- a/ext/qt/qtwindow.h +++ b/ext/qt/qtwindow.h @@ -48,6 +48,7 @@ private Q_SLOTS: void beforeRendering (); void afterRendering (); void onSceneGraphInitialized (); + void onSceneGraphInvalidated (); void aboutToQuit(); private: