summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compositor/compositor.pro1
-rw-r--r--src/compositor/compositor.qrc11
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.cpp27
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.h20
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp252
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.h2
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem_p.h36
-rw-r--r--src/compositor/hardware_integration/qwlclientbufferintegration_p.h3
-rw-r--r--src/compositor/shaders/surface.vert9
-rw-r--r--src/compositor/shaders/surface_oes_external.frag8
-rw-r--r--src/compositor/shaders/surface_rgba.frag7
-rw-r--r--src/compositor/shaders/surface_rgbx.frag8
-rw-r--r--src/compositor/shaders/surface_y_u_v.frag18
-rw-r--r--src/compositor/shaders/surface_y_uv.frag17
-rw-r--r--src/compositor/shaders/surface_y_xuxv.frag17
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp18
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h3
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp415
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h2
19 files changed, 680 insertions, 194 deletions
diff --git a/src/compositor/compositor.pro b/src/compositor/compositor.pro
index 37f670964..e60506417 100644
--- a/src/compositor/compositor.pro
+++ b/src/compositor/compositor.pro
@@ -22,6 +22,7 @@ QMAKE_DOCS = $$PWD/doc/qtwaylandcompositor.qdocconf
INCLUDEPATH += ../shared
HEADERS += ../shared/qwaylandmimehelper.h ../shared/qwaylandinputmethodeventbuilder.h
SOURCES += ../shared/qwaylandmimehelper.cpp ../shared/qwaylandinputmethodeventbuilder.cpp
+RESOURCES += compositor.qrc
include ($$PWD/global/global.pri)
include ($$PWD/wayland_wrapper/wayland_wrapper.pri)
diff --git a/src/compositor/compositor.qrc b/src/compositor/compositor.qrc
new file mode 100644
index 000000000..5dc7a70a5
--- /dev/null
+++ b/src/compositor/compositor.qrc
@@ -0,0 +1,11 @@
+<RCC>
+ <qresource prefix="/qt-project.org/wayland/compositor">
+ <file>shaders/surface.vert</file>
+ <file>shaders/surface_oes_external.frag</file>
+ <file>shaders/surface_rgba.frag</file>
+ <file>shaders/surface_rgbx.frag</file>
+ <file>shaders/surface_y_u_v.frag</file>
+ <file>shaders/surface_y_uv.frag</file>
+ <file>shaders/surface_y_xuxv.frag</file>
+ </qresource>
+</RCC>
diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp
index d0fe7ca40..faff48560 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.cpp
+++ b/src/compositor/compositor_api/qwaylandbufferref.cpp
@@ -199,6 +199,25 @@ QWaylandSurface::Origin QWaylandBufferRef::origin() const
return QWaylandSurface::OriginBottomLeft;
}
+QWaylandBufferRef::BufferType QWaylandBufferRef::bufferType() const
+{
+ if (d->nullOrDestroyed())
+ return BufferType_Null;
+
+ if (isShm())
+ return BufferType_Shm;
+
+ return BufferType_Egl;
+}
+
+QWaylandBufferRef::BufferFormatEgl QWaylandBufferRef::bufferFormatEgl() const
+{
+ if (d->nullOrDestroyed())
+ return BufferFormatEgl_Null;
+
+ return d->buffer->bufferFormatEgl();
+}
+
/*!
* Returns true if the buffer is a shared memory buffer. Otherwise returns false.
*/
@@ -235,14 +254,6 @@ void QWaylandBufferRef::bindToTexture() const
}
-int QWaylandBufferRef::textureTarget() const
-{
- if (d->nullOrDestroyed())
- return 0x0DE1; // GL_TEXTURE_2D
-
- return d->buffer->textureTarget();
-}
-
void QWaylandBufferRef::updateTexture() const
{
if (d->nullOrDestroyed() || d->buffer->isShm())
diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h
index a4a5df5e0..4ded8f17b 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.h
+++ b/src/compositor/compositor_api/qwaylandbufferref.h
@@ -75,11 +75,29 @@ public:
QSize size() const;
QWaylandSurface::Origin origin() const;
+ enum BufferType {
+ BufferType_Null,
+ BufferType_Shm,
+ BufferType_Egl
+ };
+
+ enum BufferFormatEgl {
+ BufferFormatEgl_Null,
+ BufferFormatEgl_RGB,
+ BufferFormatEgl_RGBA,
+ BufferFormatEgl_EXTERNAL_OES,
+ BufferFormatEgl_Y_U_V,
+ BufferFormatEgl_Y_UV,
+ BufferFormatEgl_Y_XUXV
+ };
+
+ BufferType bufferType() const;
+ BufferFormatEgl bufferFormatEgl() const;
+
bool isShm() const;
QImage image() const;
void bindToTexture() const;
- int textureTarget() const;
void updateTexture() const;
private:
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
index ded16a9c3..e46b38ccd 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
+++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
@@ -57,8 +57,179 @@
#include <wayland-server.h>
#include <QThread>
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif
+
QT_BEGIN_NAMESPACE
+static const struct {
+ const char * const vertexShaderSourceFile;
+ const char * const fragmentShaderSourceFile;
+ GLenum textureTarget;
+ int planeCount;
+ bool canProvideTexture;
+ QSGMaterial::Flags materialFlags;
+ QSGMaterialType materialType;
+} bufferTypes[] = {
+ // BufferFormatEgl_Null
+ { "", "", 0, 0, false, 0, {} },
+
+ // BufferFormatEgl_RGB
+ {
+ ":/qt-project.org/wayland/compositor/shaders/surface.vert",
+ ":/qt-project.org/wayland/compositor/shaders/surface_rgbx.frag",
+ GL_TEXTURE_2D, 1, true,
+ QSGMaterial::Blending,
+ {}
+ },
+
+ // BufferFormatEgl_RGBA
+ {
+ ":/qt-project.org/wayland/compositor/shaders/surface.vert",
+ ":/qt-project.org/wayland/compositor/shaders/surface_rgba.frag",
+ GL_TEXTURE_2D, 1, true,
+ QSGMaterial::Blending,
+ {}
+ },
+
+ // BufferFormatEgl_EXTERNAL_OES
+ {
+ ":/qt-project.org/wayland/compositor/shaders/surface.vert",
+ ":/qt-project.org/wayland/compositor/shaders/surface_oes_external.frag",
+ GL_TEXTURE_EXTERNAL_OES, 1, false,
+ QSGMaterial::Blending,
+ {}
+ },
+
+ // BufferFormatEgl_Y_U_V
+ {
+ ":/qt-project.org/wayland/compositor/shaders/surface.vert",
+ ":/qt-project.org/wayland/compositor/shaders/surface_y_u_v.frag",
+ GL_TEXTURE_2D, 3, false,
+ QSGMaterial::Blending,
+ {}
+ },
+
+ // BufferFormatEgl_Y_UV
+ {
+ ":/qt-project.org/wayland/compositor/shaders/surface.vert",
+ ":/qt-project.org/wayland/compositor/shaders/surface_y_uv.frag",
+ GL_TEXTURE_2D, 2, false,
+ QSGMaterial::Blending,
+ {}
+ },
+
+ // BufferFormatEgl_Y_XUXV
+ {
+ ":/qt-project.org/wayland/compositor/shaders/surface.vert",
+ ":/qt-project.org/wayland/compositor/shaders/surface_y_xuxv.frag",
+ GL_TEXTURE_2D, 2, false,
+ QSGMaterial::Blending,
+ {}
+ }
+};
+
+QWaylandBufferMaterialShader::QWaylandBufferMaterialShader(QWaylandBufferRef::BufferFormatEgl format)
+ : QSGMaterialShader()
+ , m_format(format)
+{
+ setShaderSourceFile(QOpenGLShader::Vertex, QString::fromLatin1(bufferTypes[format].vertexShaderSourceFile));
+ setShaderSourceFile(QOpenGLShader::Fragment, QString::fromLatin1(bufferTypes[format].fragmentShaderSourceFile));
+}
+
+void QWaylandBufferMaterialShader::updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
+{
+ QSGMaterialShader::updateState(state, newEffect, oldEffect);
+
+ QWaylandBufferMaterial *material = static_cast<QWaylandBufferMaterial *>(newEffect);
+ material->bind();
+
+ if (state.isMatrixDirty())
+ program()->setUniformValue(m_id_matrix, state.combinedMatrix());
+
+ if (state.isOpacityDirty())
+ program()->setUniformValue(m_id_opacity, state.opacity());
+}
+
+const char * const *QWaylandBufferMaterialShader::attributeNames() const
+{
+ static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 };
+ return attr;
+}
+
+void QWaylandBufferMaterialShader::initialize()
+{
+ QSGMaterialShader::initialize();
+
+ m_id_matrix = program()->uniformLocation("qt_Matrix");
+ m_id_opacity = program()->uniformLocation("qt_Opacity");
+
+ for (int i = 0; i < bufferTypes[m_format].planeCount; i++) {
+ m_id_tex << program()->uniformLocation("tex" + QByteArray::number(i));
+ program()->setUniformValue(m_id_tex[i], i);
+ }
+
+ Q_ASSERT(m_id_tex.size() == bufferTypes[m_format].planeCount);
+}
+
+QWaylandBufferMaterial::QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEgl format)
+ : QSGMaterial()
+ , m_format(format)
+{
+ 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);
+}
+
+QWaylandBufferMaterial::~QWaylandBufferMaterial()
+{
+ QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
+
+ for (GLuint texture : m_textures)
+ gl->glDeleteTextures(1, &texture);
+}
+
+void QWaylandBufferMaterial::bind()
+{
+ QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
+ const GLenum target = bufferTypes[m_format].textureTarget;
+
+ switch (m_textures.size()) {
+ case 3:
+ gl->glActiveTexture(GL_TEXTURE2);
+ gl->glBindTexture(target, m_textures[2]);
+ case 2:
+ gl->glActiveTexture(GL_TEXTURE1);
+ gl->glBindTexture(target, m_textures[1]);
+ case 1:
+ gl->glActiveTexture(GL_TEXTURE0);
+ gl->glBindTexture(target, m_textures[0]);
+ }
+}
+
+QSGMaterialType *QWaylandBufferMaterial::type() const
+{
+ return const_cast<QSGMaterialType *>(&bufferTypes[m_format].materialType);
+}
+
+QSGMaterialShader *QWaylandBufferMaterial::createShader() const
+{
+ return new QWaylandBufferMaterialShader(m_format);
+}
+
QMutex *QWaylandQuickItemPrivate::mutex = 0;
class QWaylandSurfaceTextureProvider : public QSGTextureProvider
@@ -85,7 +256,6 @@ public:
if (m_ref.hasBuffer()) {
if (buffer.isShm()) {
m_sgTex = surfaceItem->window()->createTextureFromImage(buffer.image());
- m_invertY = false;
if (m_sgTex) {
m_sgTex->bind();
}
@@ -101,7 +271,6 @@ public:
glBindTexture(GL_TEXTURE_2D, texture);
buffer.bindToTexture();
m_sgTex = surfaceItem->window()->createTextureFromId(texture , QSize(surfaceItem->width(), surfaceItem->height()), opt);
- m_invertY = buffer.origin() == QWaylandSurface::OriginBottomLeft;
}
}
emit textureChanged();
@@ -115,10 +284,8 @@ public:
}
void setSmooth(bool smooth) { m_smooth = smooth; }
- bool invertY() const { return m_invertY; }
private:
bool m_smooth;
- bool m_invertY;
QSGTexture *m_sgTex;
QWaylandBufferRef m_ref;
};
@@ -249,6 +416,12 @@ QWaylandSurface::Origin QWaylandQuickItem::origin() const
return d->origin;
}
+bool QWaylandQuickItem::isTextureProvider() const
+{
+ Q_D(const QWaylandQuickItem);
+ return QQuickItem::isTextureProvider() || d->provider;
+}
+
/*!
* Returns the texture provider of this QWaylandQuickItem.
*/
@@ -822,37 +995,73 @@ void QWaylandQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
Q_D(QWaylandQuickItem);
- bool mapped = (surface() && surface()->isMapped() && d->view->currentBuffer().hasBuffer())
- || (d->view->isBufferLocked() && d->provider);
+ const bool mapped = surface() && surface()->isMapped() && d->view->currentBuffer().hasBuffer();
if (!mapped || !d->paintEnabled) {
delete oldNode;
return 0;
}
- QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);
+ QWaylandBufferRef ref = d->view->currentBuffer();
+ const bool invertY = ref.origin() == QWaylandSurface::OriginBottomLeft;
+ const QRectF rect = invertY ? QRectF(0, height(), width(), -height())
+ : QRectF(0, 0, width(), height());
- if (!node)
- node = new QSGSimpleTextureNode();
+ if (ref.isShm() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) {
+ QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);
- if (!d->provider)
- d->provider = new QWaylandSurfaceTextureProvider();
+ if (!node)
+ node = new QSGSimpleTextureNode();
- if (d->newTexture) {
- d->newTexture = false;
- d->provider->setBufferRef(this, d->view->currentBuffer());
- node->setTexture(d->provider->texture());
- }
+ if (!d->provider)
+ d->provider = new QWaylandSurfaceTextureProvider();
+
+ if (d->newTexture) {
+ d->newTexture = false;
+ d->provider->setBufferRef(this, ref);
+ node->setTexture(d->provider->texture());
+ }
- d->provider->setSmooth(smooth());
+ d->provider->setSmooth(smooth());
+ node->setRect(rect);
- if (d->provider->invertY()) {
- node->setRect(0, height(), width(), -height());
+ return node;
} else {
- node->setRect(0, 0, width(), height());
+ Q_ASSERT(!d->provider);
+
+ QSGGeometryNode *node = static_cast<QSGGeometryNode *>(oldNode);
+
+ if (!node)
+ node = new QSGGeometryNode;
+
+ QSGGeometry *geometry = node->geometry();
+ QWaylandBufferMaterial *material = static_cast<QWaylandBufferMaterial *>(node->material());
+
+ if (!geometry)
+ geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4);
+
+ if (!material)
+ material = new QWaylandBufferMaterial(ref.bufferFormatEgl());
+
+ if (d->newTexture) {
+ d->newTexture = false;
+ material->bind();
+ ref.bindToTexture();
+ }
+
+ ref.updateTexture();
+ QSGGeometry::updateTexturedRectGeometry(geometry, rect, QRectF(0, 0, 1, 1));
+
+ node->setGeometry(geometry);
+ node->setFlag(QSGNode::OwnsGeometry, true);
+
+ node->setMaterial(material);
+ node->setFlag(QSGNode::OwnsMaterial, true);
+
+ return node;
}
- return node;
+ Q_UNREACHABLE();
}
void QWaylandQuickItem::setTouchEventsEnabled(bool enabled)
@@ -909,3 +1118,4 @@ void QWaylandQuickItem::handleSubsurfacePosition(const QPoint &pos)
}
QT_END_NAMESPACE
+
diff --git a/src/compositor/compositor_api/qwaylandquickitem.h b/src/compositor/compositor_api/qwaylandquickitem.h
index 20b28b5f0..08827981a 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.h
+++ b/src/compositor/compositor_api/qwaylandquickitem.h
@@ -80,7 +80,7 @@ public:
QWaylandSurface::Origin origin() const;
- bool isTextureProvider() const Q_DECL_OVERRIDE { return true; }
+ bool isTextureProvider() const Q_DECL_OVERRIDE;
QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
bool paintEnabled() const;
diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h
index eab99f8f3..5c953771e 100644
--- a/src/compositor/compositor_api/qwaylandquickitem_p.h
+++ b/src/compositor/compositor_api/qwaylandquickitem_p.h
@@ -49,6 +49,8 @@
//
#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/QSGMaterialShader>
+#include <QtQuick/QSGMaterial>
#include "qwaylandquickitem.h"
@@ -59,6 +61,40 @@ QT_BEGIN_NAMESPACE
class QWaylandSurfaceTextureProvider;
class QMutex;
+class QWaylandBufferMaterialShader : public QSGMaterialShader
+{
+public:
+ QWaylandBufferMaterialShader(QWaylandBufferRef::BufferFormatEgl format);
+
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) Q_DECL_OVERRIDE;
+ char const *const *attributeNames() const Q_DECL_OVERRIDE;
+
+protected:
+ void initialize() Q_DECL_OVERRIDE;
+
+private:
+ const QWaylandBufferRef::BufferFormatEgl m_format;
+ int m_id_matrix;
+ int m_id_opacity;
+ QVarLengthArray<int, 3> m_id_tex;
+};
+
+class QWaylandBufferMaterial : public QSGMaterial
+{
+public:
+ QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEgl format);
+ ~QWaylandBufferMaterial();
+
+ void bind();
+
+ QSGMaterialType *type() const Q_DECL_OVERRIDE;
+ QSGMaterialShader *createShader() const Q_DECL_OVERRIDE;
+
+private:
+ const QWaylandBufferRef::BufferFormatEgl m_format;
+ QVarLengthArray<GLuint, 3> m_textures;
+};
+
class QWaylandQuickItemPrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QWaylandQuickItem)
diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
index 2dff20e8f..1fbcb7991 100644
--- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
+++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
@@ -50,6 +50,7 @@
#include <QtWaylandCompositor/qwaylandexport.h>
#include <QtWaylandCompositor/qwaylandsurface.h>
+#include <QtWaylandCompositor/qwaylandbufferref.h>
#include <QtCore/QSize>
#include <wayland-server.h>
@@ -71,7 +72,7 @@ public:
virtual void initializeHardware(struct ::wl_display *display) = 0;
virtual void initializeBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); }
- virtual int textureTargetForBuffer(struct ::wl_resource *buffer) const { Q_UNUSED(buffer); return 0x0DE1; }
+ virtual QWaylandBufferRef::BufferFormatEgl bufferFormat(struct ::wl_resource *buffer) { Q_UNUSED(buffer); return QWaylandBufferRef::BufferFormatEgl_RGBA; }
virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0;
virtual void updateTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); }
diff --git a/src/compositor/shaders/surface.vert b/src/compositor/shaders/surface.vert
new file mode 100644
index 000000000..848b334f3
--- /dev/null
+++ b/src/compositor/shaders/surface.vert
@@ -0,0 +1,9 @@
+uniform highp mat4 qt_Matrix;
+attribute highp vec2 qt_VertexPosition;
+attribute highp vec2 qt_VertexTexCoord;
+varying highp vec2 v_texcoord;
+
+void main() {
+ gl_Position = qt_Matrix * vec4(qt_VertexPosition, 0.0, 1.0);
+ v_texcoord = qt_VertexTexCoord;
+}
diff --git a/src/compositor/shaders/surface_oes_external.frag b/src/compositor/shaders/surface_oes_external.frag
new file mode 100644
index 000000000..724d06a85
--- /dev/null
+++ b/src/compositor/shaders/surface_oes_external.frag
@@ -0,0 +1,8 @@
+#extension GL_OES_EGL_image_external : require
+varying highp vec2 v_texcoord;
+uniform highp samplerExternalOES tex0;
+uniform lowp float qt_Opacity;
+
+void main() {
+ gl_FragColor = qt_Opacity * texture2D(tex0, v_texcoord);
+}
diff --git a/src/compositor/shaders/surface_rgba.frag b/src/compositor/shaders/surface_rgba.frag
new file mode 100644
index 000000000..f896051ba
--- /dev/null
+++ b/src/compositor/shaders/surface_rgba.frag
@@ -0,0 +1,7 @@
+varying highp vec2 v_texcoord;
+uniform highp sampler2D tex0;
+uniform lowp float qt_Opacity;
+
+void main() {
+ gl_FragColor = qt_Opacity * texture2D(tex0, v_texcoord);
+}
diff --git a/src/compositor/shaders/surface_rgbx.frag b/src/compositor/shaders/surface_rgbx.frag
new file mode 100644
index 000000000..8fb78498c
--- /dev/null
+++ b/src/compositor/shaders/surface_rgbx.frag
@@ -0,0 +1,8 @@
+varying highp vec2 v_texcoord;
+uniform highp sampler2D tex0;
+uniform lowp float qt_Opacity;
+
+void main() {
+ gl_FragColor.rgb = qt_Opacity * texture2D(tex0, v_texcoord).rgb;
+ gl_FragColor.a = qt_Opacity;
+}
diff --git a/src/compositor/shaders/surface_y_u_v.frag b/src/compositor/shaders/surface_y_u_v.frag
new file mode 100644
index 000000000..e739f6fff
--- /dev/null
+++ b/src/compositor/shaders/surface_y_u_v.frag
@@ -0,0 +1,18 @@
+uniform highp sampler2D tex0;
+uniform highp sampler2D tex1;
+uniform highp sampler2D tex2;
+varying highp vec2 v_texcoord;
+uniform lowp float qt_Opacity;
+
+void main() {
+ float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625);
+ float u = texture2D(tex1, v_texcoord).x - 0.5;
+ float v = texture2D(tex2, v_texcoord).x - 0.5;
+ y *= qt_Opacity;
+ u *= qt_Opacity;
+ v *= qt_Opacity;
+ gl_FragColor.r = y + 1.59602678 * v;
+ gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;
+ gl_FragColor.b = y + 2.01723214 * u;
+ gl_FragColor.a = qt_Opacity;
+}
diff --git a/src/compositor/shaders/surface_y_uv.frag b/src/compositor/shaders/surface_y_uv.frag
new file mode 100644
index 000000000..e3fbcdf8d
--- /dev/null
+++ b/src/compositor/shaders/surface_y_uv.frag
@@ -0,0 +1,17 @@
+uniform highp sampler2D tex0;
+uniform highp sampler2D tex1;
+varying highp vec2 v_texcoord;
+uniform lowp float qt_Opacity;
+
+void main() {
+ float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625);
+ float u = texture2D(tex1, v_texcoord).r - 0.5;
+ float v = texture2D(tex1, v_texcoord).g - 0.5;
+ y *= qt_Opacity;
+ u *= qt_Opacity;
+ v *= qt_Opacity;
+ gl_FragColor.r = y + 1.59602678 * v;
+ gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;
+ gl_FragColor.b = y + 2.01723214 * u;
+ gl_FragColor.a = qt_Opacity;
+}
diff --git a/src/compositor/shaders/surface_y_xuxv.frag b/src/compositor/shaders/surface_y_xuxv.frag
new file mode 100644
index 000000000..79f8600e8
--- /dev/null
+++ b/src/compositor/shaders/surface_y_xuxv.frag
@@ -0,0 +1,17 @@
+uniform highp sampler2D tex0;
+uniform highp sampler2D tex1;
+varying highp vec2 v_texcoord;
+uniform lowp float qt_Opacity;
+
+void main() {
+ float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625);
+ float u = texture2D(tex1, v_texcoord).g - 0.5;
+ float v = texture2D(tex1, v_texcoord).a - 0.5;
+ y *= qt_Opacity;
+ u *= qt_Opacity;
+ v *= qt_Opacity;
+ gl_FragColor.r = y + 1.59602678 * v;
+ gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;
+ gl_FragColor.b = y + 2.01723214 * u;
+ gl_FragColor.a = qt_Opacity;
+}
diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
index f48dd3400..a6509b030 100644
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
@@ -198,6 +198,16 @@ QImage SurfaceBuffer::image() const
return QImage();
}
+QWaylandBufferRef::BufferFormatEgl SurfaceBuffer::bufferFormatEgl() const
+{
+ Q_ASSERT(isShm() == false);
+
+ if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
+ return clientInt->bufferFormat(m_buffer);
+
+ return QWaylandBufferRef::BufferFormatEgl_Null;
+}
+
void SurfaceBuffer::bindToTexture() const
{
Q_ASSERT(m_compositor);
@@ -221,14 +231,6 @@ void SurfaceBuffer::bindToTexture() const
}
}
-int SurfaceBuffer::textureTarget() const
-{
- if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
- return clientInt->textureTargetForBuffer(m_buffer);
-
- 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 1d186e2d8..85f78d41b 100644
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
@@ -54,6 +54,7 @@
#include <QAtomicInt>
#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandBufferRef>
#include <wayland-server.h>
@@ -103,7 +104,7 @@ public:
bool isShm() const { return wl_shm_buffer_get(m_buffer); }
QImage image() const;
- int textureTarget() const;
+ QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const;
void bindToTexture() const;
void updateTexture() const;
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
index d573edfcb..e6b68225b 100644
--- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
@@ -51,11 +51,43 @@
#include <QtPlatformSupport/private/qeglstreamconvenience_p.h>
#ifndef GL_TEXTURE_EXTERNAL_OES
-#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#endif
#ifndef EGL_WAYLAND_BUFFER_WL
-#define EGL_WAYLAND_BUFFER_WL 0x31D5
+#define EGL_WAYLAND_BUFFER_WL 0x31D5
+#endif
+
+#ifndef EGL_WAYLAND_PLANE_WL
+#define EGL_WAYLAND_PLANE_WL 0x31D6
+#endif
+
+#ifndef EGL_WAYLAND_Y_INVERTED_WL
+#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
+#endif
+
+#ifndef EGL_TEXTURE_RGB
+#define EGL_TEXTURE_RGB 0x305D
+#endif
+
+#ifndef EGL_TEXTURE_RGBA
+#define EGL_TEXTURE_RGBA 0x305E
+#endif
+
+#ifndef EGL_TEXTURE_EXTERNAL_WL
+#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
+#endif
+
+#ifndef EGL_TEXTURE_Y_U_V_WL
+#define EGL_TEXTURE_Y_U_V_WL 0x31D7
+#endif
+
+#ifndef EGL_TEXTURE_Y_UV_WL
+#define EGL_TEXTURE_Y_UV_WL 0x31D8
+#endif
+
+#ifndef EGL_TEXTURE_Y_XUXV_WL
+#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
#endif
/* Needed for compatibility with Mesa older than 10.0. */
@@ -80,93 +112,240 @@ QT_BEGIN_NAMESPACE
struct BufferState
{
- BufferState()
- : gl_texture(0)
- , gl_texture_target(GL_TEXTURE_2D)
- , egl_stream(EGL_NO_STREAM_KHR)
- , isYInverted(true)
- {}
-
- GLuint gl_texture;
- GLenum gl_texture_target;
+ BufferState();
+
+ EGLint egl_format;
+ QVarLengthArray<EGLImageKHR, 3> egl_images;
EGLStreamKHR egl_stream;
+
bool isYInverted;
QSize size;
};
-struct buffer_destroy_listener
+class WaylandEglClientBufferIntegrationPrivate
{
- struct wl_listener listener;
- class WaylandEglClientBufferIntegrationPrivate *d;
+public:
+ WaylandEglClientBufferIntegrationPrivate();
+
+ void attach(struct ::wl_resource *buffer);
+ void attach_egl_texture(struct ::wl_resource *buffer, EGLint format);
+ void attach_egl_fd_texture(struct ::wl_resource *buffer, EGLNativeFileDescriptorKHR streamFd);
+ void register_buffer(struct ::wl_resource *buffer, BufferState state);
+ void bindBuffer(struct ::wl_resource *buffer);
+
+ static void handle_buffer_destroy(wl_listener *listener, void *data);
+
+ EGLDisplay egl_display;
+ bool valid;
+ bool display_bound;
+ QHash<struct ::wl_resource *, BufferState> buffers;
+
+ PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display;
+ PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display;
+ PFNEGLQUERYWAYLANDBUFFERWL_compat egl_query_wayland_buffer;
+
+ PFNEGLCREATEIMAGEKHRPROC egl_create_image;
+ PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image;
+
+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d;
+
+ QEGLStreamConvenience *funcs;
};
-class WaylandEglClientBufferIntegrationPrivate
+struct buffer_destroy_listener : wl_listener
{
-public:
- WaylandEglClientBufferIntegrationPrivate()
- : egl_display(EGL_NO_DISPLAY)
- , valid(false)
- , display_bound(false)
- , egl_bind_wayland_display(0)
- , egl_unbind_wayland_display(0)
- , egl_query_wayland_buffer(0)
- , egl_create_image(0)
- , egl_destroy_image(0)
- , gl_egl_image_target_texture_2d(0)
- , funcs(Q_NULLPTR)
+ buffer_destroy_listener()
+ : d(0)
{
+ notify = WaylandEglClientBufferIntegrationPrivate::handle_buffer_destroy;
+ wl_list_init(&this->link);
}
- static void destroy_listener_callback(wl_listener *listener, void *data) {
- static QMutex mutex;
- QMutexLocker locker(&mutex);
+ WaylandEglClientBufferIntegrationPrivate *d;
+};
- buffer_destroy_listener *destroy_listener = reinterpret_cast<buffer_destroy_listener *>(listener);
- WaylandEglClientBufferIntegrationPrivate *self = destroy_listener->d;
- struct ::wl_resource *buffer = static_cast<struct ::wl_resource *>(data);
+BufferState::BufferState()
+ : egl_format(EGL_TEXTURE_RGBA)
+ , egl_stream(EGL_NO_STREAM_KHR)
+ , isYInverted(true)
+{}
+
+WaylandEglClientBufferIntegrationPrivate::WaylandEglClientBufferIntegrationPrivate()
+ : egl_display(EGL_NO_DISPLAY)
+ , valid(false)
+ , display_bound(false)
+ , egl_bind_wayland_display(0)
+ , egl_unbind_wayland_display(0)
+ , egl_query_wayland_buffer(0)
+ , egl_create_image(0)
+ , egl_destroy_image(0)
+ , gl_egl_image_target_texture_2d(0)
+ , funcs(Q_NULLPTR)
+{}
+
+void WaylandEglClientBufferIntegrationPrivate::attach(struct ::wl_resource *buffer)
+{
+ EGLint format;
+ EGLNativeFileDescriptorKHR streamFd = EGL_NO_FILE_DESCRIPTOR_KHR;
- wl_list_remove(&listener->link);
- delete listener;
+ if (egl_query_wayland_buffer(egl_display, buffer, EGL_TEXTURE_FORMAT, &format))
+ attach_egl_texture(buffer, format);
+ else if (egl_query_wayland_buffer(egl_display, buffer, EGL_WAYLAND_BUFFER_WL, &streamFd))
+ attach_egl_fd_texture(buffer, streamFd);
+}
- if (!self->buffers.contains(buffer))
- return;
+void WaylandEglClientBufferIntegrationPrivate::attach_egl_texture(struct ::wl_resource *buffer, EGLint format)
+{
+ // Resolving GL functions may need a context current, so do it only here.
+ if (!gl_egl_image_target_texture_2d)
+ gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
- Q_ASSERT(self);
- Q_ASSERT(buffer);
+ if (!gl_egl_image_target_texture_2d) {
+ qWarning("QtCompositor: bindTextureToBuffer() failed. Could not find glEGLImageTargetTexture2DOES.");
+ return;
+ }
- BufferState state = self->buffers.take(buffer);
+ BufferState state;
+ state.egl_format = format;
- if (state.gl_texture != 0)
- glDeleteTextures(1, &state.gl_texture);
+#if defined(EGL_WAYLAND_Y_INVERTED_WL)
+ EGLint isYInverted;
+ EGLBoolean ret = egl_query_wayland_buffer(egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);
+ // Yes, this looks strange, but the specification says that EGL_FALSE return
+ // value (not supported) should be treated the same as EGL_TRUE return value
+ // and EGL_TRUE in value.
+ state.isYInverted = (ret == EGL_FALSE || isYInverted == EGL_TRUE);
+#endif
- if (state.egl_stream != EGL_NO_STREAM_KHR)
- self->funcs->destroy_stream(self->egl_display, state.egl_stream);
+ int planes = 1;
+
+ switch (format) {
+ default:
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
+ case EGL_TEXTURE_EXTERNAL_WL:
+ planes = 1;
+ break;
+ case EGL_TEXTURE_Y_UV_WL:
+ planes = 2;
+ break;
+ case EGL_TEXTURE_Y_U_V_WL:
+ planes = 3;
+ break;
+ case EGL_TEXTURE_Y_XUXV_WL:
+ planes = 2;
+ break;
}
- void create_destroy_listener(struct ::wl_resource *buffer) {
- buffer_destroy_listener *newListener = new buffer_destroy_listener;
- newListener->d = this;
- newListener->listener.notify = destroy_listener_callback;
+ for (int i = 0; i < planes; i++) {
+ const EGLint attribs[] = { EGL_WAYLAND_PLANE_WL, i, EGL_NONE };
+ EGLImageKHR image = egl_create_image(egl_display,
+ EGL_NO_CONTEXT,
+ EGL_WAYLAND_BUFFER_WL,
+ buffer,
+ attribs);
+
+ if (image == EGL_NO_IMAGE_KHR)
+ qWarning("failed to create EGL image for plane %d", i);
- wl_signal_add(&buffer->destroy_signal, &newListener->listener);
+ state.egl_images << image;
}
- EGLDisplay egl_display;
- bool valid;
- bool display_bound;
- QHash<struct ::wl_resource *, BufferState> buffers;
+ register_buffer(buffer, state);
+}
- PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display;
- PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display;
- PFNEGLQUERYWAYLANDBUFFERWL_compat egl_query_wayland_buffer;
+void WaylandEglClientBufferIntegrationPrivate::attach_egl_fd_texture(struct ::wl_resource *buffer, EGLNativeFileDescriptorKHR streamFd)
+{
+ BufferState state;
- PFNEGLCREATEIMAGEKHRPROC egl_create_image;
- PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image;
+ state.egl_format = EGL_TEXTURE_EXTERNAL_WL;
+ state.isYInverted = false;
+ state.egl_stream = funcs->create_stream_from_file_descriptor(egl_display, streamFd);
- PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d;
+ close(streamFd);
- QEGLStreamConvenience *funcs;
-};
+ if (state.egl_stream == EGL_NO_STREAM_KHR) {
+ qWarning("%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
+ return;
+ }
+
+ register_buffer(buffer, state);
+}
+
+void WaylandEglClientBufferIntegrationPrivate::register_buffer(struct ::wl_resource *buffer, BufferState state)
+{
+ Q_ASSERT(!buffers.contains(buffer));
+
+ EGLint width, height;
+ egl_query_wayland_buffer(egl_display, buffer, EGL_WIDTH, &width);
+ egl_query_wayland_buffer(egl_display, buffer, EGL_HEIGHT, &height);
+ state.size = QSize(width, height);
+
+ buffers[buffer] = state;
+
+ buffer_destroy_listener *destroy_listener = new buffer_destroy_listener;
+ destroy_listener->d = this;
+ wl_signal_add(&buffer->destroy_signal, destroy_listener);
+}
+
+void WaylandEglClientBufferIntegrationPrivate::bindBuffer(struct ::wl_resource *buffer)
+{
+ if (!valid) {
+ qWarning("QtCompositor: bindTextureToBuffer() failed");
+ return;
+ }
+
+ if (!buffer || !buffers.contains(buffer))
+ return;
+
+ const BufferState state = buffers.value(buffer);
+
+ if (state.egl_stream != EGL_NO_STREAM_KHR) {
+ if (funcs->stream_consumer_gltexture(egl_display, state.egl_stream) != EGL_TRUE)
+ qWarning("%s:%d: eglStreamConsumerGLTextureExternalKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
+ } else {
+ GLint previousTexture = GL_TEXTURE0;
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &previousTexture);
+
+ const GLenum target = (state.egl_format == EGL_TEXTURE_EXTERNAL_WL) ? GL_TEXTURE_EXTERNAL_OES
+ : GL_TEXTURE_2D;
+
+ for (int i = 0; i < state.egl_images.size(); i++) {
+ glActiveTexture(GL_TEXTURE0 + i);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_egl_image_target_texture_2d(target, state.egl_images[i]);
+ }
+
+ glActiveTexture(previousTexture);
+ }
+}
+
+void WaylandEglClientBufferIntegrationPrivate::handle_buffer_destroy(wl_listener *listener, void *data)
+{
+ buffer_destroy_listener *destroy_listener = static_cast<buffer_destroy_listener *>(listener);
+ WaylandEglClientBufferIntegrationPrivate *self = destroy_listener->d;
+ struct ::wl_resource *buffer = static_cast<struct ::wl_resource *>(data);
+
+ wl_list_remove(&destroy_listener->link);
+ delete destroy_listener;
+
+ if (!self->buffers.contains(buffer))
+ return;
+
+ Q_ASSERT(self);
+ Q_ASSERT(buffer);
+
+ BufferState state = self->buffers.take(buffer);
+
+ for (int i = 0; i < state.egl_images.size(); i++)
+ self->egl_destroy_image(self->egl_display, state.egl_images[i]);
+
+ if (state.egl_stream != EGL_NO_STREAM_KHR)
+ self->funcs->destroy_stream(self->egl_display, state.egl_stream);
+}
WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration()
: QtWayland::ClientBufferIntegration()
@@ -236,24 +415,6 @@ void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *di
d->valid = true;
}
-static GLuint make_texture(GLenum target)
-{
- GLuint texture;
-
- glGenTextures(1, &texture);
- glBindTexture(target, texture);
-
- return texture;
-}
-
-static void set_texture_params(GLenum target)
-{
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
void WaylandEglClientBufferIntegration::initializeBuffer(struct ::wl_resource *buffer)
{
Q_D(WaylandEglClientBufferIntegration);
@@ -264,88 +425,38 @@ void WaylandEglClientBufferIntegration::initializeBuffer(struct ::wl_resource *b
if (!buffer || d->buffers.contains(buffer))
return;
- d->create_destroy_listener(buffer);
+ d->attach(buffer);
+}
+
+static QWaylandBufferRef::BufferFormatEgl formatFromEglFormat(EGLint format) {
+ switch (format) {
+ case EGL_TEXTURE_RGB:
+ return QWaylandBufferRef::BufferFormatEgl_RGB;
+ case EGL_TEXTURE_RGBA:
+ return QWaylandBufferRef::BufferFormatEgl_RGBA;
+ case EGL_TEXTURE_EXTERNAL_WL:
+ return QWaylandBufferRef::BufferFormatEgl_EXTERNAL_OES;
+ case EGL_TEXTURE_Y_UV_WL:
+ return QWaylandBufferRef::BufferFormatEgl_Y_UV;
+ case EGL_TEXTURE_Y_U_V_WL:
+ return QWaylandBufferRef::BufferFormatEgl_Y_U_V;
+ case EGL_TEXTURE_Y_XUXV_WL:
+ return QWaylandBufferRef::BufferFormatEgl_Y_XUXV;
+ }
+
+ return QWaylandBufferRef::BufferFormatEgl_RGBA;
}
-int WaylandEglClientBufferIntegration::textureTargetForBuffer(struct ::wl_resource *buffer) const
+QWaylandBufferRef::BufferFormatEgl WaylandEglClientBufferIntegration::bufferFormat(wl_resource *buffer)
{
Q_D(const WaylandEglClientBufferIntegration);
-
- return d->buffers.value(buffer).gl_texture_target;
+ return formatFromEglFormat(d->buffers.value(buffer).egl_format);
}
void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
{
Q_D(WaylandEglClientBufferIntegration);
- if (!d->valid) {
- qWarning("QtCompositor: bindTextureToBuffer() failed");
- return;
- }
-
- if (!buffer)
- return;
-
- BufferState state = d->buffers.value(buffer);
-
- if (state.egl_stream != EGL_NO_STREAM_KHR) {
- d->funcs->stream_consumer_acquire(d->egl_display, state.egl_stream);
- } else {
- Q_ASSERT(QOpenGLContext::currentContext());
-
- EGLint format;
- EGLNativeFileDescriptorKHR streamFd = EGL_NO_FILE_DESCRIPTOR_KHR;
-
- if (d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_TEXTURE_FORMAT, &format)) {
- // Resolving GL functions may need a context current, so do it only here.
- if (!d->gl_egl_image_target_texture_2d)
- d->gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
-
- if (!d->gl_egl_image_target_texture_2d) {
- qWarning("QtCompositor: bindTextureToBuffer() failed. Could not find glEGLImageTargetTexture2DOES.");
- return;
- }
-
- EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT,
- EGL_WAYLAND_BUFFER_WL,
- buffer, NULL);
-
- d->gl_egl_image_target_texture_2d(GL_TEXTURE_2D, image);
- set_texture_params(GL_TEXTURE_2D);
- d->egl_destroy_image(d->egl_display, image);
- } else if (d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_BUFFER_WL, &streamFd)) {
- state.egl_stream = d->funcs->create_stream_from_file_descriptor(d->egl_display, streamFd);
- close(streamFd);
-
- if (state.egl_stream == EGL_NO_STREAM_KHR) {
- qWarning("%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
- return;
- }
-
- state.isYInverted = false;
- state.gl_texture_target = GL_TEXTURE_EXTERNAL_OES;
- state.gl_texture = make_texture(state.gl_texture_target);
- set_texture_params(state.gl_texture_target);
-
- if (d->funcs->stream_consumer_gltexture(d->egl_display, state.egl_stream) != EGL_TRUE)
- qWarning("%s:%d: eglStreamConsumerGLTextureExternalKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
- }
-
- EGLint width, height;
- d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &width);
- d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_HEIGHT, &height);
- state.size = QSize(width, height);
-
-#if defined(EGL_WAYLAND_Y_INVERTED_WL)
- EGLint isYInverted;
- EGLBoolean ret = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);
- // Yes, this looks strange, but the specification says that EGL_FALSE return
- // value (not supported) should be treated the same as EGL_TRUE return value
- // and EGL_TRUE in value.
- state.isYInverted = (ret == EGL_FALSE || isYInverted == EGL_TRUE);
-#endif
-
- d->buffers[buffer] = state;
- }
+ d->bindBuffer(buffer);
}
// Update is only needed for the EGLStream path as that requires calling acquire
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
index 18893645a..57e83717a 100644
--- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
+++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
@@ -53,7 +53,7 @@ public:
void initializeHardware(struct ::wl_display *display) Q_DECL_OVERRIDE;
void initializeBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- int textureTargetForBuffer(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
+ QWaylandBufferRef::BufferFormatEgl bufferFormat(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
void updateTextureForBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;