diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-08-04 13:31:20 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-09-05 10:30:50 +0000 |
commit | cf24d203850cd87e31bc123407e7ae126be9961c (patch) | |
tree | 52bbf250df26c320b706f2cfff6fc028cfef2ea3 /src/platformsupport/kmsconvenience/qkmsdevice_p.h | |
parent | f2289bbcbbbddfd248c5e0858e148d7cc7336f8a (diff) |
eglfs_kms: Add headless mode for DRM render nodes
Attempting to switch /dev/dri/cardX to /dev/dri/renderDY is futile
on its own now since many output-related drm operations fail and we
eventually crash.
Add a new headless mode that skips the real screen stuff and registers
a fairly dummy, headless screen, does not bother with the mouse cursor,
and disallows rendering to the screen via a QWindow (while keeping the
actual rendering still fully functional).
Such applications will not need any special privileges and will run even
if there is a DRM master (X11, Wayland compositor) active.
For example the configuration can look like this:
{
"device": "/dev/dri/renderD128",
"headless": "1024x768"
}
After this applications have two choices to perform offscreen
rendering:
1. Use an ordinary window (and its default framebuffer, meaning the
gbm_surface), e.g. a QOpenGLWindow subclass
MyOpenGLWindow w;
w.show(); // will not actually show on screen
w.grabFramebuffer().save("output.png");
Note that there is no vsync-based throttling. Also note that windows are
still sized to match the screen size, hence the need for specifying a size
in the headless property.
2. Or the typical offscreen approach with an extra FBO
QOffscreenSurface s;
s.setFormat(ctx.format());
s.create();
ctx.makeCurrent(&s0;
QOpenGLFramebufferObject fbo(1024, 768);
fbo.bind();
ctx.functions()->glClearColor(1, 0, 0, 1);
ctx.functions()->glClear(GL_COLOR_BUFFER_BIT);
fbo.toImage().save("output.png");
ctx.doneCurrent();
Task-number: QTBUG-62262
Change-Id: Ic1dbfa2b27b223bd5ef8ba36b665f0f61abf4f06
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/platformsupport/kmsconvenience/qkmsdevice_p.h')
-rw-r--r-- | src/platformsupport/kmsconvenience/qkmsdevice_p.h | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice_p.h b/src/platformsupport/kmsconvenience/qkmsdevice_p.h index 390cc52e4d..bbc03b8e2a 100644 --- a/src/platformsupport/kmsconvenience/qkmsdevice_p.h +++ b/src/platformsupport/kmsconvenience/qkmsdevice_p.h @@ -77,6 +77,8 @@ public: QString devicePath() const { return m_devicePath; } + bool headless() const { return m_headless; } + QSize headlessSize() const { return m_headlessSize; } bool hwCursor() const { return m_hwCursor; } bool separateScreens() const { return m_separateScreens; } bool supportsPBuffers() const { return m_pbuffers; } @@ -88,6 +90,8 @@ private: void loadConfig(); QString m_devicePath; + bool m_headless; + QSize m_headlessSize; bool m_hwCursor; bool m_separateScreens; bool m_pbuffers; @@ -98,21 +102,21 @@ private: struct QKmsOutput { QString name; - uint32_t connector_id; - uint32_t crtc_id; + uint32_t connector_id = 0; + uint32_t crtc_id = 0; QSizeF physical_size; - int preferred_mode; // index of preferred mode in list below - int mode; // index of selected mode in list below - bool mode_set; - drmModeCrtcPtr saved_crtc; + int preferred_mode = -1; // index of preferred mode in list below + int mode = -1; // index of selected mode in list below + bool mode_set = false; + drmModeCrtcPtr saved_crtc = nullptr; QList<drmModeModeInfo> modes; - int subpixel; - drmModePropertyPtr dpms_prop; - drmModePropertyBlobPtr edid_blob; - bool wants_plane; - uint32_t plane_id; - bool plane_set; - uint32_t drm_format; + int subpixel = DRM_MODE_SUBPIXEL_UNKNOWN; + drmModePropertyPtr dpms_prop = nullptr; + drmModePropertyBlobPtr edid_blob = nullptr; + bool wants_plane = false; + uint32_t plane_id = 0; + bool plane_set = false; + uint32_t drm_format = DRM_FORMAT_XRGB8888; QString clone_source; void restoreMode(QKmsDevice *device); @@ -147,6 +151,7 @@ public: protected: virtual QPlatformScreen *createScreen(const QKmsOutput &output) = 0; + virtual QPlatformScreen *createHeadlessScreen(); virtual void registerScreenCloning(QPlatformScreen *screen, QPlatformScreen *screenThisScreenClones, const QVector<QPlatformScreen *> &screensCloningThisScreen); |