summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2012-04-16 21:24:41 +0200
committerQt by Nokia <qt-info@nokia.com>2012-04-16 21:42:19 +0200
commitc2cd2a0cb8b471165c0e690fe5c70a0e0bbcf5ae (patch)
tree500addd228c8246a5bb6f376ea73c738fecf2abc /src/plugins/platforms/eglfs
parent0e317af13f24d88a88c41f5efbd3fe9180ec6bee (diff)
Implemented raster based backing store for EGLFS plugin.
This improves quality of rendering for QWidget-based applications a bit. Change-Id: I6b832d1de7e722f4dbe4e82882f5db35f0b8c30c Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
Diffstat (limited to 'src/plugins/platforms/eglfs')
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp123
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.h17
2 files changed, 138 insertions, 2 deletions
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
index 8e9e5f76e0..48ac680043 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
@@ -43,12 +43,19 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice>
+#include <QtGui/QOpenGLShaderProgram>
+
+#include <QtGui/QScreen>
QT_BEGIN_NAMESPACE
QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
: QPlatformBackingStore(window)
, m_context(new QOpenGLContext)
+#ifdef EGLFS_BACKINGSTORE_USE_IMAGE
+ , m_texture(0)
+ , m_program(0)
+#endif
{
m_context->setFormat(window->requestedFormat());
m_context->setScreen(window->screen());
@@ -62,7 +69,11 @@ QEglFSBackingStore::~QEglFSBackingStore()
QPaintDevice *QEglFSBackingStore::paintDevice()
{
+#ifdef EGLFS_BACKINGSTORE_USE_IMAGE
+ return &m_image;
+#else
return m_device;
+#endif
}
void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
@@ -74,27 +85,135 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPo
qWarning("QEglBackingStore::flush %p", window);
#endif
+#ifdef EGLFS_BACKINGSTORE_USE_IMAGE
+ 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);\n"
+ "}\n";
+
+ m_program = new QOpenGLShaderProgram;
+
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_program->link();
+
+ m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
+ }
+
+ m_program->bind();
+
+ const GLfloat textureCoordinates[] = {
+ 0, 1,
+ 1, 1,
+ 1, 0,
+ 0, 0
+ };
+
+ 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 = (r.top() / sr.height()) * 2 - 1;
+ GLfloat y2 = (r.bottom() / sr.height()) * 2 - 1;
+
+ const GLfloat vertexCoordinates[] = {
+ x1, y1,
+ x2, y1,
+ x2, y2,
+ x1, y2
+ };
+
+ glEnableVertexAttribArray(m_vertexCoordEntry);
+ glEnableVertexAttribArray(m_textureCoordEntry);
+
+ glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
+ glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+
+ foreach (const QRect &rect, m_dirty.rects()) {
+ if (rect == m_image.rect()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_image.constBits());
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.copy(rect).constBits());
+ }
+ }
+
+ m_dirty = QRegion();
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glDisableVertexAttribArray(m_vertexCoordEntry);
+ glDisableVertexAttribArray(m_textureCoordEntry);
+#endif
+
m_context->swapBuffers(window);
}
-void QEglFSBackingStore::beginPaint(const QRegion &)
+void QEglFSBackingStore::makeCurrent()
{
// needed to prevent QOpenGLContext::makeCurrent() from failing
window()->setSurfaceType(QSurface::OpenGLSurface);
m_context->makeCurrent(window());
+}
+
+void QEglFSBackingStore::beginPaint(const QRegion &rgn)
+{
+ makeCurrent();
+
+#ifdef EGLFS_BACKINGSTORE_USE_IMAGE
+ m_dirty = m_dirty | rgn;
+#else
+ Q_UNUSED(rgn);
m_device = new QOpenGLPaintDevice(window()->size());
+#endif
}
void QEglFSBackingStore::endPaint()
{
+#ifndef EGLFS_BACKINGSTORE_USE_IMAGE
delete m_device;
+#endif
}
void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
- Q_UNUSED(size);
Q_UNUSED(staticContents);
+
+#ifdef EGLFS_BACKINGSTORE_USE_IMAGE
+ m_image = QImage(size, QImage::Format_RGB32);
+ makeCurrent();
+ 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);
+#else
+ Q_UNUSED(size);
+#endif
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
index 97ea322420..f723bca685 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
@@ -44,10 +44,16 @@
#include <QtGui/qplatformbackingstore_qpa.h>
+#include <QImage>
+#include <QRegion>
+
+#define EGLFS_BACKINGSTORE_USE_IMAGE
+
QT_BEGIN_NAMESPACE
class QOpenGLContext;
class QOpenGLPaintDevice;
+class QOpenGLShaderProgram;
class QEglFSBackingStore : public QPlatformBackingStore
{
@@ -64,8 +70,19 @@ public:
void resize(const QSize &size, const QRegion &staticContents);
private:
+ void makeCurrent();
+
QOpenGLContext *m_context;
+#ifdef EGLFS_BACKINGSTORE_USE_IMAGE
+ QImage m_image;
+ uint m_texture;
+ QRegion m_dirty;
+ QOpenGLShaderProgram *m_program;
+ int m_vertexCoordEntry;
+ int m_textureCoordEntry;
+#else
QOpenGLPaintDevice *m_device;
+#endif
};
QT_END_NAMESPACE