105
const char *mirPixelFormatToStr(MirPixelFormat pixelFormat)
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 "???";
104
123
MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
151
162
return parent ? static_cast<UbuntuWindow *>(parent->handle()) : nullptr;
154
Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirConnection *connection)
165
Spec makeSurfaceSpec(QWindow *window, UbuntuInput *input, MirPixelFormat pixelFormat, MirConnection *connection)
156
167
const auto geom = window->geometry();
157
168
const int width = geom.width() > 0 ? geom.width() : 1;
158
169
const int height = geom.height() > 0 ? geom.height() : 1;
159
const auto pixelFormat = defaultPixelFormatFor(connection);
161
171
if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
162
172
qCDebug(ubuntumirclient, "makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height);
220
MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input,
230
MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input, MirPixelFormat pixelFormat,
221
231
MirConnection *connection, mir_surface_event_callback inputCallback,
222
232
void* inputContext)
224
auto spec = makeSurfaceSpec(window, input, connection);
234
auto spec = makeSurfaceSpec(window, input, pixelFormat, connection);
226
236
// Install event handler as early as possible
227
237
mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);
257
MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat)
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
247
269
// FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633
248
270
// we need to guess the panel height (3GU)
249
271
int panelHeight()
266
288
class UbuntuSurface
269
UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, EGLConfig config, int mirOutputId,
270
UbuntuInput *input, MirConnection *connection)
291
UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, UbuntuInput *input, MirConnection *connection)
271
292
: mWindow(platformWindow->window())
272
293
, mPlatformWindow(platformWindow)
275
296
, mEglDisplay(display)
276
297
, mNeedsRepaint(false)
277
298
, mParented(mWindow->transientParent() || mWindow->parent())
299
, mFormat(mWindow->requestedFormat())
278
300
, mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)
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);
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"));
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);
319
qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat;
322
mFormat = q_glFormatFromConfig(display, config, mFormat);
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);
334
const auto outputId = static_cast<UbuntuScreen *>(mWindow->screen()->handle())->mirOutputId();
336
mMirSurface = createMirSurface(mWindow, outputId, input, pixelFormat, connection, surfaceEventCallback, this);
281
337
mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr);
283
339
// Window manager can give us a final size different from what we asked for
299
355
platformWindow->QPlatformWindow::setGeometry(geom);
300
356
QWindowSystemInterface::handleGeometryChange(mWindow, geom);
302
qCDebug(ubuntumirclient, "created surface at (%d, %d) with size (%d, %d), title '%s', role: '%d'\n",
303
geom.x(), geom.y(), geom.width(), geom.height(), mWindow->title().toUtf8().constData(), roleFor(mWindow));
358
qCDebug(ubuntumirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title()
359
<< "role:" << roleFor(mWindow)
360
<< "\nRequested format:" << mWindow->requestedFormat()
361
<< "\nActual format:" << mFormat
362
<< "with associated Mir pixel format:" << mirPixelFormatToStr(pixelFormat);
511
573
UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
512
UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay,
513
EGLConfig eglConfig, MirConnection *mirConnection)
574
UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay, MirConnection *mirConnection)
514
575
: QObject(nullptr)
515
576
, QPlatformWindow(w)
520
581
, mWindowVisible(false)
521
582
, mWindowExposed(true)
522
583
, mNativeInterface(native)
523
, mSurface(new UbuntuSurface{this, eglDisplay, eglConfig,
524
static_cast<UbuntuScreen*>(w->screen()->handle())->mirOutputId(), input, mirConnection})
584
, mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection})
526
586
, mFormFactor(mir_form_factor_unknown)