summaryrefslogtreecommitdiffstats
path: root/src/compositor
diff options
context:
space:
mode:
authorDominik Holland <dominik.holland@pelagicore.com>2016-03-02 11:27:46 +0100
committerDominik Holland <dominik.holland@pelagicore.com>2016-05-18 15:08:53 +0000
commitc7832b0a1d4e5e095e56315c43145bb8964f7030 (patch)
tree30e63aa55221255e9d759be7cdaae924e6e0798e /src/compositor
parent959d9d604da402e768ce329d43510d2b03756d89 (diff)
Fixed eglStream compositing
When creating the eglStream from the fd we also need to create the texture and call stream_consumer_gltexture. Otherwise the wayland client can't create the wayland client surface. Fixed the qwindow-compositor example to use the texture associated to the QWaylandBufferRef when compositing a EXTERNAL_OES target. QML compositing only works when QSG_RENDER_LOOP is set to basic as we need to generate a texture from the gui thread. As the texture is created by the bufferintegration it might end up in a different gl context than the quick item using it. The texture is also deleted together with the buffer, which prevents the use of the texture afterwards. Both problems need to be fixed in follow up commits. Task-number: QTBUG-50850 Change-Id: Ifec67bbe9e4b2a680c871dc4aced37b71b7b6f80 Reviewed-by: Louai Al-Khanji <louai.al-khanji@qt.io> Reviewed-by: Giulio Camuffo <giulio.camuffo@kdab.com>
Diffstat (limited to 'src/compositor')
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.cpp10
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.h3
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp64
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem_p.h5
-rw-r--r--src/compositor/hardware_integration/qwlclientbufferintegration_p.h1
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp8
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h1
7 files changed, 81 insertions, 11 deletions
diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp
index 929503b4f..e9fbcfbdb 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.cpp
+++ b/src/compositor/compositor_api/qwaylandbufferref.cpp
@@ -241,6 +241,16 @@ QImage QWaylandBufferRef::image() const
return d->buffer->image();
}
+#ifdef QT_COMPOSITOR_WAYLAND_GL
+GLuint QWaylandBufferRef::textureForPlane(int plane) const
+{
+ if (d->nullOrDestroyed())
+ return 0;
+
+ return d->buffer->textureForPlane(plane);
+}
+#endif
+
/*!
* Binds the buffer to the current OpenGL texture. This may
* perform a copy of the buffer data, depending on the platform
diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h
index 4ded8f17b..50c85b965 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.h
+++ b/src/compositor/compositor_api/qwaylandbufferref.h
@@ -96,6 +96,9 @@ public:
bool isShm() const;
QImage image() const;
+#ifdef QT_COMPOSITOR_WAYLAND_GL
+ GLuint textureForPlane(int plane) const;
+#endif
void bindToTexture() const;
void updateTexture() const;
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
index 9fa81cfb2..ab11ff4f8 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
+++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
@@ -179,17 +179,6 @@ QWaylandBufferMaterial::QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEg
{
QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
- for (int i = 0; i < bufferTypes[m_format].planeCount; i++) {
- GLuint texture;
- gl->glGenTextures(1, &texture);
- gl->glBindTexture(bufferTypes[m_format].textureTarget, texture);
- gl->glTexParameteri(bufferTypes[m_format].textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl->glTexParameteri(bufferTypes[m_format].textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl->glTexParameteri(bufferTypes[m_format].textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->glTexParameteri(bufferTypes[m_format].textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- m_textures << texture;
- }
-
gl->glBindTexture(bufferTypes[m_format].textureTarget, 0);
setFlag(bufferTypes[m_format].materialFlags);
}
@@ -202,11 +191,36 @@ QWaylandBufferMaterial::~QWaylandBufferMaterial()
gl->glDeleteTextures(1, &texture);
}
+void QWaylandBufferMaterial::setTextureForPlane(int plane, uint texture)
+{
+ if (plane < 0 || plane >= bufferTypes[m_format].planeCount) {
+ qWarning("plane index is out of range");
+ return;
+ }
+
+ QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
+ const GLenum target = bufferTypes[m_format].textureTarget;
+
+ gl->glBindTexture(target, texture);
+ setTextureParameters(target);
+
+ ensureTextures(plane - 1);
+
+ if (m_textures.size() <= plane) {
+ m_textures << texture;
+ } else {
+ std::swap(m_textures[plane], texture);
+ gl->glDeleteTextures(1, &texture);
+ }
+}
+
void QWaylandBufferMaterial::bind()
{
QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
const GLenum target = bufferTypes[m_format].textureTarget;
+ ensureTextures(bufferTypes[m_format].planeCount);
+
switch (m_textures.size()) {
case 3:
gl->glActiveTexture(GL_TEXTURE2);
@@ -230,6 +244,31 @@ QSGMaterialShader *QWaylandBufferMaterial::createShader() const
return new QWaylandBufferMaterialShader(m_format);
}
+
+void QWaylandBufferMaterial::setTextureParameters(GLenum target)
+{
+ QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
+ gl->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+//TODO move this into a separate centralized texture management class
+void QWaylandBufferMaterial::ensureTextures(int count)
+{
+ QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
+ const GLenum target = bufferTypes[m_format].textureTarget;
+ GLuint texture;
+
+ for (int plane = m_textures.size(); plane < count; plane++) {
+ gl->glGenTextures(1, &texture);
+ gl->glBindTexture(target, texture);
+ setTextureParameters(target);
+ m_textures << texture;
+ }
+}
+
QMutex *QWaylandQuickItemPrivate::mutex = 0;
class QWaylandSurfaceTextureProvider : public QSGTextureProvider
@@ -1047,6 +1086,9 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
if (d->newTexture) {
d->newTexture = false;
+ for (int plane = 0; plane < bufferTypes[ref.bufferFormatEgl()].planeCount; plane++)
+ if (uint texture = ref.textureForPlane(plane))
+ material->setTextureForPlane(plane, texture);
material->bind();
ref.bindToTexture();
}
diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h
index 679d218ee..b529ba959 100644
--- a/src/compositor/compositor_api/qwaylandquickitem_p.h
+++ b/src/compositor/compositor_api/qwaylandquickitem_p.h
@@ -85,12 +85,17 @@ public:
QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEgl format);
~QWaylandBufferMaterial();
+ void setTextureForPlane(int plane, uint texture);
+
void bind();
QSGMaterialType *type() const Q_DECL_OVERRIDE;
QSGMaterialShader *createShader() const Q_DECL_OVERRIDE;
private:
+ void setTextureParameters(GLenum target);
+ void ensureTextures(int count);
+
const QWaylandBufferRef::BufferFormatEgl m_format;
QVarLengthArray<GLuint, 3> m_textures;
};
diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
index 1fbcb7991..90762437b 100644
--- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
+++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
@@ -73,6 +73,7 @@ public:
virtual void initializeBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); }
virtual QWaylandBufferRef::BufferFormatEgl bufferFormat(struct ::wl_resource *buffer) { Q_UNUSED(buffer); return QWaylandBufferRef::BufferFormatEgl_RGBA; }
+ virtual uint textureForBuffer(struct ::wl_resource *buffer, int plane) { Q_UNUSED(buffer); Q_UNUSED(plane); return 0; }
virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0;
virtual void updateTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); }
diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
index c7bdbcee5..14ccde13a 100644
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
@@ -232,6 +232,14 @@ void SurfaceBuffer::bindToTexture() const
}
}
+uint SurfaceBuffer::textureForPlane(int plane) const
+{
+ if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
+ return clientInt->textureForBuffer(m_buffer, plane);
+
+ return 0;
+}
+
void SurfaceBuffer::updateTexture() const
{
if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
index 85f78d41b..95e7e8158 100644
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
@@ -106,6 +106,7 @@ public:
QImage image() const;
QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const;
void bindToTexture() const;
+ uint textureForPlane(int plane) const;
void updateTexture() const;
static bool hasContent(SurfaceBuffer *buffer) { return buffer && buffer->waylandBufferHandle(); }