diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-10-27 22:01:38 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2011-01-25 18:01:05 (GMT) |
commit | 4a3d4dcdcf2782530c76a6aff4775ec5f8ebd157 (patch) | |
tree | b0e278f7e6b2998eec80f1941dacb0c8b46404d6 | |
parent | cbe7ab5f5da9c14fb6acef3f6d29b319ec2dcc4a (diff) | |
download | Qt-4a3d4dcdcf2782530c76a6aff4775ec5f8ebd157.zip Qt-4a3d4dcdcf2782530c76a6aff4775ec5f8ebd157.tar.gz Qt-4a3d4dcdcf2782530c76a6aff4775ec5f8ebd157.tar.bz2 |
Wayland: add GL widget support
Make sure we copy from the private surface into the parent surface at
swapBuffers time.
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandintegration.cpp | 99 | ||||
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindowsurface.h | 1 |
2 files changed, 96 insertions, 4 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 29cd0ee..a3237fb 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -17,6 +17,7 @@ #include <private/qwindowsurface_gl_p.h> #include <private/qpixmapdata_gl_p.h> +#include <private/qpaintengineex_opengl2_p.h> #include "qwaylandintegration.h" #include "qwaylandwindowsurface.h" @@ -547,14 +548,106 @@ void QWaylandGLContext::doneCurrent() { } +static void drawTexture(const QRectF &rect, GLuint tex_id, + const QSize &texSize, const QRectF &br) +{ + QRectF src = br.isEmpty() + ? QRectF(QPointF(), texSize) + : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size()); + qreal width = texSize.width(); + qreal height = texSize.height(); + + src.setLeft(src.left() / width); + src.setRight(src.right() / width); + src.setTop(src.top() / height); + src.setBottom(src.bottom() / height); + + const GLfloat tx1 = src.left(); + const GLfloat tx2 = src.right(); + const GLfloat ty1 = src.top(); + const GLfloat ty2 = src.bottom(); + + GLfloat texCoordArray[4*2] = { + tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1 + }; + + GLfloat vertexArray[4*2]; + extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); + qt_add_rect_to_array(rect, vertexArray); + + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray); + glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray); + + glBindTexture(GL_TEXTURE_2D, tex_id); + + glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + + glBindTexture(GL_TEXTURE_2D, 0); +} + void QWaylandGLContext::swapBuffers() { - QRect geometry = mWindow->geometry(); + QWaylandWindow *mParentWindow = mWindow->getParentWindow(); + QWaylandDrmBuffer *mBuffer, *mParentBuffer; + QRect geometry = mWindow->geometry(), parentGeometry; + GLuint parentFbo, parentRbo; - if (!mWindow->surface()) + if (!mParentWindow) { + qDebug("swap without parent widget?\n"); return; + } + + if (!mParentWindow->surface()) { + qDebug("parent has no surface??\n"); + return; + } + + parentGeometry = mParentWindow->geometry(); + mBuffer = (QWaylandDrmBuffer *)mWindow->getBuffer(); + mParentBuffer = (QWaylandDrmBuffer *)mParentWindow->getBuffer(); + + qDebug("copying from texture image %d, texture %d to image %d, texture %d\n", + mBuffer->mImage, mBuffer->mTexture, mParentBuffer->mImage, mParentBuffer->mTexture); + + glDisable(GL_DEPTH_TEST); + + glGenFramebuffers(1, &parentFbo); + glGenRenderbuffers(1, &parentRbo); + glBindFramebuffer(GL_FRAMEBUFFER, parentFbo); + glBindRenderbuffer(GL_RENDERBUFFER, parentRbo); + glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mParentBuffer->mImage); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, parentRbo); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mBuffer->mImage); + glViewport(0, 0, geometry.width(), geometry.height()); + + QGLShaderProgram *blitProgram = + QGLEngineSharedShaders::shadersForContext(QGLContext::currentContext())->blitProgram(); + blitProgram->bind(); + blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/); + // The shader manager's blit program does not multiply the + // vertices by the pmv matrix, so we need to do the effect + // of the orthographic projection here ourselves. + QRectF r; + qreal w = geometry.width() ? geometry.width() : 1.0f; + qreal h = geometry.height() ? geometry.height() : 1.0f; + r.setLeft((geometry.left() / w) * 2.0f - 1.0f); + if (geometry.right() == (geometry.width() - 1)) + r.setRight(1.0f); + else + r.setRight((geometry.right() / w) * 2.0f - 1.0f); + r.setBottom((geometry.top() / h) * 2.0f - 1.0f); + if (geometry.bottom() == (geometry.height() - 1)) + r.setTop(1.0f); + else + r.setTop((geometry.bottom() / w) * 2.0f - 1.0f); + drawTexture(r, mBuffer->mTexture, mWindow->widget()->size(), geometry); - wl_surface_damage(mWindow->surface(), 0, 0, + wl_surface_damage(mParentWindow->surface(), 0, 0, geometry.width(), geometry.height()); } diff --git a/src/plugins/platforms/wayland/qwaylandwindowsurface.h b/src/plugins/platforms/wayland/qwaylandwindowsurface.h index eb9cc40..21c48f9 100644 --- a/src/plugins/platforms/wayland/qwaylandwindowsurface.h +++ b/src/plugins/platforms/wayland/qwaylandwindowsurface.h @@ -97,7 +97,6 @@ public: EGLImageKHR mImage; GLuint mTexture; QWaylandDisplay *mDisplay; - QGLFramebufferObject *pdev; QSize mSize; GLuint mFbo; }; |