summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/mirclient/qmirclientscreen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/mirclient/qmirclientscreen.cpp')
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreen.cpp278
1 files changed, 117 insertions, 161 deletions
diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.cpp b/src/plugins/platforms/mirclient/qmirclientscreen.cpp
index 0a2253e9e2..cc8db830aa 100644
--- a/src/plugins/platforms/mirclient/qmirclientscreen.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientscreen.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -42,11 +42,12 @@
#include "qmirclientscreen.h"
#include "qmirclientlogging.h"
#include "qmirclientorientationchangeevent_p.h"
+#include "qmirclientnativeinterface.h"
#include <mir_toolkit/mir_client_library.h>
// Qt
-#include <QCoreApplication>
+#include <QGuiApplication>
#include <QtCore/qmath.h>
#include <QScreen>
#include <QThread>
@@ -55,9 +56,7 @@
#include <memory>
-static const int kSwapInterval = 1;
-
-#if !defined(QT_NO_DEBUG)
+static const int overrideDevicePixelRatio = qgetenv("QT_DEVICE_PIXEL_RATIO").toInt();
static const char *orientationToStr(Qt::ScreenOrientation orientation) {
switch (orientation) {
@@ -71,173 +70,33 @@ static const char *orientationToStr(Qt::ScreenOrientation orientation) {
return "inverted portrait";
case Qt::InvertedLandscapeOrientation:
return "inverted landscape";
- default:
- return "INVALID!";
}
+ Q_UNREACHABLE();
}
-static void printEglConfig(EGLDisplay display, EGLConfig config) {
- DASSERT(display != EGL_NO_DISPLAY);
- DASSERT(config != nullptr);
- static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
- { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
- { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
- { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
- { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
- { EGL_RED_SIZE, "EGL_RED_SIZE" },
- { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
- { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
- { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
- { EGL_CONFIG_ID, "EGL_CONFIG_ID" },
- { EGL_LEVEL, "EGL_LEVEL" },
- { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
- { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
- { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
- { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
- { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
- { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
- { EGL_SAMPLES, "EGL_SAMPLES" },
- { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
- { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
- { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
- { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
- { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
- { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
- { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
- { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
- { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
- { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
- { -1, NULL }
- };
- const char* string = eglQueryString(display, EGL_VENDOR);
- LOG("EGL vendor: %s", string);
- string = eglQueryString(display, EGL_VERSION);
- LOG("EGL version: %s", string);
- string = eglQueryString(display, EGL_EXTENSIONS);
- LOG("EGL extensions: %s", string);
- LOG("EGL configuration attibutes:");
- for (int index = 0; kAttribs[index].attrib != -1; index++) {
- EGLint value;
- if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
- LOG(" %s: %d", kAttribs[index].name, static_cast<int>(value));
- }
-}
-#endif
-
-
const QEvent::Type OrientationChangeEvent::mType =
static_cast<QEvent::Type>(QEvent::registerEventType());
-static const MirDisplayOutput *find_active_output(
- const MirDisplayConfiguration *conf)
-{
- const MirDisplayOutput *output = NULL;
- for (uint32_t d = 0; d < conf->num_outputs; d++)
- {
- const MirDisplayOutput *out = conf->outputs + d;
-
- if (out->used &&
- out->connected &&
- out->num_modes &&
- out->current_mode < out->num_modes)
- {
- output = out;
- break;
- }
- }
-
- return output;
-}
-QMirClientScreen::QMirClientScreen(MirConnection *connection)
- : mFormat(QImage::Format_RGB32)
+QMirClientScreen::QMirClientScreen(const MirOutput *output, MirConnection *connection)
+ : mDevicePixelRatio(1.0)
+ , mFormat(QImage::Format_RGB32)
, mDepth(32)
+ , mDpi{0}
+ , mFormFactor{mir_form_factor_unknown}
+ , mScale{1.0}
, mOutputId(0)
- , mSurfaceFormat()
- , mEglDisplay(EGL_NO_DISPLAY)
- , mEglConfig(nullptr)
, mCursor(connection)
{
- // Initialize EGL.
- ASSERT(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
-
- mEglNativeDisplay = mir_connection_get_egl_native_display(connection);
- ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
- ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
-
- // Configure EGL buffers format.
- mSurfaceFormat.setRedBufferSize(8);
- mSurfaceFormat.setGreenBufferSize(8);
- mSurfaceFormat.setBlueBufferSize(8);
- mSurfaceFormat.setAlphaBufferSize(8);
- mSurfaceFormat.setDepthBufferSize(24);
- mSurfaceFormat.setStencilBufferSize(8);
- if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) {
- mSurfaceFormat.setSamples(4);
- DLOG("ubuntumirclient: setting MSAA to 4 samples");
- }
-#ifdef QTUBUNTU_USE_OPENGL
- mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
-#else
- mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
-#endif
- mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true);
-
- #if !defined(QT_NO_DEBUG)
- printEglConfig(mEglDisplay, mEglConfig);
- #endif
-
- // Set vblank swap interval.
- int swapInterval = kSwapInterval;
- QByteArray swapIntervalString = qgetenv("QTUBUNTU_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = kSwapInterval;
- }
- DLOG("ubuntumirclient: setting swap interval to %d", swapInterval);
- eglSwapInterval(mEglDisplay, swapInterval);
-
- // Get screen resolution.
- auto configDeleter = [](MirDisplayConfiguration *config) { mir_display_config_destroy(config); };
- using configUp = std::unique_ptr<MirDisplayConfiguration, decltype(configDeleter)>;
- configUp displayConfig(mir_connection_create_display_config(connection), configDeleter);
- ASSERT(displayConfig != nullptr);
-
- auto const displayOutput = find_active_output(displayConfig.get());
- ASSERT(displayOutput != nullptr);
-
- mOutputId = displayOutput->output_id;
-
- mPhysicalSize = QSizeF(displayOutput->physical_width_mm, displayOutput->physical_height_mm);
- DLOG("ubuntumirclient: screen physical size: %.2fx%.2f", mPhysicalSize.width(), mPhysicalSize.height());
-
- const MirDisplayMode *mode = &displayOutput->modes[displayOutput->current_mode];
- const int kScreenWidth = mode->horizontal_resolution;
- const int kScreenHeight = mode->vertical_resolution;
- DASSERT(kScreenWidth > 0 && kScreenHeight > 0);
-
- DLOG("ubuntumirclient: screen resolution: %dx%d", kScreenWidth, kScreenHeight);
-
- mGeometry = QRect(0, 0, kScreenWidth, kScreenHeight);
-
- DLOG("QQMirClientScreen::QQMirClientScreen (this=%p)", this);
-
- // Set the default orientation based on the initial screen dimmensions.
- mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
-
- // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
- mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+ setMirOutput(output);
}
QMirClientScreen::~QMirClientScreen()
{
- eglTerminate(mEglDisplay);
}
void QMirClientScreen::customEvent(QEvent* event) {
- DASSERT(QThread::currentThread() == thread());
+ Q_ASSERT(QThread::currentThread() == thread());
OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event);
switch (oReadingEvent->mOrientation) {
@@ -261,14 +120,10 @@ void QMirClientScreen::customEvent(QEvent* event) {
Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation;
break;
}
- default: {
- DLOG("QMirClientScreen::customEvent - Unknown orientation.");
- return;
- }
}
// Raise the event signal so that client apps know the orientation changed
- DLOG("QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
+ qCDebug(mirclient, "QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
}
@@ -289,7 +144,7 @@ void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeig
mGeometry.setWidth(currGeometry.height());
mGeometry.setHeight(currGeometry.width());
- DLOG("QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
+ qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
mGeometry.width(), mGeometry.height());
QWindowSystemInterface::handleScreenGeometryChange(screen(),
mGeometry /* newGeometry */,
@@ -300,7 +155,108 @@ void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeig
} else {
mCurrentOrientation = Qt::LandscapeOrientation;
}
- DLOG("QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
+ qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
}
}
+
+void QMirClientScreen::setMirOutput(const MirOutput *output)
+{
+ // Physical screen size (in mm)
+ mPhysicalSize.setWidth(mir_output_get_physical_width_mm(output));
+ mPhysicalSize.setHeight(mir_output_get_physical_height_mm(output));
+
+ // Pixel Format
+// mFormat = qImageFormatFromMirPixelFormat(mir_output_get_current_pixel_format(output)); // GERRY: TODO
+
+ // Pixel depth
+ mDepth = 8 * MIR_BYTES_PER_PIXEL(mir_output_get_current_pixel_format(output));
+
+ // Mode = Resolution & refresh rate
+ const MirOutputMode *mode = mir_output_get_current_mode(output);
+ mNativeGeometry.setX(mir_output_get_position_x(output));
+ mNativeGeometry.setY(mir_output_get_position_y(output));
+ mNativeGeometry.setWidth(mir_output_mode_get_width(mode));
+ mNativeGeometry.setHeight(mir_output_mode_get_height(mode));
+
+ mRefreshRate = mir_output_mode_get_refresh_rate(mode);
+
+ // UI scale & DPR
+ mScale = mir_output_get_scale_factor(output);
+ if (overrideDevicePixelRatio > 0) {
+ mDevicePixelRatio = overrideDevicePixelRatio;
+ } else {
+ mDevicePixelRatio = 1.0; // FIXME - need to determine suitable DPR for the specified scale
+ }
+
+ mFormFactor = mir_output_get_form_factor(output);
+
+ mOutputId = mir_output_get_id(output);
+
+ mGeometry.setX(mNativeGeometry.x());
+ mGeometry.setY(mNativeGeometry.y());
+ mGeometry.setWidth(mNativeGeometry.width());
+ mGeometry.setHeight(mNativeGeometry.height());
+
+ // Set the default orientation based on the initial screen dimensions.
+ mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+
+ // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
+ mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+}
+
+void QMirClientScreen::updateMirOutput(const MirOutput *output)
+{
+ auto oldRefreshRate = mRefreshRate;
+ auto oldScale = mScale;
+ auto oldFormFactor = mFormFactor;
+ auto oldGeometry = mGeometry;
+
+ setMirOutput(output);
+
+ // Emit change signals in particular order
+ if (oldGeometry != mGeometry) {
+ QWindowSystemInterface::handleScreenGeometryChange(screen(),
+ mGeometry /* newGeometry */,
+ mGeometry /* newAvailableGeometry */);
+ }
+
+ if (!qFuzzyCompare(mRefreshRate, oldRefreshRate)) {
+ QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate);
+ }
+
+ auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface());
+ if (!qFuzzyCompare(mScale, oldScale)) {
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("scale"));
+ }
+ if (mFormFactor != oldFormFactor) {
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor"));
+ }
+}
+
+void QMirClientScreen::setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi)
+{
+ if (mDpi != dpi) {
+ mDpi = dpi;
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), dpi, dpi);
+ }
+
+ auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface());
+ if (!qFuzzyCompare(mScale, scale)) {
+ mScale = scale;
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("scale"));
+ }
+ if (mFormFactor != formFactor) {
+ mFormFactor = formFactor;
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor"));
+ }
+}
+
+QDpi QMirClientScreen::logicalDpi() const
+{
+ if (mDpi > 0) {
+ return QDpi(mDpi, mDpi);
+ } else {
+ return QPlatformScreen::logicalDpi();
+ }
+}