diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-03-24 07:37:43 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-03-24 07:38:02 +0100 |
commit | 135ebe4f3d268121047fdbfee49f2dd52006165e (patch) | |
tree | 6b303103f36e69e29cfa860b8b7afc584c55d6f3 /src/platformsupport | |
parent | e7feb956280105113b3e58f12e5f32f54199a95a (diff) | |
parent | 1e8f50a8d069c97ea6a4f00d664c12e594884f54 (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Change-Id: If5d2e621c2fa5476c3ab687a3f4620c54fc3b32e
Diffstat (limited to 'src/platformsupport')
6 files changed, 108 insertions, 4 deletions
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp index 6e2fc81c42..61f8cdd9b4 100644 --- a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "qeglplatformscreen_p.h" +#include "qeglplatformwindow_p.h" #include <QtGui/qwindow.h> #include <qpa/qwindowsysteminterface.h> #include <QtPlatformSupport/private/qopenglcompositor_p.h> @@ -94,4 +95,52 @@ void QEGLPlatformScreen::handleCursorMove(const QPoint &pos) QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); } +QPixmap QEGLPlatformScreen::grabWindow(WId wid, int x, int y, int width, int height) const +{ + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + Q_ASSERT(!windows.isEmpty()); + + QImage img; + + if (static_cast<QEGLPlatformWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) { + // Request the compositor to render everything into an FBO and read it back. This + // is of course slow, but it's safe and reliable. It will not include the mouse + // cursor, which is a plus. + img = compositor->grab(); + } else { + // Just a single OpenGL window without compositing. Do not support this case for now. Doing + // glReadPixels is not an option since it would read from the back buffer which may have + // undefined content when calling right after a swapBuffers (unless preserved swap is + // available and enabled, but we have no support for that). + qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead."); + return QPixmap(); + } + + if (!wid) { + const QSize screenSize = geometry().size(); + if (width < 0) + width = screenSize.width() - x; + if (height < 0) + height = screenSize.height() - y; + return QPixmap::fromImage(img).copy(x, y, width, height); + } + + foreach (QOpenGLCompositorWindow *w, windows) { + const QWindow *window = w->sourceWindow(); + if (window->winId() == wid) { + const QRect geom = window->geometry(); + if (width < 0) + width = geom.width() - x; + if (height < 0) + height = geom.height() - y; + QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); + rect &= window->geometry(); + return QPixmap::fromImage(img).copy(rect); + } + } + + return QPixmap(); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h index 98a108c4b7..4a987f6860 100644 --- a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h @@ -67,6 +67,8 @@ public: void handleCursorMove(const QPoint &pos); + QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + private: EGLDisplay m_dpy; QWindow *m_pointerWindow; diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp index b467b7721f..73661f33bd 100644 --- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp +++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp @@ -75,6 +75,12 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay XFree(chosenVisualInfo); return visualId; } + // Skip also for i.MX6 where 565 visuals are suggested for the default 444 configs and it works just fine. + const char *vendor = eglQueryString(eglDisplay, EGL_VENDOR); + if (vendor && strstr(vendor, "Vivante")) { + XFree(chosenVisualInfo); + return visualId; + } int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask); int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask); diff --git a/src/platformsupport/fbconvenience/qfbvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp index 84844d8eda..c46e470c34 100644 --- a/src/platformsupport/fbconvenience/qfbvthandler.cpp +++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp @@ -38,9 +38,11 @@ #define VTH_ENABLED +#include <private/qcore_unix_p.h> #include <unistd.h> #include <signal.h> #include <errno.h> +#include <fcntl.h> #include <sys/signalfd.h> #include <sys/ioctl.h> #include <linux/kd.h> @@ -59,6 +61,24 @@ QT_BEGIN_NAMESPACE +#ifdef VTH_ENABLED +static void setTTYCursor(bool enable) +{ + const char * const devs[] = { "/dev/tty0", "/dev/tty", "/dev/console", 0 }; + int fd = -1; + for (const char * const *dev = devs; *dev; ++dev) { + fd = QT_OPEN(*dev, O_RDWR); + if (fd != -1) { + // Enable/disable screen blanking and the blinking cursor. + const char *termctl = enable ? "\033[9;15]\033[?33h\033[?25h\033[?0c" : "\033[9;0]\033[?33l\033[?25l\033[?1c"; + QT_WRITE(fd, termctl, strlen(termctl) + 1); + QT_CLOSE(fd); + return; + } + } +} +#endif + QFbVtHandler::QFbVtHandler(QObject *parent) : QObject(parent), m_tty(-1), @@ -66,6 +86,8 @@ QFbVtHandler::QFbVtHandler(QObject *parent) m_signalNotifier(0) { #ifdef VTH_ENABLED + setTTYCursor(false); + if (isatty(0)) { m_tty = 0; ioctl(m_tty, KDGKBMODE, &m_oldKbdMode); @@ -114,6 +136,7 @@ QFbVtHandler::~QFbVtHandler() { #ifdef VTH_ENABLED restoreKeyboard(); + setTTYCursor(true); if (m_signalFd != -1) close(m_signalFd); @@ -172,6 +195,7 @@ void QFbVtHandler::handleInt() #ifdef VTH_ENABLED emit interrupted(); restoreKeyboard(); + setTTYCursor(true); _exit(1); #endif } diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 3048b2b777..3fd6c999a2 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFramebufferObject> #include <QtGui/QWindow> #include <QtGui/QMatrix4x4> #include <qpa/qplatformbackingstore.h> @@ -76,7 +77,7 @@ QOpenGLCompositor::QOpenGLCompositor() Q_ASSERT(!compositor); m_updateTimer.setSingleShot(true); m_updateTimer.setInterval(0); - connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll())); + connect(&m_updateTimer, SIGNAL(timeout()), SLOT(handleRenderAllRequest())); } QOpenGLCompositor::~QOpenGLCompositor() @@ -98,10 +99,26 @@ void QOpenGLCompositor::update() m_updateTimer.start(); } -void QOpenGLCompositor::renderAll() +QImage QOpenGLCompositor::grab() { Q_ASSERT(m_context && m_targetWindow); m_context->makeCurrent(m_targetWindow); + QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(m_targetWindow->geometry().size())); + renderAll(fbo.data()); + return fbo->toImage(); +} + +void QOpenGLCompositor::handleRenderAllRequest() +{ + Q_ASSERT(m_context && m_targetWindow); + m_context->makeCurrent(m_targetWindow); + renderAll(0); +} + +void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo) +{ + if (fbo) + fbo->bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -120,7 +137,10 @@ void QOpenGLCompositor::renderAll() render(m_windows.at(i)); m_blitter.release(); - m_context->swapBuffers(m_targetWindow); + if (!fbo) + m_context->swapBuffers(m_targetWindow); + else + fbo->release(); for (int i = 0; i < m_windows.size(); ++i) m_windows.at(i)->endCompositing(); diff --git a/src/platformsupport/platformcompositor/qopenglcompositor_p.h b/src/platformsupport/platformcompositor/qopenglcompositor_p.h index 257bbf2531..2a8257305b 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor_p.h +++ b/src/platformsupport/platformcompositor/qopenglcompositor_p.h @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE class QOpenGLContext; +class QOpenGLFramebufferObject; class QWindow; class QPlatformTextureList; @@ -76,6 +77,7 @@ public: QWindow *targetWindow() const { return m_targetWindow; } void update(); + QImage grab(); QList<QOpenGLCompositorWindow *> windows() const { return m_windows; } void addWindow(QOpenGLCompositorWindow *window); @@ -87,12 +89,13 @@ signals: void topWindowChanged(QOpenGLCompositorWindow *window); private slots: - void renderAll(); + void handleRenderAllRequest(); private: QOpenGLCompositor(); ~QOpenGLCompositor(); + void renderAll(QOpenGLFramebufferObject *fbo); void render(QOpenGLCompositorWindow *window); QOpenGLContext *m_context; |