diff options
author | Laszlo Agocs <laszlo.p.agocs@nokia.com> | 2012-07-21 14:20:33 +0300 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-07-23 19:57:07 +0200 |
commit | 7a3dd20b98679abaa7fda9dd6bed3667f75b103a (patch) | |
tree | fe48953c83c68dfb5a66e06936ee14c1a590fce7 /src | |
parent | c2942cb7b6b8d06ebb8156dc9fb2bda4a4cc7c9e (diff) |
Add basic backingstore implementation to kms
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 <samuel.rodal@nokia.com>
Reviewed-by: Elvis Lee <kwangwoong.lee@lge.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/kms/qkmsbackingstore.cpp | 123 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmsbackingstore.h | 11 |
2 files changed, 130 insertions, 4 deletions
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 <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLShaderProgram> +#include <QtGui/QScreen> + 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 |