summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2012-07-21 14:20:33 +0300
committerQt by Nokia <qt-info@nokia.com>2012-07-23 19:57:07 +0200
commit7a3dd20b98679abaa7fda9dd6bed3667f75b103a (patch)
treefe48953c83c68dfb5a66e06936ee14c1a590fce7 /src
parentc2942cb7b6b8d06ebb8156dc9fb2bda4a4cc7c9e (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.cpp123
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h11
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 &region, 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 &region, 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 &region, 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