Add support for grabWindow() on eglfs with widgets
For real OpenGL content it is still not supported because we have no reliable way to read back the contents at arbitrary times. Applications should rather use QQuickWindow::grabWindow() in that case. [ChangeLog][QtGui] Support for QScreen::grabWindow() is now available on embedded platforms (eglfs, linuxfb). Task-number: QTBUG-44937 Change-Id: I4ad046062782c160f5bb9f8f2a2fe82f2e7394cc Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>bb10
parent
3acd8d9aa4
commit
60cdc6035d
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue