From 7a3dd20b98679abaa7fda9dd6bed3667f75b103a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sat, 21 Jul 2012 14:20:33 +0300 Subject: Add basic backingstore implementation to kms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows using the kms plugin in QWidget apps having a single (preferably fullscreen) top-level widget. Based on eglfs' implementation. Dirty rectangle tracking is missing, should be added later. There is no composition so multiple TLWs will not work nicely. Change-Id: Ia78589d1a375925ebdcc46aa20fc1619ec14d6cc Reviewed-by: Samuel Rødal Reviewed-by: Elvis Lee --- src/plugins/platforms/kms/qkmsbackingstore.cpp | 123 ++++++++++++++++++++++++- src/plugins/platforms/kms/qkmsbackingstore.h | 11 +++ 2 files changed, 130 insertions(+), 4 deletions(-) (limited to 'src/plugins/platforms/kms') diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp index d32f9f1775..9fb828ab26 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.cpp +++ b/src/plugins/platforms/kms/qkmsbackingstore.cpp @@ -41,11 +41,31 @@ #include "qkmsbackingstore.h" +#include +#include +#include + QT_BEGIN_NAMESPACE QKmsBackingStore::QKmsBackingStore(QWindow *window) : QPlatformBackingStore(window) + , m_context(new QOpenGLContext) + , m_texture(0) + , m_program(0) { + m_context->setFormat(window->requestedFormat()); + m_context->setScreen(window->screen()); + m_context->create(); + window->setSurfaceType(QSurface::OpenGLSurface); +} + +QKmsBackingStore::~QKmsBackingStore() +{ + delete m_program; + if (m_texture) + glDeleteTextures(1, &m_texture); + + delete m_context; } QPaintDevice *QKmsBackingStore::paintDevice() @@ -53,20 +73,115 @@ QPaintDevice *QKmsBackingStore::paintDevice() return &m_image; } -void QKmsBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +void QKmsBackingStore::beginPaint(const QRegion &) +{ +} + +void QKmsBackingStore::endPaint() { - //'window' can be a child window, in which case 'region' is in child window coordinates and - // offset is the (child) window's offset in relation to the window surface. +} +void QKmsBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ Q_UNUSED(region) Q_UNUSED(offset) - Q_UNUSED(window) + + m_context->makeCurrent(window); + + if (!m_program) { + static const char *textureVertexProgram = + "attribute highp vec2 vertexCoordEntry;\n" + "attribute highp vec2 textureCoordEntry;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " textureCoord = textureCoordEntry;\n" + " gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n" + "}\n"; + + static const char *textureFragmentProgram = + "uniform sampler2D texture;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " gl_FragColor = texture2D(texture, textureCoord).bgra;\n" + "}\n"; + + m_program = new QOpenGLShaderProgram; + + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); + m_program->bindAttributeLocation("vertexCoordEntry", 0); + m_program->bindAttributeLocation("textureCoordEntry", 1); + m_program->link(); + } + + m_program->bind(); + + QRectF r = window->geometry(); + QRectF sr = window->screen()->geometry(); + + GLfloat x1 = (r.left() / sr.width()) * 2 - 1; + GLfloat x2 = (r.right() / sr.width()) * 2 - 1; + GLfloat y1 = -1 * ((r.top() / sr.height()) * 2 - 1); + GLfloat y2 = -1 * ((r.bottom() / sr.height()) * 2 - 1); + + const GLfloat vertexCoordinates[] = { + x1, y1, + x2, y1, + x2, y2, + x1, y2 + }; + + const GLfloat textureCoordinates[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 + }; + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates); + + glBindTexture(GL_TEXTURE_2D, m_texture); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.constScanLine(0)); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + m_program->release(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + + m_context->swapBuffers(window); + + m_context->doneCurrent(); } void QKmsBackingStore::resize(const QSize &size, const QRegion &staticContents) { Q_UNUSED(staticContents) + m_image = QImage(size, QImage::Format_RGB32); + + m_context->makeCurrent(window()); + + if (m_texture) + glDeleteTextures(1, &m_texture); + + glGenTextures(1, &m_texture); + glBindTexture(GL_TEXTURE_2D, m_texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + } QT_END_NAMESPACE diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h index 59d9c9ad94..6357019210 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.h +++ b/src/plugins/platforms/kms/qkmsbackingstore.h @@ -47,17 +47,28 @@ QT_BEGIN_NAMESPACE +class QOpenGLContext; +class QOpenGLShaderProgram; + class QKmsBackingStore : public QPlatformBackingStore { public: QKmsBackingStore(QWindow *window); + ~QKmsBackingStore(); QPaintDevice *paintDevice(); + + void beginPaint(const QRegion &); + void endPaint(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); private: + QOpenGLContext *m_context; QImage m_image; + uint m_texture; + QOpenGLShaderProgram *m_program; }; QT_END_NAMESPACE -- cgit v1.2.3