Merge lp:~dandrader/qtubuntu/rasterGLSurface into lp:qtubuntu

Proposed by Daniel d'Andrada
Status: Superseded
Proposed branch: lp:~dandrader/qtubuntu/rasterGLSurface
Merge into: lp:qtubuntu
Diff against target: 931 lines (+243/-346)
12 files modified
README (+6/-7)
src/ubuntumirclient/desktopwindow.cpp (+26/-0)
src/ubuntumirclient/desktopwindow.h (+29/-0)
src/ubuntumirclient/glcontext.cpp (+42/-177)
src/ubuntumirclient/glcontext.h (+13/-19)
src/ubuntumirclient/integration.cpp (+36/-27)
src/ubuntumirclient/integration.h (+0/-4)
src/ubuntumirclient/offscreensurface.cpp (+0/-47)
src/ubuntumirclient/offscreensurface.h (+0/-41)
src/ubuntumirclient/ubuntumirclient.pro (+2/-2)
src/ubuntumirclient/window.cpp (+86/-21)
src/ubuntumirclient/window.h (+3/-1)
To merge this branch: bzr merge lp:~dandrader/qtubuntu/rasterGLSurface
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Approve
Ubuntu Phablet Team Pending
Review via email: mp+299079@code.launchpad.net

Commit message

Add support for QQuickWidgets

- Advertise RasterGLSurface capability

- Implement proper offscreen rendering support using EGL pixel buffers.

- Don't create mir surfaces for Qt::Desktop QWindows. Proper
implementation still pending

Description of the change

To test:
Build & run lp:~dandrader/+junk/qwidget

If you can see the "Hello World" in a red rect, it's working.

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:330
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/93/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/2209
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2237
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2143
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2143
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2143
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2134/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2134
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2134/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/93/rebuild

review: Approve (continuous-integration)

Unmerged revisions

330. By Daniel d'Andrada

Add support for QQuickWidgets

- Advertise RasterGLSurface capability

- Implement proper offscreen rendering support using EGL pixel buffers.

- Don't create mir surfaces for Qt::Desktop QWindows. Proper
implementation still pending

329. By Daniel d'Andrada

merge lp:~gerboland/qtubuntu/eglconvenience-retry

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README'
2--- README 2016-06-20 08:37:56 +0000
3+++ README 2016-07-04 17:59:30 +0000
4@@ -23,13 +23,10 @@
5 $ qmlscene -platform ubuntumirclient Foo.qml
6 $ QT_QPA_PLATFORM=ubuntumirclient qmlscene Foo.qml
7
8- The QPA plugins expose the following environment variables:
9-
10- QTUBUNTU_SWAPINTERVAL: Specifies the required swap interval as an
11- integer. 1 by default.
12-
13- QTUBUNTU_MULTISAMPLE: Enables multisampling with using 4 samples
14- per fragment.
15+ This QPA plugin exposes the following environment variables:
16+
17+ QT_QPA_EGLFS_SWAPINTERVAL: Specifies the required swap interval as an
18+ integer. 1 by default.
19
20 QTUBUNTU_NO_THREADED_OPENGL: Disables QtQuick threaded OpenGL
21 rendering.
22@@ -51,6 +48,8 @@
23 * ubuntumirclient.swapBuffers - Messages related to surface buffer swapping.
24 * ubuntumirclient - For all other messages.
25
26+ The QT_QPA_EGLFS_DEBUG environment variable prints a little more information
27+ from Qt's internals.
28
29 4. Building
30 -----------
31
32=== added file 'src/ubuntumirclient/desktopwindow.cpp'
33--- src/ubuntumirclient/desktopwindow.cpp 1970-01-01 00:00:00 +0000
34+++ src/ubuntumirclient/desktopwindow.cpp 2016-07-04 17:59:30 +0000
35@@ -0,0 +1,26 @@
36+/*
37+ * Copyright (C) 2016 Canonical, Ltd.
38+ *
39+ * This program is free software: you can redistribute it and/or modify it under
40+ * the terms of the GNU Lesser General Public License version 3, as published by
41+ * the Free Software Foundation.
42+ *
43+ * This program is distributed in the hope that it will be useful, but WITHOUT
44+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
45+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
46+ * Lesser General Public License for more details.
47+ *
48+ * You should have received a copy of the GNU Lesser General Public License
49+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
50+ */
51+
52+#include "desktopwindow.h"
53+
54+// local
55+#include "logging.h"
56+
57+UbuntuDesktopWindow::UbuntuDesktopWindow(QWindow *window)
58+ : QPlatformWindow(window)
59+{
60+ qCDebug(ubuntumirclient, "UbuntuDesktopWindow(window=%p)", window);
61+}
62
63=== added file 'src/ubuntumirclient/desktopwindow.h'
64--- src/ubuntumirclient/desktopwindow.h 1970-01-01 00:00:00 +0000
65+++ src/ubuntumirclient/desktopwindow.h 2016-07-04 17:59:30 +0000
66@@ -0,0 +1,29 @@
67+/*
68+ * Copyright (C) 2016 Canonical, Ltd.
69+ *
70+ * This program is free software: you can redistribute it and/or modify it under
71+ * the terms of the GNU Lesser General Public License version 3, as published by
72+ * the Free Software Foundation.
73+ *
74+ * This program is distributed in the hope that it will be useful, but WITHOUT
75+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
76+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
77+ * Lesser General Public License for more details.
78+ *
79+ * You should have received a copy of the GNU Lesser General Public License
80+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
81+ */
82+
83+#ifndef UBUNTU_DESKTOP_WINDOW_H
84+#define UBUNTU_DESKTOP_WINDOW_H
85+
86+#include <qpa/qplatformwindow.h>
87+
88+// TODO Implement it. For now it's just an empty, dummy class.
89+class UbuntuDesktopWindow : public QPlatformWindow
90+{
91+public:
92+ UbuntuDesktopWindow(QWindow*);
93+};
94+
95+#endif // UBUNTU_DESKTOP_WINDOW_H
96
97=== modified file 'src/ubuntumirclient/glcontext.cpp'
98--- src/ubuntumirclient/glcontext.cpp 2016-06-20 08:37:56 +0000
99+++ src/ubuntumirclient/glcontext.cpp 2016-07-04 17:59:30 +0000
100@@ -16,7 +16,6 @@
101
102 #include "glcontext.h"
103 #include "logging.h"
104-#include "offscreensurface.h"
105 #include "window.h"
106
107 #include <QOpenGLFramebufferObject>
108@@ -25,58 +24,12 @@
109
110 namespace {
111
112-void printOpenGLESConfig() {
113- static bool once = true;
114- if (once) {
115- const char* string = (const char*) glGetString(GL_VENDOR);
116- qCDebug(ubuntumirclient, "OpenGL ES vendor: %s", string);
117- string = (const char*) glGetString(GL_RENDERER);
118- qCDebug(ubuntumirclient, "OpenGL ES renderer: %s", string);
119- string = (const char*) glGetString(GL_VERSION);
120- qCDebug(ubuntumirclient, "OpenGL ES version: %s", string);
121- string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
122- qCDebug(ubuntumirclient, "OpenGL ES Shading Language version: %s", string);
123- string = (const char*) glGetString(GL_EXTENSIONS);
124- qCDebug(ubuntumirclient, "OpenGL ES extensions: %s", string);
125- once = false;
126- }
127-}
128-
129-void printEglConfig(EGLDisplay display, EGLConfig config) {
130+void printEglConfig(EGLDisplay display, EGLConfig config)
131+{
132 Q_ASSERT(display != EGL_NO_DISPLAY);
133 Q_ASSERT(config != nullptr);
134
135- static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
136- { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
137- { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
138- { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
139- { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
140- { EGL_RED_SIZE, "EGL_RED_SIZE" },
141- { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
142- { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
143- { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
144- { EGL_CONFIG_ID, "EGL_CONFIG_ID" },
145- { EGL_LEVEL, "EGL_LEVEL" },
146- { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
147- { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
148- { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
149- { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
150- { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
151- { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
152- { EGL_SAMPLES, "EGL_SAMPLES" },
153- { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
154- { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
155- { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
156- { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
157- { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
158- { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
159- { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
160- { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
161- { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
162- { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
163- { -1, NULL }
164- };
165- const char* string = eglQueryString(display, EGL_VENDOR);
166+ const char *string = eglQueryString(display, EGL_VENDOR);
167 qCDebug(ubuntumirclient, "EGL vendor: %s", string);
168
169 string = eglQueryString(display, EGL_VERSION);
170@@ -85,93 +38,19 @@
171 string = eglQueryString(display, EGL_EXTENSIONS);
172 qCDebug(ubuntumirclient, "EGL extensions: %s", string);
173
174- qCDebug(ubuntumirclient, "EGL configuration attibutes:");
175- for (int index = 0; kAttribs[index].attrib != -1; index++) {
176- EGLint value;
177- if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
178- qCDebug(ubuntumirclient, " %s: %d", kAttribs[index].name, static_cast<int>(value));
179- }
180-}
181-
182-QString eglErrorToString(EGLint errorNumber)
183-{
184- #define EGL_ERROR_CASE(error) case error: return QString(#error);
185-
186- switch (errorNumber) {
187- EGL_ERROR_CASE(EGL_SUCCESS)
188- EGL_ERROR_CASE(EGL_NOT_INITIALIZED)
189- EGL_ERROR_CASE(EGL_BAD_ACCESS)
190- EGL_ERROR_CASE(EGL_BAD_ALLOC)
191- EGL_ERROR_CASE(EGL_BAD_ATTRIBUTE)
192- EGL_ERROR_CASE(EGL_BAD_CONTEXT)
193- EGL_ERROR_CASE(EGL_BAD_CONFIG)
194- EGL_ERROR_CASE(EGL_BAD_CURRENT_SURFACE)
195- EGL_ERROR_CASE(EGL_BAD_DISPLAY)
196- EGL_ERROR_CASE(EGL_BAD_SURFACE)
197- EGL_ERROR_CASE(EGL_BAD_MATCH)
198- EGL_ERROR_CASE(EGL_BAD_PARAMETER)
199- EGL_ERROR_CASE(EGL_BAD_NATIVE_PIXMAP)
200- EGL_ERROR_CASE(EGL_BAD_NATIVE_WINDOW)
201- EGL_ERROR_CASE(EGL_CONTEXT_LOST)
202- default:
203- return QString("?");
204- }
205-
206- #undef EGL_ERROR_CASE
207-}
208-
209-EGLenum api_in_use()
210-{
211- #ifdef QTUBUNTU_USE_OPENGL
212- return EGL_OPENGL_API;
213- #else
214- return EGL_OPENGL_ES_API;
215- #endif
216-}
217-
218-const int kSwapInterval = 1;
219-
220-int qGetEnvIntValue(const char *varName, bool *ok)
221-{
222- return qgetenv(varName).toInt(ok);
223+ qCDebug(ubuntumirclient, "EGL configuration attributes:");
224+ q_printEglConfig(display, config);
225 }
226
227 } // anonymous namespace
228
229-UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &surfaceFormat, UbuntuOpenGLContext *share,
230- EGLDisplay display, EGLConfig config)
231- : mSurfaceFormat(surfaceFormat)
232- , mEglDisplay(display)
233+UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
234+ EGLDisplay display)
235+ : QEGLPlatformContext(format, share, display, 0)
236 {
237- // Create an OpenGL ES 2 context.
238- QVector<EGLint> attribs;
239- attribs.append(EGL_CONTEXT_CLIENT_VERSION);
240- attribs.append(2);
241- attribs.append(EGL_NONE);
242- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
243-
244 if (ubuntumirclient().isDebugEnabled()) {
245- printEglConfig(mEglDisplay, config);
246+ printEglConfig(display, eglConfig());
247 }
248-
249- // Set vblank swap interval.
250- bool ok;
251- int swapInterval = qGetEnvIntValue("QTUBUNTU_SWAPINTERVAL", &ok);
252- if (!ok)
253- swapInterval = kSwapInterval;
254-
255- qCDebug(ubuntumirclient, "Setting swap interval to %d", swapInterval);
256- eglSwapInterval(mEglDisplay, swapInterval);
257-
258- mEglContext = eglCreateContext(mEglDisplay, config, share ? share->eglContext() : EGL_NO_CONTEXT,
259- attribs.constData());
260-
261- Q_ASSERT(mEglContext != EGL_NO_CONTEXT);
262-}
263-
264-UbuntuOpenGLContext::~UbuntuOpenGLContext()
265-{
266- ASSERT(eglDestroyContext(mEglDisplay, mEglContext) == EGL_TRUE);
267 }
268
269 static bool needsFBOReadBackWorkaround()
270@@ -179,7 +58,7 @@
271 static bool set = false;
272 static bool needsWorkaround = false;
273
274- if (!set) {
275+ if (Q_UNLIKELY(!set)) {
276 const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
277 needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 0
278 || qstrncmp(rendererString, "Mali-T7", 7) == 0
279@@ -194,55 +73,41 @@
280 {
281 Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
282
283- if (surface->surface()->surfaceClass() == QSurface::Offscreen) {
284- auto offscreen = static_cast<UbuntuOffscreenSurface *>(surface);
285- if (!offscreen->buffer()) {
286- auto buffer = new QOpenGLFramebufferObject(surface->surface()->size());
287- offscreen->setBuffer(buffer);
288- }
289- return offscreen->buffer()->bind();
290- } else {
291- EGLSurface eglSurface = static_cast<UbuntuWindow*>(surface)->eglSurface();
292- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
293-
294- EGLBoolean result = eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
295- if (result == EGL_FALSE) {
296- qCCritical(ubuntumirclient, "eglMakeCurrent() failed with %s",
297- qPrintable(eglErrorToString(eglGetError())));
298- return false;
299- }
300-
301+ const bool ret = QEGLPlatformContext::makeCurrent(surface);
302+
303+ if (Q_LIKELY(ret)) {
304 QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
305 if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) {
306 ctx_d->workaround_brokenFBOReadBack = true;
307 }
308-
309- if (ubuntumirclient().isDebugEnabled()) {
310- printOpenGLESConfig();
311- }
312- return true;
313- }
314-}
315-
316-void UbuntuOpenGLContext::doneCurrent()
317-{
318- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
319- ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE);
320-}
321-
322-void UbuntuOpenGLContext::swapBuffers(QPlatformSurface* surface)
323-{
324- UbuntuWindow *ubuntuWindow = static_cast<UbuntuWindow*>(surface);
325-
326- EGLSurface eglSurface = ubuntuWindow->eglSurface();
327- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
328- ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE);
329-
330+ }
331+
332+ return ret;
333+}
334+
335+// WORKAROUND for bug 1594198 - avoid having Qt use GLESv3
336+QSurfaceFormat UbuntuOpenGLContext::format() const
337+{
338+ auto format = QEGLPlatformContext::format();
339+ if (format.renderableType() == QSurfaceFormat::OpenGLES && format.majorVersion() > 2) {
340+ format.setMajorVersion(2);
341+ }
342+ return format;
343+}
344+
345+// Following method used internally in the base class QEGLPlatformContext to access
346+// the egl surface of a QPlatformSurface/UbuntuWindow
347+EGLSurface UbuntuOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
348+{
349+ auto ubuntuWindow = static_cast<UbuntuWindow *>(surface);
350+ return ubuntuWindow->eglSurface();
351+}
352+
353+void UbuntuOpenGLContext::swapBuffers(QPlatformSurface *surface)
354+{
355+ QEGLPlatformContext::swapBuffers(surface);
356+
357+ // notify window on swap completion
358+ auto ubuntuWindow = static_cast<UbuntuWindow *>(surface);
359 ubuntuWindow->onSwapBuffersDone();
360 }
361-
362-void (*UbuntuOpenGLContext::getProcAddress(const QByteArray& procName)) ()
363-{
364- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
365- return eglGetProcAddress(procName.constData());
366-}
367
368=== modified file 'src/ubuntumirclient/glcontext.h'
369--- src/ubuntumirclient/glcontext.h 2016-06-20 08:37:56 +0000
370+++ src/ubuntumirclient/glcontext.h 2016-07-04 17:59:30 +0000
371@@ -18,30 +18,24 @@
372 #define UBUNTU_OPENGL_CONTEXT_H
373
374 #include <qpa/qplatformopenglcontext.h>
375+#include <private/qeglplatformcontext_p.h>
376
377 #include <EGL/egl.h>
378
379-class UbuntuOpenGLContext : public QPlatformOpenGLContext
380+class UbuntuOpenGLContext : public QEGLPlatformContext
381 {
382 public:
383- UbuntuOpenGLContext(const QSurfaceFormat &surfaceFormat, UbuntuOpenGLContext *share,
384- EGLDisplay display, EGLConfig config);
385- virtual ~UbuntuOpenGLContext();
386-
387- // QPlatformOpenGLContext methods.
388- QSurfaceFormat format() const override { return mSurfaceFormat; }
389- void swapBuffers(QPlatformSurface *surface) override;
390- bool makeCurrent(QPlatformSurface *surface) override;
391- void doneCurrent() override;
392- bool isValid() const override { return mEglContext != EGL_NO_CONTEXT; }
393- void (*getProcAddress(const QByteArray& procName)) () override;
394-
395- EGLContext eglContext() const { return mEglContext; }
396-
397-private:
398- const QSurfaceFormat mSurfaceFormat;
399- EGLContext mEglContext;
400- EGLDisplay mEglDisplay;
401+ UbuntuOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
402+ EGLDisplay display);
403+
404+ // QEGLPlatformContext methods.
405+ void swapBuffers(QPlatformSurface *surface) final;
406+ bool makeCurrent(QPlatformSurface *surface) final;
407+
408+ QSurfaceFormat format() const final;
409+
410+protected:
411+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) final;
412 };
413
414 #endif // UBUNTU_OPENGL_CONTEXT_H
415
416=== modified file 'src/ubuntumirclient/integration.cpp'
417--- src/ubuntumirclient/integration.cpp 2016-06-20 08:37:56 +0000
418+++ src/ubuntumirclient/integration.cpp 2016-07-04 17:59:30 +0000
419@@ -18,11 +18,11 @@
420 #include "integration.h"
421 #include "backingstore.h"
422 #include "clipboard.h"
423+#include "desktopwindow.h"
424 #include "glcontext.h"
425 #include "input.h"
426 #include "logging.h"
427 #include "nativeinterface.h"
428-#include "offscreensurface.h"
429 #include "screen.h"
430 #include "theme.h"
431 #include "window.h"
432@@ -30,7 +30,7 @@
433 // Qt
434 #include <QFileInfo>
435 #include <QGuiApplication>
436-#include <private/qguiapplication_p.h>
437+#include <private/qeglpbuffer_p.h>
438 #include <qpa/qplatformnativeinterface.h>
439 #include <qpa/qplatforminputcontextfactory_p.h>
440 #include <qpa/qplatforminputcontext.h>
441@@ -95,31 +95,17 @@
442
443 mMirConnection = u_application_instance_get_mir_connection(mInstance);
444
445+ // Choose the default surface format suited to the Mir platform
446+ QSurfaceFormat defaultFormat;
447+ defaultFormat.setRedBufferSize(8);
448+ defaultFormat.setGreenBufferSize(8);
449+ defaultFormat.setBlueBufferSize(8);
450+ QSurfaceFormat::setDefaultFormat(defaultFormat);
451+
452 // Initialize EGL.
453- ASSERT(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
454-
455 mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection);
456 ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
457 ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
458-
459- // Configure EGL buffers format for all Windows.
460- mSurfaceFormat.setRedBufferSize(8);
461- mSurfaceFormat.setGreenBufferSize(8);
462- mSurfaceFormat.setBlueBufferSize(8);
463- mSurfaceFormat.setAlphaBufferSize(8);
464- mSurfaceFormat.setDepthBufferSize(24);
465- mSurfaceFormat.setStencilBufferSize(8);
466- if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) {
467- mSurfaceFormat.setSamples(4);
468- qCDebug(ubuntumirclient, "setting MSAA to 4 samples");
469- }
470-#ifdef QTUBUNTU_USE_OPENGL
471- mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
472-#else
473- mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
474-#endif
475-
476- mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true);
477 }
478
479 void UbuntuClientIntegration::initialize()
480@@ -226,7 +212,12 @@
481
482 QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) const
483 {
484- return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, mEglDisplay, mEglConfig, mMirConnection);
485+ if (window->type() == Qt::Desktop) {
486+ // Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should).
487+ return new UbuntuDesktopWindow(window);
488+ } else {
489+ return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, mEglDisplay, mMirConnection);
490+ }
491 }
492
493 bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
494@@ -250,6 +241,7 @@
495 }
496 case MultipleWindows:
497 case NonFullScreenWindows:
498+ case RasterGLSurface:
499 return true;
500 default:
501 return QPlatformIntegration::hasCapability(cap);
502@@ -269,8 +261,25 @@
503 QPlatformOpenGLContext* UbuntuClientIntegration::createPlatformOpenGLContext(
504 QOpenGLContext* context) const
505 {
506- return new UbuntuOpenGLContext(mSurfaceFormat, static_cast<UbuntuOpenGLContext*>(context->shareHandle()),
507- mEglDisplay, mEglConfig);
508+ QSurfaceFormat format(context->format());
509+
510+ auto platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay);
511+ if (!platformContext->isValid()) {
512+ // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
513+ // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
514+ // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to
515+ // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
516+ // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
517+ static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
518+ if (isMesa) {
519+ qCDebug(ubuntumirclient, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
520+ format.setMajorVersion(1);
521+ format.setMinorVersion(4);
522+ delete platformContext;
523+ platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay);
524+ }
525+ }
526+ return platformContext;
527 }
528
529 QStringList UbuntuClientIntegration::themeNames() const
530@@ -314,7 +323,7 @@
531 QPlatformOffscreenSurface *UbuntuClientIntegration::createPlatformOffscreenSurface(
532 QOffscreenSurface *surface) const
533 {
534- return new UbuntuOffscreenSurface(surface);
535+ return new QEGLPbuffer(mEglDisplay, QSurfaceFormat::defaultFormat(), surface);
536 }
537
538 void UbuntuClientIntegration::destroyScreen(UbuntuScreen *screen)
539
540=== modified file 'src/ubuntumirclient/integration.h'
541--- src/ubuntumirclient/integration.h 2016-06-20 08:37:56 +0000
542+++ src/ubuntumirclient/integration.h 2016-07-04 17:59:30 +0000
543@@ -62,9 +62,7 @@
544
545 // New methods.
546 MirConnection *mirConnection() const { return mMirConnection; }
547- QSurfaceFormat surfaceFormat() const { return mSurfaceFormat; }
548 EGLDisplay eglDisplay() const { return mEglDisplay; }
549- EGLConfig eglConfig() const { return mEglConfig; }
550 EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
551 UbuntuScreenObserver *screenObserver() const { return mScreenObserver.data(); }
552
553@@ -97,9 +95,7 @@
554
555 // EGL related
556 EGLDisplay mEglDisplay{EGL_NO_DISPLAY};
557- EGLConfig mEglConfig{nullptr};
558 EGLNativeDisplayType mEglNativeDisplay;
559- QSurfaceFormat mSurfaceFormat;
560 };
561
562 #endif // UBUNTU_CLIENT_INTEGRATION_H
563
564=== removed file 'src/ubuntumirclient/offscreensurface.cpp'
565--- src/ubuntumirclient/offscreensurface.cpp 2016-01-04 17:18:51 +0000
566+++ src/ubuntumirclient/offscreensurface.cpp 1970-01-01 00:00:00 +0000
567@@ -1,47 +0,0 @@
568-/*
569- * Copyright (C) 2016 Canonical, Ltd.
570- *
571- * This program is free software: you can redistribute it and/or modify it under
572- * the terms of the GNU Lesser General Public License version 3, as published by
573- * the Free Software Foundation.
574- *
575- * This program is distributed in the hope that it will be useful, but WITHOUT
576- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
577- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
578- * Lesser General Public License for more details.
579- *
580- * You should have received a copy of the GNU Lesser General Public License
581- * along with this program. If not, see <http://www.gnu.org/licenses/>.
582- */
583-
584-#include "offscreensurface.h"
585-
586-#include <QOffscreenSurface>
587-#include <QOpenGLFramebufferObject>
588-
589-UbuntuOffscreenSurface::UbuntuOffscreenSurface(QOffscreenSurface *offscreenSurface)
590- : QPlatformOffscreenSurface(offscreenSurface)
591- , m_buffer(nullptr)
592- , m_format(offscreenSurface->requestedFormat())
593-{
594-}
595-
596-QSurfaceFormat UbuntuOffscreenSurface::format() const
597-{
598- return m_format;
599-}
600-
601-bool UbuntuOffscreenSurface::isValid() const
602-{
603- return m_buffer != nullptr && m_buffer->isValid();
604-}
605-
606-QOpenGLFramebufferObject* UbuntuOffscreenSurface::buffer() const
607-{
608- return m_buffer;
609-}
610-
611-void UbuntuOffscreenSurface::setBuffer(QOpenGLFramebufferObject *buffer)
612-{
613- m_buffer = buffer;
614-}
615
616=== removed file 'src/ubuntumirclient/offscreensurface.h'
617--- src/ubuntumirclient/offscreensurface.h 2016-01-04 17:18:51 +0000
618+++ src/ubuntumirclient/offscreensurface.h 1970-01-01 00:00:00 +0000
619@@ -1,41 +0,0 @@
620-/*
621- * Copyright (C) 2016 Canonical, Ltd.
622- *
623- * This program is free software: you can redistribute it and/or modify it under
624- * the terms of the GNU Lesser General Public License version 3, as published by
625- * the Free Software Foundation.
626- *
627- * This program is distributed in the hope that it will be useful, but WITHOUT
628- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
629- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
630- * Lesser General Public License for more details.
631- *
632- * You should have received a copy of the GNU Lesser General Public License
633- * along with this program. If not, see <http://www.gnu.org/licenses/>.
634- */
635-
636-#ifndef UBUNTU_OFFSCREEN_SURFACE_H
637-#define UBUNTU_OFFSCREEN_SURFACE_H
638-
639-#include <qpa/qplatformoffscreensurface.h>
640-#include <QSurfaceFormat>
641-
642-class QOpenGLFramebufferObject;
643-
644-class UbuntuOffscreenSurface : public QPlatformOffscreenSurface
645-{
646-public:
647- UbuntuOffscreenSurface(QOffscreenSurface *offscreenSurface);
648-
649- QSurfaceFormat format() const override;
650- bool isValid() const override;
651-
652- QOpenGLFramebufferObject* buffer() const;
653- void setBuffer(QOpenGLFramebufferObject *buffer);
654-
655-private:
656- QOpenGLFramebufferObject *m_buffer;
657- QSurfaceFormat m_format;
658-};
659-
660-#endif // UBUNTU_OFFSCREEN_SURFACE_H
661
662=== modified file 'src/ubuntumirclient/ubuntumirclient.pro'
663--- src/ubuntumirclient/ubuntumirclient.pro 2016-05-30 17:14:14 +0000
664+++ src/ubuntumirclient/ubuntumirclient.pro 2016-07-04 17:59:30 +0000
665@@ -18,11 +18,11 @@
666 backingstore.cpp \
667 clipboard.cpp \
668 cursor.cpp \
669+ desktopwindow.cpp \
670 glcontext.cpp \
671 input.cpp \
672 integration.cpp \
673 nativeinterface.cpp \
674- offscreensurface.cpp \
675 platformservices.cpp \
676 plugin.cpp \
677 screen.cpp \
678@@ -34,12 +34,12 @@
679 backingstore.h \
680 clipboard.h \
681 cursor.h \
682+ desktopwindow.h \
683 glcontext.h \
684 input.h \
685 integration.h \
686 logging.h \
687 nativeinterface.h \
688- offscreensurface.h \
689 orientationchangeevent_p.h \
690 platformservices.h \
691 plugin.h \
692
693=== modified file 'src/ubuntumirclient/window.cpp'
694--- src/ubuntumirclient/window.cpp 2016-06-20 08:37:56 +0000
695+++ src/ubuntumirclient/window.cpp 2016-07-04 17:59:30 +0000
696@@ -29,6 +29,7 @@
697 #include <QMutexLocker>
698 #include <QSize>
699 #include <QtMath>
700+#include <private/qeglconvenience_p.h>
701
702 // Platform API
703 #include <ubuntu/application/instance.h>
704@@ -101,6 +102,24 @@
705 }
706 }
707
708+const char *mirPixelFormatToStr(MirPixelFormat pixelFormat)
709+{
710+ switch (pixelFormat) {
711+ case mir_pixel_format_invalid: return "invalid";
712+ case mir_pixel_format_abgr_8888: return "ABGR8888";
713+ case mir_pixel_format_xbgr_8888: return "XBGR8888";
714+ case mir_pixel_format_argb_8888: return "ARGB8888";
715+ case mir_pixel_format_xrgb_8888: return "XRGB8888";
716+ case mir_pixel_format_bgr_888: return "BGR888";
717+ case mir_pixel_format_rgb_888: return "RGB888";
718+ case mir_pixel_format_rgb_565: return "RGB565";
719+ case mir_pixel_format_rgba_5551: return "RGBA5551";
720+ case mir_pixel_format_rgba_4444: return "RGBA4444";
721+ case mir_pixel_formats:
722+ default: return "???";
723+ }
724+}
725+
726 MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
727 {
728 switch (state) {
729@@ -124,14 +143,6 @@
730 return id++;
731 }
732
733-MirPixelFormat defaultPixelFormatFor(MirConnection *connection)
734-{
735- MirPixelFormat format;
736- unsigned int nformats;
737- mir_connection_get_available_surface_formats(connection, &format, 1, &nformats);
738- return format;
739-}
740-
741 UAUiWindowRole roleFor(QWindow *window)
742 {
743 QVariant roleVariant = window->property("role");
744@@ -151,12 +162,11 @@
745 return parent ? static_cast<UbuntuWindow *>(parent->handle()) : nullptr;
746 }
747
748-Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirConnection *connection)
749+Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirPixelFormat pixelFormat, MirConnection *connection)
750 {
751 const auto geom = window->geometry();
752 const int width = geom.width() > 0 ? geom.width() : 1;
753 const int height = geom.height() > 0 ? geom.height() : 1;
754- const auto pixelFormat = defaultPixelFormatFor(connection);
755
756 if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
757 qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height);
758@@ -217,11 +227,11 @@
759 }
760 }
761
762-MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input,
763+MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input, MirPixelFormat pixelFormat,
764 MirConnection *connection, mir_surface_event_callback inputCallback,
765 void* inputContext)
766 {
767- auto spec = makeSurfaceSpec(window, input, connection);
768+ auto spec = makeSurfaceSpec(window, input, pixelFormat, connection);
769
770 // Install event handler as early as possible
771 mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);
772@@ -244,6 +254,18 @@
773 return surface;
774 }
775
776+MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat)
777+{
778+ switch(pixelFormat) {
779+ case mir_pixel_format_abgr_8888:
780+ return mir_pixel_format_xbgr_8888;
781+ case mir_pixel_format_argb_8888:
782+ return mir_pixel_format_xrgb_8888;
783+ default: // can do nothing, leave it alone
784+ return pixelFormat;
785+ }
786+}
787+
788 // FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633
789 // we need to guess the panel height (3GU)
790 int panelHeight()
791@@ -266,8 +288,7 @@
792 class UbuntuSurface
793 {
794 public:
795- UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, EGLConfig config, int mirOutputId,
796- UbuntuInput *input, MirConnection *connection)
797+ UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, UbuntuInput *input, MirConnection *connection)
798 : mWindow(platformWindow->window())
799 , mPlatformWindow(platformWindow)
800 , mInput(input)
801@@ -275,9 +296,44 @@
802 , mEglDisplay(display)
803 , mNeedsRepaint(false)
804 , mParented(mWindow->transientParent() || mWindow->parent())
805+ , mFormat(mWindow->requestedFormat())
806 , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)
807 {
808- mMirSurface = createMirSurface(mWindow, mirOutputId, input, connection, surfaceEventCallback, this);
809+ // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it
810+ EGLConfig config = q_configFromGLFormat(display, mFormat, true);
811+ if (config == 0) {
812+ // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
813+ // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
814+ // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to
815+ // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
816+ // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
817+ static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
818+ if (isMesa) {
819+ qCDebug(ubuntumirclient, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
820+ mFormat.setMajorVersion(1);
821+ mFormat.setMinorVersion(4);
822+ config = q_configFromGLFormat(display, mFormat, true);
823+ }
824+ }
825+ if (config == 0) {
826+ qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat;
827+ }
828+
829+ mFormat = q_glFormatFromConfig(display, config, mFormat);
830+
831+ // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way
832+ // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers.
833+ auto pixelFormat = mir_connection_get_egl_pixel_format(connection, display, config);
834+ // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client.
835+ // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer.
836+ // This is an optimisation for the compositor, as it can avoid blending this surface.
837+ if (mWindow->requestedFormat().alphaBufferSize() < 0) {
838+ pixelFormat = disableAlphaBufferIfPossible(pixelFormat);
839+ }
840+
841+ const auto outputId = static_cast<UbuntuScreen *>(mWindow->screen()->handle())->mirOutputId();
842+
843+ mMirSurface = createMirSurface(mWindow, outputId, input, pixelFormat, connection, surfaceEventCallback, this);
844 mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr);
845
846 // Window manager can give us a final size different from what we asked for
847@@ -299,8 +355,11 @@
848 platformWindow->QPlatformWindow::setGeometry(geom);
849 QWindowSystemInterface::handleGeometryChange(mWindow, geom);
850
851- qCDebug(ubuntumirclient, "created surface at (%d, %d) with size (%d, %d), title '%s', role: '%d'\n",
852- geom.x(), geom.y(), geom.width(), geom.height(), mWindow->title().toUtf8().constData(), roleFor(mWindow));
853+ qCDebug(ubuntumirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title()
854+ << "role:" << roleFor(mWindow)
855+ << "\nRequested format:" << mWindow->requestedFormat()
856+ << "\nActual format:" << mFormat
857+ << "with associated Mir pixel format:" << mirPixelFormatToStr(pixelFormat);
858 }
859
860 ~UbuntuSurface()
861@@ -335,6 +394,8 @@
862 void setSurfaceParent(MirSurface*);
863 bool hasParent() const { return mParented; }
864
865+ QSurfaceFormat format() const { return mFormat; }
866+
867 private:
868 static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context);
869 void postEvent(const MirEvent *event);
870@@ -351,6 +412,7 @@
871 bool mNeedsRepaint;
872 bool mParented;
873 QSize mBufferSize;
874+ QSurfaceFormat mFormat;
875
876 QMutex mTargetSizeMutex;
877 QSize mTargetSize;
878@@ -509,8 +571,7 @@
879 }
880
881 UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
882- UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay,
883- EGLConfig eglConfig, MirConnection *mirConnection)
884+ UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay, MirConnection *mirConnection)
885 : QObject(nullptr)
886 , QPlatformWindow(w)
887 , mId(makeId())
888@@ -520,8 +581,7 @@
889 , mWindowVisible(false)
890 , mWindowExposed(true)
891 , mNativeInterface(native)
892- , mSurface(new UbuntuSurface{this, eglDisplay, eglConfig,
893- static_cast<UbuntuScreen*>(w->screen()->handle())->mirOutputId(), input, mirConnection})
894+ , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection})
895 , mScale(1.0)
896 , mFormFactor(mir_form_factor_unknown)
897 {
898@@ -709,6 +769,11 @@
899 return mWindowVisible && mWindowExposed;
900 }
901
902+QSurfaceFormat UbuntuWindow::format() const
903+{
904+ return mSurface->format();
905+}
906+
907 void* UbuntuWindow::eglSurface() const
908 {
909 return mSurface->eglSurface();
910
911=== modified file 'src/ubuntumirclient/window.h'
912--- src/ubuntumirclient/window.h 2016-06-20 08:37:56 +0000
913+++ src/ubuntumirclient/window.h 2016-07-04 17:59:30 +0000
914@@ -40,7 +40,7 @@
915 Q_OBJECT
916 public:
917 UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
918- UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay, EGLConfig eglConfig,
919+ UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay,
920 MirConnection *mirConnection);
921 virtual ~UbuntuWindow();
922
923@@ -54,6 +54,8 @@
924 void propagateSizeHints() override;
925 bool isExposed() const override;
926
927+ QSurfaceFormat format() const override;
928+
929 // Additional Window properties exposed by NativeInterface
930 MirFormFactor formFactor() const { return mFormFactor; }
931 float scale() const { return mScale; }

Subscribers

People subscribed via source and target branches