diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-10-15 18:26:00 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-10-20 14:58:29 +0000 |
commit | 955ac0d0eeaf2f543676b649291558f4dcce37c3 (patch) | |
tree | 7217e1c805f1386d89f0dccbafbe2ae4f5e40409 /examples/wayland | |
parent | 3a584414d9df972721a4fbf4b1088bce5e95484b (diff) |
Support EGLStream in wayland-egl
For Wayland on NVIDIA. Tested with a Jetson TK1 Pro and Vibrante Linux.
With just the hw integration no compositors would work out of the box
since EGL_KHR_stream_consumer_gltexture only allows connecting to the
texture bound to GL_TEXTURE_EXTERNAL_OES, meaning that assumptions about
the target always being GL_TEXTURE_2D break horribly both in C++ and in
shader code.
In addition, buffers have to be extended with an additional updateTexture()
operation as EGLStream requires to call ConsumerAcquire on every
frame. Previously there was no concept of this as calling
createTexture() on attach() was sufficient.
Qt Quick bits are omitted since the refactored compositor API is pretty
different. This means that QML compositors will not currently function
in this environment.
The qwindow-compositor example is enhanced to support the external
texture target, but this won't apply for the refactored branch
either. It is provided for testing purposes for the time being, and to
show how C++ compositors can support different texture targets and
correct operation with EGLStreams.
Done-with: Louai Al-Khanji <louai.al-khanji@theqtcompany.com>
Change-Id: I0e209fc0cbcf435cca83528d938eb50e4bdceb82
Reviewed-by: Louai Al-Khanji <louai.al-khanji@theqtcompany.com>
Diffstat (limited to 'examples/wayland')
3 files changed, 60 insertions, 14 deletions
diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp index 5d338692f..4e3f6336b 100644 --- a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp +++ b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp @@ -92,8 +92,10 @@ public: shmTex = new QOpenGLTexture(bufferRef.image(), QOpenGLTexture::DontGenerateMipMaps); shmTex->setWrapMode(QOpenGLTexture::ClampToEdge); texture = shmTex->textureId(); + textureTarget = GL_TEXTURE_2D; } else { texture = bufferRef.createTexture(); + textureTarget = bufferRef.textureTarget(); } } } @@ -112,9 +114,16 @@ public: return bufferRef.image(); } + void updateTexture() + { + if (bufferRef) + bufferRef.updateTexture(); + } + QOpenGLTexture *shmTex; QWaylandBufferRef bufferRef; GLuint texture; + GLenum textureTarget; }; QWindowCompositor::QWindowCompositor(CompositorWindow *window) @@ -326,7 +335,7 @@ void QWindowCompositor::render() if (!m_backgroundTexture) m_backgroundTexture = new QOpenGLTexture(m_backgroundImage, QOpenGLTexture::DontGenerateMipMaps); - m_textureBlitter->bind(); + m_textureBlitter->bind(GL_TEXTURE_2D); // Draw the background image texture m_textureBlitter->drawTexture(m_backgroundTexture->textureId(), QRect(QPoint(0, 0), m_backgroundImage.size()), @@ -336,7 +345,11 @@ void QWindowCompositor::render() foreach (QWaylandSurface *surface, m_surfaces) { if (!surface->visible()) continue; - GLuint texture = static_cast<BufferAttacher *>(surface->bufferAttacher())->texture; + BufferAttacher *ba = static_cast<BufferAttacher *>(surface->bufferAttacher()); + ba->updateTexture(); + const GLuint texture = ba->texture; + const GLenum target = ba->textureTarget; + m_textureBlitter->bind(target); foreach (QWaylandSurfaceView *view, surface->views()) { QRect geo(view->pos().toPoint(),surface->size()); m_textureBlitter->drawTexture(texture,geo,m_window->size(),0,false,surface->isYInverted()); diff --git a/examples/wayland/qwindow-compositor/textureblitter.cpp b/examples/wayland/qwindow-compositor/textureblitter.cpp index a9acfc026..c550985de 100644 --- a/examples/wayland/qwindow-compositor/textureblitter.cpp +++ b/examples/wayland/qwindow-compositor/textureblitter.cpp @@ -48,6 +48,9 @@ QT_BEGIN_NAMESPACE TextureBlitter::TextureBlitter() : m_shaderProgram(new QOpenGLShaderProgram) + , m_shaderProgramExternal(new QOpenGLShaderProgram) + , m_currentProgram(0) + , m_currentTarget(GL_TEXTURE_2D) { static const char *textureVertexProgram = "uniform highp mat4 matrix;\n" @@ -66,33 +69,58 @@ TextureBlitter::TextureBlitter() " gl_FragColor = texture2D(texture, textureCoord);\n" "}\n"; - //Enable transparent windows - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + static const char *textureFragmentProgramExternal = + "#extension GL_OES_EGL_image_external : require\n" + "uniform samplerExternalOES texture;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " gl_FragColor = texture2D(texture, textureCoord);\n" + "}\n"; m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); m_shaderProgram->link(); + + m_shaderProgramExternal->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); + m_shaderProgramExternal->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgramExternal); + m_shaderProgramExternal->link(); } TextureBlitter::~TextureBlitter() { delete m_shaderProgram; + delete m_shaderProgramExternal; } -void TextureBlitter::bind() +void TextureBlitter::bind(quint32 target) { + m_currentTarget = target; + switch (target) { + case GL_TEXTURE_2D: + m_currentProgram = m_shaderProgram; + break; + case GL_TEXTURE_EXTERNAL_OES: + m_currentProgram = m_shaderProgramExternal; + break; + default: + qFatal("INVALID TARGET TYPE %d", target); + break; + } - m_shaderProgram->bind(); + m_currentProgram->bind(); m_vertexCoordEntry = m_shaderProgram->attributeLocation("vertexCoordEntry"); m_textureCoordEntry = m_shaderProgram->attributeLocation("textureCoordEntry"); m_matrixLocation = m_shaderProgram->uniformLocation("matrix"); + + //Enable transparent windows + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void TextureBlitter::release() { - m_shaderProgram->release(); + m_currentProgram->release(); } void TextureBlitter::drawTexture(int textureId, const QRectF &targetRect, const QSize &targetSize, int depth, bool targethasInvertedY, bool sourceHasInvertedY) @@ -148,16 +176,17 @@ void TextureBlitter::drawTexture(int textureId, const QRectF &targetRect, const currentContext->functions()->glVertexAttribPointer(m_vertexCoordEntry, 3, GL_FLOAT, GL_FALSE, 0, vertexCoordinates); currentContext->functions()->glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates); - m_shaderProgram->setUniformValue(m_matrixLocation, m_transformMatrix); - glBindTexture(GL_TEXTURE_2D, textureId); + m_currentProgram->setUniformValue(m_matrixLocation, m_transformMatrix); + + glBindTexture(m_currentTarget, textureId); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(m_currentTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(m_currentTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(m_currentTarget, 0); currentContext->functions()->glDisableVertexAttribArray(m_vertexCoordEntry); currentContext->functions()->glDisableVertexAttribArray(m_textureCoordEntry); diff --git a/examples/wayland/qwindow-compositor/textureblitter.h b/examples/wayland/qwindow-compositor/textureblitter.h index b46d354e0..85e2bbfb4 100644 --- a/examples/wayland/qwindow-compositor/textureblitter.h +++ b/examples/wayland/qwindow-compositor/textureblitter.h @@ -51,7 +51,7 @@ class TextureBlitter public: TextureBlitter(); ~TextureBlitter(); - void bind(); + void bind(quint32 target); void release(); void drawTexture(int textureId, const QRectF &sourceGeometry, const QSize &targetRect, int depth, @@ -59,11 +59,15 @@ public: private: QOpenGLShaderProgram *m_shaderProgram; + QOpenGLShaderProgram *m_shaderProgramExternal; + QOpenGLShaderProgram *m_currentProgram; QMatrix4x4 m_transformMatrix; int m_matrixLocation; int m_vertexCoordEntry; int m_textureCoordEntry; + + quint32 m_currentTarget; }; QT_END_NAMESPACE |