Merge lp:~gerboland/qtubuntu/minor-cleanup into lp:qtubuntu
- minor-cleanup
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~gerboland/qtubuntu/minor-cleanup |
Merge into: | lp:qtubuntu |
Diff against target: |
687 lines (+162/-256) 7 files modified
README (+6/-7) src/ubuntumirclient/glcontext.cpp (+30/-165) src/ubuntumirclient/glcontext.h (+11/-19) src/ubuntumirclient/integration.cpp (+26/-35) src/ubuntumirclient/integration.h (+0/-8) src/ubuntumirclient/window.cpp (+86/-21) src/ubuntumirclient/window.h (+3/-1) |
To merge this branch: | bzr merge lp:~gerboland/qtubuntu/minor-cleanup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Approve | |
Daniel d'Andrada (community) | Approve | ||
Review via email: mp+295241@code.launchpad.net |
This proposal has been superseded by a proposal from 2016-06-03.
Commit message
Integration: no need for the non-const versions of createWindow and createGLContext
Description of the change
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
- 328. By Gerry Boland
-
Remove old incorrect info from readme
- 329. By Gerry Boland
-
Fix typo
- 330. By Gerry Boland
-
Set minimum GL version to 1.0 so that EGL chooses a suitable context on Atom-based hardware
Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default requested OpenGL version to 1.0 to ensure EGL will give us a working context.
- 331. By Gerry Boland
-
Rename SurfaceFormatCh
ooser to SurfaceFormatFilter and add env var to disable filteringi - 332. By Gerry Boland
-
QML does not need alpha channel to render correctly, so do not impose it
- 333. By Gerry Boland
-
Typo spot dy duflu
- 334. By Gerry Boland
-
Update comments to reflect reality
- 335. By Gerry Boland
-
Enable GL version hack only on Mesa
- 336. By Gerry Boland
-
Micro optimisation
- 337. By Gerry Boland
-
Minor syntax standardization
- 338. By Gerry Boland
-
GCC disagreeed with CLang about removing the default from the switch
- 339. By Gerry Boland
-
Set a sensible QSurfaceFormat:
:setDefaultForm at instead of guess-filtering after user request - 340. By Gerry Boland
-
Refactor again to remove the SurfaceFormatFi
lter, and just retry config choice with lower GL version
Daniel d'Andrada (dandrader) : | # |
- 341. By Gerry Boland
-
Merge trunk, fix conflicts, give hints to branch predictor
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:317
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
Preview Diff
1 | === modified file 'README' |
2 | --- README 2015-12-09 13:30:15 +0000 |
3 | +++ README 2016-06-03 10:25:36 +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 | === modified file 'src/ubuntumirclient/glcontext.cpp' |
33 | --- src/ubuntumirclient/glcontext.cpp 2016-05-27 13:05:20 +0000 |
34 | +++ src/ubuntumirclient/glcontext.cpp 2016-06-03 10:25:36 +0000 |
35 | @@ -25,58 +25,12 @@ |
36 | |
37 | namespace { |
38 | |
39 | -void printOpenGLESConfig() { |
40 | - static bool once = true; |
41 | - if (once) { |
42 | - const char* string = (const char*) glGetString(GL_VENDOR); |
43 | - qCDebug(ubuntumirclient, "OpenGL ES vendor: %s", string); |
44 | - string = (const char*) glGetString(GL_RENDERER); |
45 | - qCDebug(ubuntumirclient, "OpenGL ES renderer: %s", string); |
46 | - string = (const char*) glGetString(GL_VERSION); |
47 | - qCDebug(ubuntumirclient, "OpenGL ES version: %s", string); |
48 | - string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); |
49 | - qCDebug(ubuntumirclient, "OpenGL ES Shading Language version: %s", string); |
50 | - string = (const char*) glGetString(GL_EXTENSIONS); |
51 | - qCDebug(ubuntumirclient, "OpenGL ES extensions: %s", string); |
52 | - once = false; |
53 | - } |
54 | -} |
55 | - |
56 | -void printEglConfig(EGLDisplay display, EGLConfig config) { |
57 | +void printEglConfig(EGLDisplay display, EGLConfig config) |
58 | +{ |
59 | Q_ASSERT(display != EGL_NO_DISPLAY); |
60 | Q_ASSERT(config != nullptr); |
61 | |
62 | - static const struct { const EGLint attrib; const char* name; } kAttribs[] = { |
63 | - { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" }, |
64 | - { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" }, |
65 | - { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" }, |
66 | - { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" }, |
67 | - { EGL_RED_SIZE, "EGL_RED_SIZE" }, |
68 | - { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" }, |
69 | - { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" }, |
70 | - { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" }, |
71 | - { EGL_CONFIG_ID, "EGL_CONFIG_ID" }, |
72 | - { EGL_LEVEL, "EGL_LEVEL" }, |
73 | - { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" }, |
74 | - { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" }, |
75 | - { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" }, |
76 | - { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" }, |
77 | - { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" }, |
78 | - { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" }, |
79 | - { EGL_SAMPLES, "EGL_SAMPLES" }, |
80 | - { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" }, |
81 | - { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" }, |
82 | - { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" }, |
83 | - { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" }, |
84 | - { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" }, |
85 | - { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" }, |
86 | - { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" }, |
87 | - { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" }, |
88 | - { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" }, |
89 | - { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" }, |
90 | - { -1, NULL } |
91 | - }; |
92 | - const char* string = eglQueryString(display, EGL_VENDOR); |
93 | + const char *string = eglQueryString(display, EGL_VENDOR); |
94 | qCDebug(ubuntumirclient, "EGL vendor: %s", string); |
95 | |
96 | string = eglQueryString(display, EGL_VERSION); |
97 | @@ -85,93 +39,19 @@ |
98 | string = eglQueryString(display, EGL_EXTENSIONS); |
99 | qCDebug(ubuntumirclient, "EGL extensions: %s", string); |
100 | |
101 | - qCDebug(ubuntumirclient, "EGL configuration attibutes:"); |
102 | - for (int index = 0; kAttribs[index].attrib != -1; index++) { |
103 | - EGLint value; |
104 | - if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value)) |
105 | - qCDebug(ubuntumirclient, " %s: %d", kAttribs[index].name, static_cast<int>(value)); |
106 | - } |
107 | -} |
108 | - |
109 | -QString eglErrorToString(EGLint errorNumber) |
110 | -{ |
111 | - #define EGL_ERROR_CASE(error) case error: return QString(#error); |
112 | - |
113 | - switch (errorNumber) { |
114 | - EGL_ERROR_CASE(EGL_SUCCESS) |
115 | - EGL_ERROR_CASE(EGL_NOT_INITIALIZED) |
116 | - EGL_ERROR_CASE(EGL_BAD_ACCESS) |
117 | - EGL_ERROR_CASE(EGL_BAD_ALLOC) |
118 | - EGL_ERROR_CASE(EGL_BAD_ATTRIBUTE) |
119 | - EGL_ERROR_CASE(EGL_BAD_CONTEXT) |
120 | - EGL_ERROR_CASE(EGL_BAD_CONFIG) |
121 | - EGL_ERROR_CASE(EGL_BAD_CURRENT_SURFACE) |
122 | - EGL_ERROR_CASE(EGL_BAD_DISPLAY) |
123 | - EGL_ERROR_CASE(EGL_BAD_SURFACE) |
124 | - EGL_ERROR_CASE(EGL_BAD_MATCH) |
125 | - EGL_ERROR_CASE(EGL_BAD_PARAMETER) |
126 | - EGL_ERROR_CASE(EGL_BAD_NATIVE_PIXMAP) |
127 | - EGL_ERROR_CASE(EGL_BAD_NATIVE_WINDOW) |
128 | - EGL_ERROR_CASE(EGL_CONTEXT_LOST) |
129 | - default: |
130 | - return QString("?"); |
131 | - } |
132 | - |
133 | - #undef EGL_ERROR_CASE |
134 | -} |
135 | - |
136 | -EGLenum api_in_use() |
137 | -{ |
138 | - #ifdef QTUBUNTU_USE_OPENGL |
139 | - return EGL_OPENGL_API; |
140 | - #else |
141 | - return EGL_OPENGL_ES_API; |
142 | - #endif |
143 | -} |
144 | - |
145 | -const int kSwapInterval = 1; |
146 | - |
147 | -int qGetEnvIntValue(const char *varName, bool *ok) |
148 | -{ |
149 | - return qgetenv(varName).toInt(ok); |
150 | + qCDebug(ubuntumirclient, "EGL configuration attributes:"); |
151 | + q_printEglConfig(display, config); |
152 | } |
153 | |
154 | } // anonymous namespace |
155 | |
156 | -UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &surfaceFormat, UbuntuOpenGLContext *share, |
157 | - EGLDisplay display, EGLConfig config) |
158 | - : mSurfaceFormat(surfaceFormat) |
159 | - , mEglDisplay(display) |
160 | +UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, |
161 | + EGLDisplay display) |
162 | + : QEGLPlatformContext(format, share, display, 0) |
163 | { |
164 | - // Create an OpenGL ES 2 context. |
165 | - QVector<EGLint> attribs; |
166 | - attribs.append(EGL_CONTEXT_CLIENT_VERSION); |
167 | - attribs.append(2); |
168 | - attribs.append(EGL_NONE); |
169 | - ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE); |
170 | - |
171 | if (ubuntumirclient().isDebugEnabled()) { |
172 | - printEglConfig(mEglDisplay, config); |
173 | + printEglConfig(display, eglConfig()); |
174 | } |
175 | - |
176 | - // Set vblank swap interval. |
177 | - bool ok; |
178 | - int swapInterval = qGetEnvIntValue("QTUBUNTU_SWAPINTERVAL", &ok); |
179 | - if (!ok) |
180 | - swapInterval = kSwapInterval; |
181 | - |
182 | - qCDebug(ubuntumirclient, "Setting swap interval to %d", swapInterval); |
183 | - eglSwapInterval(mEglDisplay, swapInterval); |
184 | - |
185 | - mEglContext = eglCreateContext(mEglDisplay, config, share ? share->eglContext() : EGL_NO_CONTEXT, |
186 | - attribs.constData()); |
187 | - |
188 | - Q_ASSERT(mEglContext != EGL_NO_CONTEXT); |
189 | -} |
190 | - |
191 | -UbuntuOpenGLContext::~UbuntuOpenGLContext() |
192 | -{ |
193 | - ASSERT(eglDestroyContext(mEglDisplay, mEglContext) == EGL_TRUE); |
194 | } |
195 | |
196 | static bool needsFBOReadBackWorkaround() |
197 | @@ -179,7 +59,7 @@ |
198 | static bool set = false; |
199 | static bool needsWorkaround = false; |
200 | |
201 | - if (!set) { |
202 | + if (Q_UNLIKELY(!set)) { |
203 | const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); |
204 | needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 0 |
205 | || qstrncmp(rendererString, "Mali-T7", 7) == 0 |
206 | @@ -202,47 +82,32 @@ |
207 | } |
208 | return offscreen->buffer()->bind(); |
209 | } else { |
210 | - EGLSurface eglSurface = static_cast<UbuntuWindow*>(surface)->eglSurface(); |
211 | - ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE); |
212 | - |
213 | - EGLBoolean result = eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext); |
214 | - if (result == EGL_FALSE) { |
215 | - qCCritical(ubuntumirclient, "eglMakeCurrent() failed with %s", |
216 | - qPrintable(eglErrorToString(eglGetError()))); |
217 | - return false; |
218 | - } |
219 | - |
220 | - QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context()); |
221 | - if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) { |
222 | - ctx_d->workaround_brokenFBOReadBack = true; |
223 | - } |
224 | - |
225 | - if (ubuntumirclient().isDebugEnabled()) { |
226 | - printOpenGLESConfig(); |
227 | - } |
228 | - return true; |
229 | + const bool ret = QEGLPlatformContext::makeCurrent(surface); |
230 | + |
231 | + if (Q_LIKELY(ret)) { |
232 | + QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context()); |
233 | + if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) { |
234 | + ctx_d->workaround_brokenFBOReadBack = true; |
235 | + } |
236 | + } |
237 | + |
238 | + return ret; |
239 | } |
240 | } |
241 | |
242 | -void UbuntuOpenGLContext::doneCurrent() |
243 | +// Following method used internally in the base class QEGLPlatformContext to access |
244 | +// the egl surface of a QPlatformSurface/UbuntuWindow |
245 | +EGLSurface UbuntuOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) |
246 | { |
247 | - ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE); |
248 | - ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE); |
249 | + auto ubuntuWindow = static_cast<UbuntuWindow *>(surface); |
250 | + return ubuntuWindow->eglSurface(); |
251 | } |
252 | |
253 | -void UbuntuOpenGLContext::swapBuffers(QPlatformSurface* surface) |
254 | +void UbuntuOpenGLContext::swapBuffers(QPlatformSurface *surface) |
255 | { |
256 | - UbuntuWindow *ubuntuWindow = static_cast<UbuntuWindow*>(surface); |
257 | - |
258 | - EGLSurface eglSurface = ubuntuWindow->eglSurface(); |
259 | - ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE); |
260 | - ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE); |
261 | - |
262 | + QEGLPlatformContext::swapBuffers(surface); |
263 | + |
264 | + // notify window on swap completion |
265 | + auto ubuntuWindow = static_cast<UbuntuWindow *>(surface); |
266 | ubuntuWindow->onSwapBuffersDone(); |
267 | } |
268 | - |
269 | -void (*UbuntuOpenGLContext::getProcAddress(const QByteArray& procName)) () |
270 | -{ |
271 | - ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE); |
272 | - return eglGetProcAddress(procName.constData()); |
273 | -} |
274 | |
275 | === modified file 'src/ubuntumirclient/glcontext.h' |
276 | --- src/ubuntumirclient/glcontext.h 2016-04-28 14:09:54 +0000 |
277 | +++ src/ubuntumirclient/glcontext.h 2016-06-03 10:25:36 +0000 |
278 | @@ -18,30 +18,22 @@ |
279 | #define UBUNTU_OPENGL_CONTEXT_H |
280 | |
281 | #include <qpa/qplatformopenglcontext.h> |
282 | +#include <private/qeglplatformcontext_p.h> |
283 | |
284 | #include <EGL/egl.h> |
285 | |
286 | -class UbuntuOpenGLContext : public QPlatformOpenGLContext |
287 | +class UbuntuOpenGLContext : public QEGLPlatformContext |
288 | { |
289 | public: |
290 | - UbuntuOpenGLContext(const QSurfaceFormat &surfaceFormat, UbuntuOpenGLContext *share, |
291 | - EGLDisplay display, EGLConfig config); |
292 | - virtual ~UbuntuOpenGLContext(); |
293 | - |
294 | - // QPlatformOpenGLContext methods. |
295 | - QSurfaceFormat format() const override { return mSurfaceFormat; } |
296 | - void swapBuffers(QPlatformSurface *surface) override; |
297 | - bool makeCurrent(QPlatformSurface *surface) override; |
298 | - void doneCurrent() override; |
299 | - bool isValid() const override { return mEglContext != EGL_NO_CONTEXT; } |
300 | - void (*getProcAddress(const QByteArray& procName)) () override; |
301 | - |
302 | - EGLContext eglContext() const { return mEglContext; } |
303 | - |
304 | -private: |
305 | - const QSurfaceFormat mSurfaceFormat; |
306 | - EGLContext mEglContext; |
307 | - EGLDisplay mEglDisplay; |
308 | + UbuntuOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, |
309 | + EGLDisplay display); |
310 | + |
311 | + // QEGLPlatformContext methods. |
312 | + void swapBuffers(QPlatformSurface *surface) final; |
313 | + bool makeCurrent(QPlatformSurface *surface) final; |
314 | + |
315 | +protected: |
316 | + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) final; |
317 | }; |
318 | |
319 | #endif // UBUNTU_OPENGL_CONTEXT_H |
320 | |
321 | === modified file 'src/ubuntumirclient/integration.cpp' |
322 | --- src/ubuntumirclient/integration.cpp 2016-04-28 14:44:18 +0000 |
323 | +++ src/ubuntumirclient/integration.cpp 2016-06-03 10:25:36 +0000 |
324 | @@ -29,7 +29,6 @@ |
325 | |
326 | // Qt |
327 | #include <QGuiApplication> |
328 | -#include <private/qguiapplication_p.h> |
329 | #include <qpa/qplatformnativeinterface.h> |
330 | #include <qpa/qplatforminputcontextfactory_p.h> |
331 | #include <qpa/qplatforminputcontext.h> |
332 | @@ -90,31 +89,17 @@ |
333 | |
334 | mMirConnection = u_application_instance_get_mir_connection(mInstance); |
335 | |
336 | + // Choose the default surface format suited to the Mir platform |
337 | + QSurfaceFormat defaultFormat; |
338 | + defaultFormat.setRedBufferSize(8); |
339 | + defaultFormat.setGreenBufferSize(8); |
340 | + defaultFormat.setBlueBufferSize(8); |
341 | + QSurfaceFormat::setDefaultFormat(defaultFormat); |
342 | + |
343 | // Initialize EGL. |
344 | - ASSERT(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE); |
345 | - |
346 | mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection); |
347 | ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY); |
348 | ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE); |
349 | - |
350 | - // Configure EGL buffers format for all Windows. |
351 | - mSurfaceFormat.setRedBufferSize(8); |
352 | - mSurfaceFormat.setGreenBufferSize(8); |
353 | - mSurfaceFormat.setBlueBufferSize(8); |
354 | - mSurfaceFormat.setAlphaBufferSize(8); |
355 | - mSurfaceFormat.setDepthBufferSize(24); |
356 | - mSurfaceFormat.setStencilBufferSize(8); |
357 | - if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) { |
358 | - mSurfaceFormat.setSamples(4); |
359 | - qCDebug(ubuntumirclient, "setting MSAA to 4 samples"); |
360 | - } |
361 | -#ifdef QTUBUNTU_USE_OPENGL |
362 | - mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL); |
363 | -#else |
364 | - mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES); |
365 | -#endif |
366 | - |
367 | - mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true); |
368 | } |
369 | |
370 | void UbuntuClientIntegration::initialize() |
371 | @@ -192,12 +177,7 @@ |
372 | |
373 | QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) const |
374 | { |
375 | - return const_cast<UbuntuClientIntegration*>(this)->createPlatformWindow(window); |
376 | -} |
377 | - |
378 | -QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) |
379 | -{ |
380 | - return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, mEglDisplay, mEglConfig, mMirConnection); |
381 | + return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, mEglDisplay, mMirConnection); |
382 | } |
383 | |
384 | bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const |
385 | @@ -240,14 +220,25 @@ |
386 | QPlatformOpenGLContext* UbuntuClientIntegration::createPlatformOpenGLContext( |
387 | QOpenGLContext* context) const |
388 | { |
389 | - return const_cast<UbuntuClientIntegration*>(this)->createPlatformOpenGLContext(context); |
390 | -} |
391 | + QSurfaceFormat format(context->format()); |
392 | |
393 | -QPlatformOpenGLContext* UbuntuClientIntegration::createPlatformOpenGLContext( |
394 | - QOpenGLContext* context) |
395 | -{ |
396 | - return new UbuntuOpenGLContext(mSurfaceFormat, static_cast<UbuntuOpenGLContext*>(context->shareHandle()), |
397 | - mEglDisplay, mEglConfig); |
398 | + auto platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay); |
399 | + if (!platformContext->isValid()) { |
400 | + // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default |
401 | + // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a |
402 | + // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to |
403 | + // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default |
404 | + // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). |
405 | + static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa")); |
406 | + if (isMesa) { |
407 | + qCDebug(ubuntumirclient, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); |
408 | + format.setMajorVersion(1); |
409 | + format.setMinorVersion(4); |
410 | + delete platformContext; |
411 | + platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay); |
412 | + } |
413 | + } |
414 | + return platformContext; |
415 | } |
416 | |
417 | QStringList UbuntuClientIntegration::themeNames() const |
418 | |
419 | === modified file 'src/ubuntumirclient/integration.h' |
420 | --- src/ubuntumirclient/integration.h 2016-04-28 14:09:54 +0000 |
421 | +++ src/ubuntumirclient/integration.h 2016-06-03 10:25:36 +0000 |
422 | @@ -60,15 +60,9 @@ |
423 | void initialize() override; |
424 | QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; |
425 | |
426 | - // non-const versions of some QPlatformIntegration methods |
427 | - QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context); |
428 | - QPlatformWindow* createPlatformWindow(QWindow* window); |
429 | - |
430 | // New methods. |
431 | MirConnection *mirConnection() const { return mMirConnection; } |
432 | - QSurfaceFormat surfaceFormat() const { return mSurfaceFormat; } |
433 | EGLDisplay eglDisplay() const { return mEglDisplay; } |
434 | - EGLConfig eglConfig() const { return mEglConfig; } |
435 | EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; } |
436 | UbuntuScreenObserver *screenObserver() const { return mScreenObserver.data(); } |
437 | |
438 | @@ -99,9 +93,7 @@ |
439 | |
440 | // EGL related |
441 | EGLDisplay mEglDisplay{EGL_NO_DISPLAY}; |
442 | - EGLConfig mEglConfig{nullptr}; |
443 | EGLNativeDisplayType mEglNativeDisplay; |
444 | - QSurfaceFormat mSurfaceFormat; |
445 | }; |
446 | |
447 | #endif // UBUNTU_CLIENT_INTEGRATION_H |
448 | |
449 | === modified file 'src/ubuntumirclient/window.cpp' |
450 | --- src/ubuntumirclient/window.cpp 2016-04-28 14:44:18 +0000 |
451 | +++ src/ubuntumirclient/window.cpp 2016-06-03 10:25:36 +0000 |
452 | @@ -29,6 +29,7 @@ |
453 | #include <QMutexLocker> |
454 | #include <QSize> |
455 | #include <QtMath> |
456 | +#include <private/qeglconvenience_p.h> |
457 | |
458 | // Platform API |
459 | #include <ubuntu/application/instance.h> |
460 | @@ -101,6 +102,24 @@ |
461 | } |
462 | } |
463 | |
464 | +const char *mirPixelFormatToStr(MirPixelFormat pixelFormat) |
465 | +{ |
466 | + switch (pixelFormat) { |
467 | + case mir_pixel_format_invalid: return "invalid"; |
468 | + case mir_pixel_format_abgr_8888: return "ABGR8888"; |
469 | + case mir_pixel_format_xbgr_8888: return "XBGR8888"; |
470 | + case mir_pixel_format_argb_8888: return "ARGB8888"; |
471 | + case mir_pixel_format_xrgb_8888: return "XRGB8888"; |
472 | + case mir_pixel_format_bgr_888: return "BGR888"; |
473 | + case mir_pixel_format_rgb_888: return "RGB888"; |
474 | + case mir_pixel_format_rgb_565: return "RGB565"; |
475 | + case mir_pixel_format_rgba_5551: return "RGBA5551"; |
476 | + case mir_pixel_format_rgba_4444: return "RGBA4444"; |
477 | + case mir_pixel_formats: |
478 | + default: return "???"; |
479 | + } |
480 | +} |
481 | + |
482 | MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state) |
483 | { |
484 | switch (state) { |
485 | @@ -124,14 +143,6 @@ |
486 | return id++; |
487 | } |
488 | |
489 | -MirPixelFormat defaultPixelFormatFor(MirConnection *connection) |
490 | -{ |
491 | - MirPixelFormat format; |
492 | - unsigned int nformats; |
493 | - mir_connection_get_available_surface_formats(connection, &format, 1, &nformats); |
494 | - return format; |
495 | -} |
496 | - |
497 | UAUiWindowRole roleFor(QWindow *window) |
498 | { |
499 | QVariant roleVariant = window->property("role"); |
500 | @@ -151,12 +162,11 @@ |
501 | return parent ? static_cast<UbuntuWindow *>(parent->handle()) : nullptr; |
502 | } |
503 | |
504 | -Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirConnection *connection) |
505 | +Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirPixelFormat pixelFormat, MirConnection *connection) |
506 | { |
507 | const auto geom = window->geometry(); |
508 | const int width = geom.width() > 0 ? geom.width() : 1; |
509 | const int height = geom.height() > 0 ? geom.height() : 1; |
510 | - const auto pixelFormat = defaultPixelFormatFor(connection); |
511 | |
512 | if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) { |
513 | qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height); |
514 | @@ -217,11 +227,11 @@ |
515 | } |
516 | } |
517 | |
518 | -MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input, |
519 | +MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input, MirPixelFormat pixelFormat, |
520 | MirConnection *connection, mir_surface_event_callback inputCallback, |
521 | void* inputContext) |
522 | { |
523 | - auto spec = makeSurfaceSpec(window, input, connection); |
524 | + auto spec = makeSurfaceSpec(window, input, pixelFormat, connection); |
525 | |
526 | // Install event handler as early as possible |
527 | mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext); |
528 | @@ -244,6 +254,18 @@ |
529 | return surface; |
530 | } |
531 | |
532 | +MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat) |
533 | +{ |
534 | + switch(pixelFormat) { |
535 | + case mir_pixel_format_abgr_8888: |
536 | + return mir_pixel_format_xbgr_8888; |
537 | + case mir_pixel_format_argb_8888: |
538 | + return mir_pixel_format_xrgb_8888; |
539 | + default: // can do nothing, leave it alone |
540 | + return pixelFormat; |
541 | + } |
542 | +} |
543 | + |
544 | // FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633 |
545 | // we need to guess the panel height (3GU) |
546 | int panelHeight() |
547 | @@ -266,8 +288,7 @@ |
548 | class UbuntuSurface |
549 | { |
550 | public: |
551 | - UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, EGLConfig config, int mirOutputId, |
552 | - UbuntuInput *input, MirConnection *connection) |
553 | + UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, UbuntuInput *input, MirConnection *connection) |
554 | : mWindow(platformWindow->window()) |
555 | , mPlatformWindow(platformWindow) |
556 | , mInput(input) |
557 | @@ -275,9 +296,44 @@ |
558 | , mEglDisplay(display) |
559 | , mNeedsRepaint(false) |
560 | , mParented(mWindow->transientParent() || mWindow->parent()) |
561 | + , mFormat(mWindow->requestedFormat()) |
562 | , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) |
563 | { |
564 | - mMirSurface = createMirSurface(mWindow, mirOutputId, input, connection, surfaceEventCallback, this); |
565 | + // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it |
566 | + EGLConfig config = q_configFromGLFormat(display, mFormat, true); |
567 | + if (config == 0) { |
568 | + // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default |
569 | + // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a |
570 | + // 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to |
571 | + // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default |
572 | + // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). |
573 | + static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa")); |
574 | + if (isMesa) { |
575 | + qCDebug(ubuntumirclient, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); |
576 | + mFormat.setMajorVersion(1); |
577 | + mFormat.setMinorVersion(4); |
578 | + config = q_configFromGLFormat(display, mFormat, true); |
579 | + } |
580 | + } |
581 | + if (config == 0) { |
582 | + qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat; |
583 | + } |
584 | + |
585 | + mFormat = q_glFormatFromConfig(display, config, mFormat); |
586 | + |
587 | + // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way |
588 | + // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers. |
589 | + auto pixelFormat = mir_connection_get_egl_pixel_format(connection, display, config); |
590 | + // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client. |
591 | + // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer. |
592 | + // This is an optimisation for the compositor, as it can avoid blending this surface. |
593 | + if (mWindow->requestedFormat().alphaBufferSize() < 0) { |
594 | + pixelFormat = disableAlphaBufferIfPossible(pixelFormat); |
595 | + } |
596 | + |
597 | + const auto outputId = static_cast<UbuntuScreen *>(mWindow->screen()->handle())->mirOutputId(); |
598 | + |
599 | + mMirSurface = createMirSurface(mWindow, outputId, input, pixelFormat, connection, surfaceEventCallback, this); |
600 | mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr); |
601 | |
602 | // Window manager can give us a final size different from what we asked for |
603 | @@ -299,8 +355,11 @@ |
604 | platformWindow->QPlatformWindow::setGeometry(geom); |
605 | QWindowSystemInterface::handleGeometryChange(mWindow, geom); |
606 | |
607 | - qCDebug(ubuntumirclient, "created surface at (%d, %d) with size (%d, %d), title '%s', role: '%d'\n", |
608 | - geom.x(), geom.y(), geom.width(), geom.height(), mWindow->title().toUtf8().constData(), roleFor(mWindow)); |
609 | + qCDebug(ubuntumirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title() |
610 | + << "role:" << roleFor(mWindow) |
611 | + << "\nRequested format:" << mWindow->requestedFormat() |
612 | + << "\nActual format:" << mFormat |
613 | + << "with associated Mir pixel format:" << mirPixelFormatToStr(pixelFormat); |
614 | } |
615 | |
616 | ~UbuntuSurface() |
617 | @@ -335,6 +394,8 @@ |
618 | void setSurfaceParent(MirSurface*); |
619 | bool hasParent() const { return mParented; } |
620 | |
621 | + QSurfaceFormat format() const { return mFormat; } |
622 | + |
623 | private: |
624 | static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context); |
625 | void postEvent(const MirEvent *event); |
626 | @@ -351,6 +412,7 @@ |
627 | bool mNeedsRepaint; |
628 | bool mParented; |
629 | QSize mBufferSize; |
630 | + QSurfaceFormat mFormat; |
631 | |
632 | QMutex mTargetSizeMutex; |
633 | QSize mTargetSize; |
634 | @@ -509,8 +571,7 @@ |
635 | } |
636 | |
637 | UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard, |
638 | - UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay, |
639 | - EGLConfig eglConfig, MirConnection *mirConnection) |
640 | + UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay, MirConnection *mirConnection) |
641 | : QObject(nullptr) |
642 | , QPlatformWindow(w) |
643 | , mId(makeId()) |
644 | @@ -520,8 +581,7 @@ |
645 | , mWindowVisible(false) |
646 | , mWindowExposed(true) |
647 | , mNativeInterface(native) |
648 | - , mSurface(new UbuntuSurface{this, eglDisplay, eglConfig, |
649 | - static_cast<UbuntuScreen*>(w->screen()->handle())->mirOutputId(), input, mirConnection}) |
650 | + , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection}) |
651 | , mScale(1.0) |
652 | , mFormFactor(mir_form_factor_unknown) |
653 | { |
654 | @@ -709,6 +769,11 @@ |
655 | return mWindowVisible && mWindowExposed; |
656 | } |
657 | |
658 | +QSurfaceFormat UbuntuWindow::format() const |
659 | +{ |
660 | + return mSurface->format(); |
661 | +} |
662 | + |
663 | void* UbuntuWindow::eglSurface() const |
664 | { |
665 | return mSurface->eglSurface(); |
666 | |
667 | === modified file 'src/ubuntumirclient/window.h' |
668 | --- src/ubuntumirclient/window.h 2016-04-28 14:44:18 +0000 |
669 | +++ src/ubuntumirclient/window.h 2016-06-03 10:25:36 +0000 |
670 | @@ -40,7 +40,7 @@ |
671 | Q_OBJECT |
672 | public: |
673 | UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard, |
674 | - UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay, EGLConfig eglConfig, |
675 | + UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay, |
676 | MirConnection *mirConnection); |
677 | virtual ~UbuntuWindow(); |
678 | |
679 | @@ -54,6 +54,8 @@ |
680 | void propagateSizeHints() override; |
681 | bool isExposed() const override; |
682 | |
683 | + QSurfaceFormat format() const override; |
684 | + |
685 | // Additional Window properties exposed by NativeInterface |
686 | MirFormFactor formFactor() const { return mFormFactor; } |
687 | float scale() const { return mScale; } |
PASSED: Continuous integration, rev:317 /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- ci/55/ /unity8- jenkins. ubuntu. com/job/ build-0- fetch/1696 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 1646 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 1646 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 1639 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 1639/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1639 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1639/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 1639 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 1639/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1639 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1639/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 1639 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 1639/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1639 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1639/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-qtubuntu- ci/55/rebuild
https:/