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
=== modified file 'README'
--- README 2016-06-20 08:37:56 +0000
+++ README 2016-07-04 17:59:30 +0000
@@ -23,13 +23,10 @@
23 $ qmlscene -platform ubuntumirclient Foo.qml23 $ qmlscene -platform ubuntumirclient Foo.qml
24 $ QT_QPA_PLATFORM=ubuntumirclient qmlscene Foo.qml24 $ QT_QPA_PLATFORM=ubuntumirclient qmlscene Foo.qml
2525
26 The QPA plugins expose the following environment variables:26 This QPA plugin exposes the following environment variables:
2727
28 QTUBUNTU_SWAPINTERVAL: Specifies the required swap interval as an28 QT_QPA_EGLFS_SWAPINTERVAL: Specifies the required swap interval as an
29 integer. 1 by default.29 integer. 1 by default.
30
31 QTUBUNTU_MULTISAMPLE: Enables multisampling with using 4 samples
32 per fragment.
3330
34 QTUBUNTU_NO_THREADED_OPENGL: Disables QtQuick threaded OpenGL31 QTUBUNTU_NO_THREADED_OPENGL: Disables QtQuick threaded OpenGL
35 rendering.32 rendering.
@@ -51,6 +48,8 @@
51 * ubuntumirclient.swapBuffers - Messages related to surface buffer swapping.48 * ubuntumirclient.swapBuffers - Messages related to surface buffer swapping.
52 * ubuntumirclient - For all other messages.49 * ubuntumirclient - For all other messages.
5350
51 The QT_QPA_EGLFS_DEBUG environment variable prints a little more information
52 from Qt's internals.
5453
554. Building544. Building
56-----------55-----------
5756
=== added file 'src/ubuntumirclient/desktopwindow.cpp'
--- src/ubuntumirclient/desktopwindow.cpp 1970-01-01 00:00:00 +0000
+++ src/ubuntumirclient/desktopwindow.cpp 2016-07-04 17:59:30 +0000
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "desktopwindow.h"
18
19// local
20#include "logging.h"
21
22UbuntuDesktopWindow::UbuntuDesktopWindow(QWindow *window)
23 : QPlatformWindow(window)
24{
25 qCDebug(ubuntumirclient, "UbuntuDesktopWindow(window=%p)", window);
26}
027
=== added file 'src/ubuntumirclient/desktopwindow.h'
--- src/ubuntumirclient/desktopwindow.h 1970-01-01 00:00:00 +0000
+++ src/ubuntumirclient/desktopwindow.h 2016-07-04 17:59:30 +0000
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef UBUNTU_DESKTOP_WINDOW_H
18#define UBUNTU_DESKTOP_WINDOW_H
19
20#include <qpa/qplatformwindow.h>
21
22// TODO Implement it. For now it's just an empty, dummy class.
23class UbuntuDesktopWindow : public QPlatformWindow
24{
25public:
26 UbuntuDesktopWindow(QWindow*);
27};
28
29#endif // UBUNTU_DESKTOP_WINDOW_H
030
=== modified file 'src/ubuntumirclient/glcontext.cpp'
--- src/ubuntumirclient/glcontext.cpp 2016-06-20 08:37:56 +0000
+++ src/ubuntumirclient/glcontext.cpp 2016-07-04 17:59:30 +0000
@@ -16,7 +16,6 @@
1616
17#include "glcontext.h"17#include "glcontext.h"
18#include "logging.h"18#include "logging.h"
19#include "offscreensurface.h"
20#include "window.h"19#include "window.h"
2120
22#include <QOpenGLFramebufferObject>21#include <QOpenGLFramebufferObject>
@@ -25,58 +24,12 @@
2524
26namespace {25namespace {
2726
28void printOpenGLESConfig() {27void printEglConfig(EGLDisplay display, EGLConfig config)
29 static bool once = true;28{
30 if (once) {
31 const char* string = (const char*) glGetString(GL_VENDOR);
32 qCDebug(ubuntumirclient, "OpenGL ES vendor: %s", string);
33 string = (const char*) glGetString(GL_RENDERER);
34 qCDebug(ubuntumirclient, "OpenGL ES renderer: %s", string);
35 string = (const char*) glGetString(GL_VERSION);
36 qCDebug(ubuntumirclient, "OpenGL ES version: %s", string);
37 string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
38 qCDebug(ubuntumirclient, "OpenGL ES Shading Language version: %s", string);
39 string = (const char*) glGetString(GL_EXTENSIONS);
40 qCDebug(ubuntumirclient, "OpenGL ES extensions: %s", string);
41 once = false;
42 }
43}
44
45void printEglConfig(EGLDisplay display, EGLConfig config) {
46 Q_ASSERT(display != EGL_NO_DISPLAY);29 Q_ASSERT(display != EGL_NO_DISPLAY);
47 Q_ASSERT(config != nullptr);30 Q_ASSERT(config != nullptr);
4831
49 static const struct { const EGLint attrib; const char* name; } kAttribs[] = {32 const char *string = eglQueryString(display, EGL_VENDOR);
50 { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
51 { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
52 { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
53 { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
54 { EGL_RED_SIZE, "EGL_RED_SIZE" },
55 { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
56 { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
57 { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
58 { EGL_CONFIG_ID, "EGL_CONFIG_ID" },
59 { EGL_LEVEL, "EGL_LEVEL" },
60 { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
61 { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
62 { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
63 { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
64 { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
65 { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
66 { EGL_SAMPLES, "EGL_SAMPLES" },
67 { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
68 { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
69 { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
70 { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
71 { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
72 { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
73 { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
74 { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
75 { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
76 { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
77 { -1, NULL }
78 };
79 const char* string = eglQueryString(display, EGL_VENDOR);
80 qCDebug(ubuntumirclient, "EGL vendor: %s", string);33 qCDebug(ubuntumirclient, "EGL vendor: %s", string);
8134
82 string = eglQueryString(display, EGL_VERSION);35 string = eglQueryString(display, EGL_VERSION);
@@ -85,93 +38,19 @@
85 string = eglQueryString(display, EGL_EXTENSIONS);38 string = eglQueryString(display, EGL_EXTENSIONS);
86 qCDebug(ubuntumirclient, "EGL extensions: %s", string);39 qCDebug(ubuntumirclient, "EGL extensions: %s", string);
8740
88 qCDebug(ubuntumirclient, "EGL configuration attibutes:");41 qCDebug(ubuntumirclient, "EGL configuration attributes:");
89 for (int index = 0; kAttribs[index].attrib != -1; index++) {42 q_printEglConfig(display, config);
90 EGLint value;
91 if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
92 qCDebug(ubuntumirclient, " %s: %d", kAttribs[index].name, static_cast<int>(value));
93 }
94}
95
96QString eglErrorToString(EGLint errorNumber)
97{
98 #define EGL_ERROR_CASE(error) case error: return QString(#error);
99
100 switch (errorNumber) {
101 EGL_ERROR_CASE(EGL_SUCCESS)
102 EGL_ERROR_CASE(EGL_NOT_INITIALIZED)
103 EGL_ERROR_CASE(EGL_BAD_ACCESS)
104 EGL_ERROR_CASE(EGL_BAD_ALLOC)
105 EGL_ERROR_CASE(EGL_BAD_ATTRIBUTE)
106 EGL_ERROR_CASE(EGL_BAD_CONTEXT)
107 EGL_ERROR_CASE(EGL_BAD_CONFIG)
108 EGL_ERROR_CASE(EGL_BAD_CURRENT_SURFACE)
109 EGL_ERROR_CASE(EGL_BAD_DISPLAY)
110 EGL_ERROR_CASE(EGL_BAD_SURFACE)
111 EGL_ERROR_CASE(EGL_BAD_MATCH)
112 EGL_ERROR_CASE(EGL_BAD_PARAMETER)
113 EGL_ERROR_CASE(EGL_BAD_NATIVE_PIXMAP)
114 EGL_ERROR_CASE(EGL_BAD_NATIVE_WINDOW)
115 EGL_ERROR_CASE(EGL_CONTEXT_LOST)
116 default:
117 return QString("?");
118 }
119
120 #undef EGL_ERROR_CASE
121}
122
123EGLenum api_in_use()
124{
125 #ifdef QTUBUNTU_USE_OPENGL
126 return EGL_OPENGL_API;
127 #else
128 return EGL_OPENGL_ES_API;
129 #endif
130}
131
132const int kSwapInterval = 1;
133
134int qGetEnvIntValue(const char *varName, bool *ok)
135{
136 return qgetenv(varName).toInt(ok);
137}43}
13844
139} // anonymous namespace45} // anonymous namespace
14046
141UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &surfaceFormat, UbuntuOpenGLContext *share,47UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
142 EGLDisplay display, EGLConfig config)48 EGLDisplay display)
143 : mSurfaceFormat(surfaceFormat)49 : QEGLPlatformContext(format, share, display, 0)
144 , mEglDisplay(display)
145{50{
146 // Create an OpenGL ES 2 context.
147 QVector<EGLint> attribs;
148 attribs.append(EGL_CONTEXT_CLIENT_VERSION);
149 attribs.append(2);
150 attribs.append(EGL_NONE);
151 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
152
153 if (ubuntumirclient().isDebugEnabled()) {51 if (ubuntumirclient().isDebugEnabled()) {
154 printEglConfig(mEglDisplay, config);52 printEglConfig(display, eglConfig());
155 }53 }
156
157 // Set vblank swap interval.
158 bool ok;
159 int swapInterval = qGetEnvIntValue("QTUBUNTU_SWAPINTERVAL", &ok);
160 if (!ok)
161 swapInterval = kSwapInterval;
162
163 qCDebug(ubuntumirclient, "Setting swap interval to %d", swapInterval);
164 eglSwapInterval(mEglDisplay, swapInterval);
165
166 mEglContext = eglCreateContext(mEglDisplay, config, share ? share->eglContext() : EGL_NO_CONTEXT,
167 attribs.constData());
168
169 Q_ASSERT(mEglContext != EGL_NO_CONTEXT);
170}
171
172UbuntuOpenGLContext::~UbuntuOpenGLContext()
173{
174 ASSERT(eglDestroyContext(mEglDisplay, mEglContext) == EGL_TRUE);
175}54}
17655
177static bool needsFBOReadBackWorkaround()56static bool needsFBOReadBackWorkaround()
@@ -179,7 +58,7 @@
179 static bool set = false;58 static bool set = false;
180 static bool needsWorkaround = false;59 static bool needsWorkaround = false;
18160
182 if (!set) {61 if (Q_UNLIKELY(!set)) {
183 const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));62 const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
184 needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 063 needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 0
185 || qstrncmp(rendererString, "Mali-T7", 7) == 064 || qstrncmp(rendererString, "Mali-T7", 7) == 0
@@ -194,55 +73,41 @@
194{73{
195 Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);74 Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
19675
197 if (surface->surface()->surfaceClass() == QSurface::Offscreen) {76 const bool ret = QEGLPlatformContext::makeCurrent(surface);
198 auto offscreen = static_cast<UbuntuOffscreenSurface *>(surface);77
199 if (!offscreen->buffer()) {78 if (Q_LIKELY(ret)) {
200 auto buffer = new QOpenGLFramebufferObject(surface->surface()->size());
201 offscreen->setBuffer(buffer);
202 }
203 return offscreen->buffer()->bind();
204 } else {
205 EGLSurface eglSurface = static_cast<UbuntuWindow*>(surface)->eglSurface();
206 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
207
208 EGLBoolean result = eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
209 if (result == EGL_FALSE) {
210 qCCritical(ubuntumirclient, "eglMakeCurrent() failed with %s",
211 qPrintable(eglErrorToString(eglGetError())));
212 return false;
213 }
214
215 QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());79 QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
216 if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) {80 if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) {
217 ctx_d->workaround_brokenFBOReadBack = true;81 ctx_d->workaround_brokenFBOReadBack = true;
218 }82 }
21983 }
220 if (ubuntumirclient().isDebugEnabled()) {84
221 printOpenGLESConfig();85 return ret;
222 }86}
223 return true;87
224 }88// WORKAROUND for bug 1594198 - avoid having Qt use GLESv3
225}89QSurfaceFormat UbuntuOpenGLContext::format() const
22690{
227void UbuntuOpenGLContext::doneCurrent()91 auto format = QEGLPlatformContext::format();
228{92 if (format.renderableType() == QSurfaceFormat::OpenGLES && format.majorVersion() > 2) {
229 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);93 format.setMajorVersion(2);
230 ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE);94 }
231}95 return format;
23296}
233void UbuntuOpenGLContext::swapBuffers(QPlatformSurface* surface)97
234{98// Following method used internally in the base class QEGLPlatformContext to access
235 UbuntuWindow *ubuntuWindow = static_cast<UbuntuWindow*>(surface);99// the egl surface of a QPlatformSurface/UbuntuWindow
236100EGLSurface UbuntuOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
237 EGLSurface eglSurface = ubuntuWindow->eglSurface();101{
238 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);102 auto ubuntuWindow = static_cast<UbuntuWindow *>(surface);
239 ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE);103 return ubuntuWindow->eglSurface();
240104}
105
106void UbuntuOpenGLContext::swapBuffers(QPlatformSurface *surface)
107{
108 QEGLPlatformContext::swapBuffers(surface);
109
110 // notify window on swap completion
111 auto ubuntuWindow = static_cast<UbuntuWindow *>(surface);
241 ubuntuWindow->onSwapBuffersDone();112 ubuntuWindow->onSwapBuffersDone();
242}113}
243
244void (*UbuntuOpenGLContext::getProcAddress(const QByteArray& procName)) ()
245{
246 ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
247 return eglGetProcAddress(procName.constData());
248}
249114
=== modified file 'src/ubuntumirclient/glcontext.h'
--- src/ubuntumirclient/glcontext.h 2016-06-20 08:37:56 +0000
+++ src/ubuntumirclient/glcontext.h 2016-07-04 17:59:30 +0000
@@ -18,30 +18,24 @@
18#define UBUNTU_OPENGL_CONTEXT_H18#define UBUNTU_OPENGL_CONTEXT_H
1919
20#include <qpa/qplatformopenglcontext.h>20#include <qpa/qplatformopenglcontext.h>
21#include <private/qeglplatformcontext_p.h>
2122
22#include <EGL/egl.h>23#include <EGL/egl.h>
2324
24class UbuntuOpenGLContext : public QPlatformOpenGLContext25class UbuntuOpenGLContext : public QEGLPlatformContext
25{26{
26public:27public:
27 UbuntuOpenGLContext(const QSurfaceFormat &surfaceFormat, UbuntuOpenGLContext *share,28 UbuntuOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
28 EGLDisplay display, EGLConfig config);29 EGLDisplay display);
29 virtual ~UbuntuOpenGLContext();30
3031 // QEGLPlatformContext methods.
31 // QPlatformOpenGLContext methods.32 void swapBuffers(QPlatformSurface *surface) final;
32 QSurfaceFormat format() const override { return mSurfaceFormat; }33 bool makeCurrent(QPlatformSurface *surface) final;
33 void swapBuffers(QPlatformSurface *surface) override;34
34 bool makeCurrent(QPlatformSurface *surface) override;35 QSurfaceFormat format() const final;
35 void doneCurrent() override;36
36 bool isValid() const override { return mEglContext != EGL_NO_CONTEXT; }37protected:
37 void (*getProcAddress(const QByteArray& procName)) () override;38 EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) final;
38
39 EGLContext eglContext() const { return mEglContext; }
40
41private:
42 const QSurfaceFormat mSurfaceFormat;
43 EGLContext mEglContext;
44 EGLDisplay mEglDisplay;
45};39};
4640
47#endif // UBUNTU_OPENGL_CONTEXT_H41#endif // UBUNTU_OPENGL_CONTEXT_H
4842
=== modified file 'src/ubuntumirclient/integration.cpp'
--- src/ubuntumirclient/integration.cpp 2016-06-20 08:37:56 +0000
+++ src/ubuntumirclient/integration.cpp 2016-07-04 17:59:30 +0000
@@ -18,11 +18,11 @@
18#include "integration.h"18#include "integration.h"
19#include "backingstore.h"19#include "backingstore.h"
20#include "clipboard.h"20#include "clipboard.h"
21#include "desktopwindow.h"
21#include "glcontext.h"22#include "glcontext.h"
22#include "input.h"23#include "input.h"
23#include "logging.h"24#include "logging.h"
24#include "nativeinterface.h"25#include "nativeinterface.h"
25#include "offscreensurface.h"
26#include "screen.h"26#include "screen.h"
27#include "theme.h"27#include "theme.h"
28#include "window.h"28#include "window.h"
@@ -30,7 +30,7 @@
30// Qt30// Qt
31#include <QFileInfo>31#include <QFileInfo>
32#include <QGuiApplication>32#include <QGuiApplication>
33#include <private/qguiapplication_p.h>33#include <private/qeglpbuffer_p.h>
34#include <qpa/qplatformnativeinterface.h>34#include <qpa/qplatformnativeinterface.h>
35#include <qpa/qplatforminputcontextfactory_p.h>35#include <qpa/qplatforminputcontextfactory_p.h>
36#include <qpa/qplatforminputcontext.h>36#include <qpa/qplatforminputcontext.h>
@@ -95,31 +95,17 @@
9595
96 mMirConnection = u_application_instance_get_mir_connection(mInstance);96 mMirConnection = u_application_instance_get_mir_connection(mInstance);
9797
98 // Choose the default surface format suited to the Mir platform
99 QSurfaceFormat defaultFormat;
100 defaultFormat.setRedBufferSize(8);
101 defaultFormat.setGreenBufferSize(8);
102 defaultFormat.setBlueBufferSize(8);
103 QSurfaceFormat::setDefaultFormat(defaultFormat);
104
98 // Initialize EGL.105 // Initialize EGL.
99 ASSERT(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
100
101 mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection);106 mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection);
102 ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);107 ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
103 ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);108 ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
104
105 // Configure EGL buffers format for all Windows.
106 mSurfaceFormat.setRedBufferSize(8);
107 mSurfaceFormat.setGreenBufferSize(8);
108 mSurfaceFormat.setBlueBufferSize(8);
109 mSurfaceFormat.setAlphaBufferSize(8);
110 mSurfaceFormat.setDepthBufferSize(24);
111 mSurfaceFormat.setStencilBufferSize(8);
112 if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) {
113 mSurfaceFormat.setSamples(4);
114 qCDebug(ubuntumirclient, "setting MSAA to 4 samples");
115 }
116#ifdef QTUBUNTU_USE_OPENGL
117 mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
118#else
119 mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
120#endif
121
122 mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true);
123}109}
124110
125void UbuntuClientIntegration::initialize()111void UbuntuClientIntegration::initialize()
@@ -226,7 +212,12 @@
226212
227QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) const213QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) const
228{214{
229 return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, mEglDisplay, mEglConfig, mMirConnection);215 if (window->type() == Qt::Desktop) {
216 // Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should).
217 return new UbuntuDesktopWindow(window);
218 } else {
219 return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, mEglDisplay, mMirConnection);
220 }
230}221}
231222
232bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const223bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -250,6 +241,7 @@
250 }241 }
251 case MultipleWindows:242 case MultipleWindows:
252 case NonFullScreenWindows:243 case NonFullScreenWindows:
244 case RasterGLSurface:
253 return true;245 return true;
254 default:246 default:
255 return QPlatformIntegration::hasCapability(cap);247 return QPlatformIntegration::hasCapability(cap);
@@ -269,8 +261,25 @@
269QPlatformOpenGLContext* UbuntuClientIntegration::createPlatformOpenGLContext(261QPlatformOpenGLContext* UbuntuClientIntegration::createPlatformOpenGLContext(
270 QOpenGLContext* context) const262 QOpenGLContext* context) const
271{263{
272 return new UbuntuOpenGLContext(mSurfaceFormat, static_cast<UbuntuOpenGLContext*>(context->shareHandle()),264 QSurfaceFormat format(context->format());
273 mEglDisplay, mEglConfig);265
266 auto platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay);
267 if (!platformContext->isValid()) {
268 // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
269 // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
270 // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to
271 // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
272 // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
273 static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
274 if (isMesa) {
275 qCDebug(ubuntumirclient, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
276 format.setMajorVersion(1);
277 format.setMinorVersion(4);
278 delete platformContext;
279 platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay);
280 }
281 }
282 return platformContext;
274}283}
275284
276QStringList UbuntuClientIntegration::themeNames() const285QStringList UbuntuClientIntegration::themeNames() const
@@ -314,7 +323,7 @@
314QPlatformOffscreenSurface *UbuntuClientIntegration::createPlatformOffscreenSurface(323QPlatformOffscreenSurface *UbuntuClientIntegration::createPlatformOffscreenSurface(
315 QOffscreenSurface *surface) const324 QOffscreenSurface *surface) const
316{325{
317 return new UbuntuOffscreenSurface(surface);326 return new QEGLPbuffer(mEglDisplay, QSurfaceFormat::defaultFormat(), surface);
318}327}
319328
320void UbuntuClientIntegration::destroyScreen(UbuntuScreen *screen)329void UbuntuClientIntegration::destroyScreen(UbuntuScreen *screen)
321330
=== modified file 'src/ubuntumirclient/integration.h'
--- src/ubuntumirclient/integration.h 2016-06-20 08:37:56 +0000
+++ src/ubuntumirclient/integration.h 2016-07-04 17:59:30 +0000
@@ -62,9 +62,7 @@
6262
63 // New methods.63 // New methods.
64 MirConnection *mirConnection() const { return mMirConnection; }64 MirConnection *mirConnection() const { return mMirConnection; }
65 QSurfaceFormat surfaceFormat() const { return mSurfaceFormat; }
66 EGLDisplay eglDisplay() const { return mEglDisplay; }65 EGLDisplay eglDisplay() const { return mEglDisplay; }
67 EGLConfig eglConfig() const { return mEglConfig; }
68 EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }66 EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
69 UbuntuScreenObserver *screenObserver() const { return mScreenObserver.data(); }67 UbuntuScreenObserver *screenObserver() const { return mScreenObserver.data(); }
7068
@@ -97,9 +95,7 @@
9795
98 // EGL related96 // EGL related
99 EGLDisplay mEglDisplay{EGL_NO_DISPLAY};97 EGLDisplay mEglDisplay{EGL_NO_DISPLAY};
100 EGLConfig mEglConfig{nullptr};
101 EGLNativeDisplayType mEglNativeDisplay;98 EGLNativeDisplayType mEglNativeDisplay;
102 QSurfaceFormat mSurfaceFormat;
103};99};
104100
105#endif // UBUNTU_CLIENT_INTEGRATION_H101#endif // UBUNTU_CLIENT_INTEGRATION_H
106102
=== removed file 'src/ubuntumirclient/offscreensurface.cpp'
--- src/ubuntumirclient/offscreensurface.cpp 2016-01-04 17:18:51 +0000
+++ src/ubuntumirclient/offscreensurface.cpp 1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "offscreensurface.h"
18
19#include <QOffscreenSurface>
20#include <QOpenGLFramebufferObject>
21
22UbuntuOffscreenSurface::UbuntuOffscreenSurface(QOffscreenSurface *offscreenSurface)
23 : QPlatformOffscreenSurface(offscreenSurface)
24 , m_buffer(nullptr)
25 , m_format(offscreenSurface->requestedFormat())
26{
27}
28
29QSurfaceFormat UbuntuOffscreenSurface::format() const
30{
31 return m_format;
32}
33
34bool UbuntuOffscreenSurface::isValid() const
35{
36 return m_buffer != nullptr && m_buffer->isValid();
37}
38
39QOpenGLFramebufferObject* UbuntuOffscreenSurface::buffer() const
40{
41 return m_buffer;
42}
43
44void UbuntuOffscreenSurface::setBuffer(QOpenGLFramebufferObject *buffer)
45{
46 m_buffer = buffer;
47}
480
=== removed file 'src/ubuntumirclient/offscreensurface.h'
--- src/ubuntumirclient/offscreensurface.h 2016-01-04 17:18:51 +0000
+++ src/ubuntumirclient/offscreensurface.h 1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef UBUNTU_OFFSCREEN_SURFACE_H
18#define UBUNTU_OFFSCREEN_SURFACE_H
19
20#include <qpa/qplatformoffscreensurface.h>
21#include <QSurfaceFormat>
22
23class QOpenGLFramebufferObject;
24
25class UbuntuOffscreenSurface : public QPlatformOffscreenSurface
26{
27public:
28 UbuntuOffscreenSurface(QOffscreenSurface *offscreenSurface);
29
30 QSurfaceFormat format() const override;
31 bool isValid() const override;
32
33 QOpenGLFramebufferObject* buffer() const;
34 void setBuffer(QOpenGLFramebufferObject *buffer);
35
36private:
37 QOpenGLFramebufferObject *m_buffer;
38 QSurfaceFormat m_format;
39};
40
41#endif // UBUNTU_OFFSCREEN_SURFACE_H
420
=== modified file 'src/ubuntumirclient/ubuntumirclient.pro'
--- src/ubuntumirclient/ubuntumirclient.pro 2016-05-30 17:14:14 +0000
+++ src/ubuntumirclient/ubuntumirclient.pro 2016-07-04 17:59:30 +0000
@@ -18,11 +18,11 @@
18 backingstore.cpp \18 backingstore.cpp \
19 clipboard.cpp \19 clipboard.cpp \
20 cursor.cpp \20 cursor.cpp \
21 desktopwindow.cpp \
21 glcontext.cpp \22 glcontext.cpp \
22 input.cpp \23 input.cpp \
23 integration.cpp \24 integration.cpp \
24 nativeinterface.cpp \25 nativeinterface.cpp \
25 offscreensurface.cpp \
26 platformservices.cpp \26 platformservices.cpp \
27 plugin.cpp \27 plugin.cpp \
28 screen.cpp \28 screen.cpp \
@@ -34,12 +34,12 @@
34 backingstore.h \34 backingstore.h \
35 clipboard.h \35 clipboard.h \
36 cursor.h \36 cursor.h \
37 desktopwindow.h \
37 glcontext.h \38 glcontext.h \
38 input.h \39 input.h \
39 integration.h \40 integration.h \
40 logging.h \41 logging.h \
41 nativeinterface.h \42 nativeinterface.h \
42 offscreensurface.h \
43 orientationchangeevent_p.h \43 orientationchangeevent_p.h \
44 platformservices.h \44 platformservices.h \
45 plugin.h \45 plugin.h \
4646
=== modified file 'src/ubuntumirclient/window.cpp'
--- src/ubuntumirclient/window.cpp 2016-06-20 08:37:56 +0000
+++ src/ubuntumirclient/window.cpp 2016-07-04 17:59:30 +0000
@@ -29,6 +29,7 @@
29#include <QMutexLocker>29#include <QMutexLocker>
30#include <QSize>30#include <QSize>
31#include <QtMath>31#include <QtMath>
32#include <private/qeglconvenience_p.h>
3233
33// Platform API34// Platform API
34#include <ubuntu/application/instance.h>35#include <ubuntu/application/instance.h>
@@ -101,6 +102,24 @@
101 }102 }
102}103}
103104
105const char *mirPixelFormatToStr(MirPixelFormat pixelFormat)
106{
107 switch (pixelFormat) {
108 case mir_pixel_format_invalid: return "invalid";
109 case mir_pixel_format_abgr_8888: return "ABGR8888";
110 case mir_pixel_format_xbgr_8888: return "XBGR8888";
111 case mir_pixel_format_argb_8888: return "ARGB8888";
112 case mir_pixel_format_xrgb_8888: return "XRGB8888";
113 case mir_pixel_format_bgr_888: return "BGR888";
114 case mir_pixel_format_rgb_888: return "RGB888";
115 case mir_pixel_format_rgb_565: return "RGB565";
116 case mir_pixel_format_rgba_5551: return "RGBA5551";
117 case mir_pixel_format_rgba_4444: return "RGBA4444";
118 case mir_pixel_formats:
119 default: return "???";
120 }
121}
122
104MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)123MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
105{124{
106 switch (state) {125 switch (state) {
@@ -124,14 +143,6 @@
124 return id++;143 return id++;
125}144}
126145
127MirPixelFormat defaultPixelFormatFor(MirConnection *connection)
128{
129 MirPixelFormat format;
130 unsigned int nformats;
131 mir_connection_get_available_surface_formats(connection, &format, 1, &nformats);
132 return format;
133}
134
135UAUiWindowRole roleFor(QWindow *window)146UAUiWindowRole roleFor(QWindow *window)
136{147{
137 QVariant roleVariant = window->property("role");148 QVariant roleVariant = window->property("role");
@@ -151,12 +162,11 @@
151 return parent ? static_cast<UbuntuWindow *>(parent->handle()) : nullptr;162 return parent ? static_cast<UbuntuWindow *>(parent->handle()) : nullptr;
152}163}
153164
154Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirConnection *connection)165Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirPixelFormat pixelFormat, MirConnection *connection)
155{166{
156 const auto geom = window->geometry();167 const auto geom = window->geometry();
157 const int width = geom.width() > 0 ? geom.width() : 1;168 const int width = geom.width() > 0 ? geom.width() : 1;
158 const int height = geom.height() > 0 ? geom.height() : 1;169 const int height = geom.height() > 0 ? geom.height() : 1;
159 const auto pixelFormat = defaultPixelFormatFor(connection);
160170
161 if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {171 if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
162 qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height);172 qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height);
@@ -217,11 +227,11 @@
217 }227 }
218}228}
219229
220MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input,230MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input, MirPixelFormat pixelFormat,
221 MirConnection *connection, mir_surface_event_callback inputCallback,231 MirConnection *connection, mir_surface_event_callback inputCallback,
222 void* inputContext)232 void* inputContext)
223{233{
224 auto spec = makeSurfaceSpec(window, input, connection);234 auto spec = makeSurfaceSpec(window, input, pixelFormat, connection);
225235
226 // Install event handler as early as possible236 // Install event handler as early as possible
227 mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);237 mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);
@@ -244,6 +254,18 @@
244 return surface;254 return surface;
245}255}
246256
257MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat)
258{
259 switch(pixelFormat) {
260 case mir_pixel_format_abgr_8888:
261 return mir_pixel_format_xbgr_8888;
262 case mir_pixel_format_argb_8888:
263 return mir_pixel_format_xrgb_8888;
264 default: // can do nothing, leave it alone
265 return pixelFormat;
266 }
267}
268
247// FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633269// FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633
248// we need to guess the panel height (3GU)270// we need to guess the panel height (3GU)
249int panelHeight()271int panelHeight()
@@ -266,8 +288,7 @@
266class UbuntuSurface288class UbuntuSurface
267{289{
268public:290public:
269 UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, EGLConfig config, int mirOutputId,291 UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, UbuntuInput *input, MirConnection *connection)
270 UbuntuInput *input, MirConnection *connection)
271 : mWindow(platformWindow->window())292 : mWindow(platformWindow->window())
272 , mPlatformWindow(platformWindow)293 , mPlatformWindow(platformWindow)
273 , mInput(input)294 , mInput(input)
@@ -275,9 +296,44 @@
275 , mEglDisplay(display)296 , mEglDisplay(display)
276 , mNeedsRepaint(false)297 , mNeedsRepaint(false)
277 , mParented(mWindow->transientParent() || mWindow->parent())298 , mParented(mWindow->transientParent() || mWindow->parent())
299 , mFormat(mWindow->requestedFormat())
278 , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)300 , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)
279 {301 {
280 mMirSurface = createMirSurface(mWindow, mirOutputId, input, connection, surfaceEventCallback, this);302 // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it
303 EGLConfig config = q_configFromGLFormat(display, mFormat, true);
304 if (config == 0) {
305 // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
306 // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
307 // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to
308 // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
309 // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
310 static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
311 if (isMesa) {
312 qCDebug(ubuntumirclient, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
313 mFormat.setMajorVersion(1);
314 mFormat.setMinorVersion(4);
315 config = q_configFromGLFormat(display, mFormat, true);
316 }
317 }
318 if (config == 0) {
319 qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat;
320 }
321
322 mFormat = q_glFormatFromConfig(display, config, mFormat);
323
324 // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way
325 // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers.
326 auto pixelFormat = mir_connection_get_egl_pixel_format(connection, display, config);
327 // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client.
328 // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer.
329 // This is an optimisation for the compositor, as it can avoid blending this surface.
330 if (mWindow->requestedFormat().alphaBufferSize() < 0) {
331 pixelFormat = disableAlphaBufferIfPossible(pixelFormat);
332 }
333
334 const auto outputId = static_cast<UbuntuScreen *>(mWindow->screen()->handle())->mirOutputId();
335
336 mMirSurface = createMirSurface(mWindow, outputId, input, pixelFormat, connection, surfaceEventCallback, this);
281 mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr);337 mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr);
282338
283 // Window manager can give us a final size different from what we asked for339 // Window manager can give us a final size different from what we asked for
@@ -299,8 +355,11 @@
299 platformWindow->QPlatformWindow::setGeometry(geom);355 platformWindow->QPlatformWindow::setGeometry(geom);
300 QWindowSystemInterface::handleGeometryChange(mWindow, geom);356 QWindowSystemInterface::handleGeometryChange(mWindow, geom);
301357
302 qCDebug(ubuntumirclient, "created surface at (%d, %d) with size (%d, %d), title '%s', role: '%d'\n",358 qCDebug(ubuntumirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title()
303 geom.x(), geom.y(), geom.width(), geom.height(), mWindow->title().toUtf8().constData(), roleFor(mWindow));359 << "role:" << roleFor(mWindow)
360 << "\nRequested format:" << mWindow->requestedFormat()
361 << "\nActual format:" << mFormat
362 << "with associated Mir pixel format:" << mirPixelFormatToStr(pixelFormat);
304 }363 }
305364
306 ~UbuntuSurface()365 ~UbuntuSurface()
@@ -335,6 +394,8 @@
335 void setSurfaceParent(MirSurface*);394 void setSurfaceParent(MirSurface*);
336 bool hasParent() const { return mParented; }395 bool hasParent() const { return mParented; }
337396
397 QSurfaceFormat format() const { return mFormat; }
398
338private:399private:
339 static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context);400 static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context);
340 void postEvent(const MirEvent *event);401 void postEvent(const MirEvent *event);
@@ -351,6 +412,7 @@
351 bool mNeedsRepaint;412 bool mNeedsRepaint;
352 bool mParented;413 bool mParented;
353 QSize mBufferSize;414 QSize mBufferSize;
415 QSurfaceFormat mFormat;
354416
355 QMutex mTargetSizeMutex;417 QMutex mTargetSizeMutex;
356 QSize mTargetSize;418 QSize mTargetSize;
@@ -509,8 +571,7 @@
509}571}
510572
511UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,573UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
512 UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay,574 UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay, MirConnection *mirConnection)
513 EGLConfig eglConfig, MirConnection *mirConnection)
514 : QObject(nullptr)575 : QObject(nullptr)
515 , QPlatformWindow(w)576 , QPlatformWindow(w)
516 , mId(makeId())577 , mId(makeId())
@@ -520,8 +581,7 @@
520 , mWindowVisible(false)581 , mWindowVisible(false)
521 , mWindowExposed(true)582 , mWindowExposed(true)
522 , mNativeInterface(native)583 , mNativeInterface(native)
523 , mSurface(new UbuntuSurface{this, eglDisplay, eglConfig,584 , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection})
524 static_cast<UbuntuScreen*>(w->screen()->handle())->mirOutputId(), input, mirConnection})
525 , mScale(1.0)585 , mScale(1.0)
526 , mFormFactor(mir_form_factor_unknown)586 , mFormFactor(mir_form_factor_unknown)
527{587{
@@ -709,6 +769,11 @@
709 return mWindowVisible && mWindowExposed;769 return mWindowVisible && mWindowExposed;
710}770}
711771
772QSurfaceFormat UbuntuWindow::format() const
773{
774 return mSurface->format();
775}
776
712void* UbuntuWindow::eglSurface() const777void* UbuntuWindow::eglSurface() const
713{778{
714 return mSurface->eglSurface();779 return mSurface->eglSurface();
715780
=== modified file 'src/ubuntumirclient/window.h'
--- src/ubuntumirclient/window.h 2016-06-20 08:37:56 +0000
+++ src/ubuntumirclient/window.h 2016-07-04 17:59:30 +0000
@@ -40,7 +40,7 @@
40 Q_OBJECT40 Q_OBJECT
41public:41public:
42 UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,42 UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
43 UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay, EGLConfig eglConfig,43 UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay,
44 MirConnection *mirConnection);44 MirConnection *mirConnection);
45 virtual ~UbuntuWindow();45 virtual ~UbuntuWindow();
4646
@@ -54,6 +54,8 @@
54 void propagateSizeHints() override;54 void propagateSizeHints() override;
55 bool isExposed() const override;55 bool isExposed() const override;
5656
57 QSurfaceFormat format() const override;
58
57 // Additional Window properties exposed by NativeInterface59 // Additional Window properties exposed by NativeInterface
58 MirFormFactor formFactor() const { return mFormFactor; }60 MirFormFactor formFactor() const { return mFormFactor; }
59 float scale() const { return mScale; }61 float scale() const { return mScale; }

Subscribers

People subscribed via source and target branches