diff options
Diffstat (limited to 'src/plugins/platforms/eglfs')
-rw-r--r-- | src/plugins/platforms/eglfs/eglfs.pro | 2 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfsbackingstore.cpp | 144 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfsbackingstore.h | 17 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfshooks_x11.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfsscreen.cpp | 14 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfswindow.cpp | 11 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfswindow.h | 1 |
8 files changed, 174 insertions, 22 deletions
diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index 421bbd5561..b3bbc4e3e4 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -7,8 +7,6 @@ DESTDIR = $$QT.gui.plugins/platforms #DEFINES += QEGL_EXTRA_DEBUG -#DEFINES += Q_OPENKODE - #Avoid X11 header collision DEFINES += MESA_EGL_NO_X11_HEADERS diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp index 8e9e5f76e0..5c1919a4f3 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 ®ion, const QPoint &offset) @@ -74,27 +85,156 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion ®ion, 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).bgra;\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); + + if (!m_dirty.isNull()) { + QRect imageRect = m_image.rect(); + + QRegion fixed; + foreach (const QRect &rect, m_dirty.rects()) { + // intersect with image rect to be sure + QRect r = imageRect & rect; + + // if the rect is wide enough it's cheaper to just + // extend it instead of doing an image copy + if (r.width() >= imageRect.width() / 2) { + r.setX(0); + r.setWidth(imageRect.width()); + } + + fixed |= r; + } + + foreach (const QRect &rect, fixed.rects()) { + // if the sub-rect is full-width we can pass the image data directly to + // OpenGL instead of copying, since there's no gap between scanlines + if (rect.width() == imageRect.width()) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_image.constScanLine(rect.y())); + } 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 diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index 7cc3527a0c..c0e202fb70 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -41,6 +41,8 @@ #include "qeglfshooks.h" +QT_BEGIN_NAMESPACE + void QEglFSHooks::platformInit() { } @@ -79,3 +81,5 @@ bool QEglFSHooks::hasCapability(QPlatformIntegration::Capability cap) const #ifndef EGLFS_PLATFORM_HOOKS QEglFSHooks stubHooks; #endif + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp b/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp index cb788c52f2..af750a73f1 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp @@ -43,6 +43,8 @@ #include <X11/Xlib.h> +QT_BEGIN_NAMESPACE + class QEglFSX11Hooks : public QEglFSHooks { public: @@ -108,3 +110,4 @@ bool QEglFSX11Hooks::hasCapability(QPlatformIntegration::Capability cap) const static QEglFSX11Hooks eglFSX11Hooks; QEglFSHooks *platformHooks = &eglFSX11Hooks; +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index ea939a9821..78f9e13150 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -46,11 +46,6 @@ #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglplatformcontext_p.h> -#ifdef Q_OPENKODE -#include <KD/kd.h> -#include <KD/NV_initialize.h> -#endif //Q_OPENKODE - QT_BEGIN_NAMESPACE // #define QEGL_EXTRA_DEBUG @@ -196,17 +191,8 @@ void QEglFSScreen::createAndSetPlatformContext() EGLConfig config = q_configFromGLFormat(m_dpy, platformFormat); -#ifdef Q_OPENKODE - if (kdInitializeNV() == KD_ENOTINITIALIZED) { - qFatal("Did not manage to initialize openkode"); - } - KDWindow *window = kdCreateWindow(m_dpy,config,0); - - kdRealizeWindow(window, &m_window); -#else if (hooks) m_window = hooks->createNativeWindow(hooks->screenSize()); -#endif #ifdef QEGL_EXTRA_DEBUG qWarning("Configuration %d matches requirements\n", (int)config); diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index f380542559..e9430eae40 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -54,10 +54,7 @@ QEglFSWindow::QEglFSWindow(QWindow *w) qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_winid)); #endif - QRect screenGeometry(screen()->availableGeometry()); - if (w->geometry() != screenGeometry) { - QWindowSystemInterface::handleGeometryChange(w, screenGeometry); - } + setWindowState(Qt::WindowFullScreen); } void QEglFSWindow::setGeometry(const QRect &) @@ -69,6 +66,12 @@ void QEglFSWindow::setGeometry(const QRect &) QPlatformWindow::setGeometry(rect); } +Qt::WindowState QEglFSWindow::setWindowState(Qt::WindowState state) +{ + setGeometry(QRect()); + return Qt::WindowFullScreen; +} + WId QEglFSWindow::winId() const { return m_winid; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 1376708ad6..7f40c78550 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -56,6 +56,7 @@ public: QEglFSWindow(QWindow *w); void setGeometry(const QRect &); + Qt::WindowState setWindowState(Qt::WindowState state); WId winId() const; private: |