~dandrader/qtmir/surfaceDrawn

« back to all changes in this revision

Viewing changes to src/platforms/mirserver/screen.cpp

  • Committer: CI Train Bot
  • Author(s): Gerry Boland, Michał Sawicz, Nick Dedekind
  • Date: 2016-04-29 20:04:51 UTC
  • mfrom: (434.5.64 set-display-config)
  • Revision ID: ci-train-bot@canonical.com-20160429200451-v0bjc4pcypynt83b
Enhance ScreenController & the DisplayConfigurationPolicy to implement dynamic grid units.

- Rename ScreenController to ScreenModel, as it just reflects current screen state, does not offer means to configure it
- ScreenController can update state of existing Screens, based on Mir DisplayConfiguration changes.
- Expand Screen to include scale & form factor properties, with getter/notifier in NativeInterface. This enables the dynamic grid units in the shell
- Add a Unity.Screens qml module to give QML better information about connected screens, and allow basic reconfiguring.
- Implement a basic display configuration policy to set suitable scale and form factor on an external display (needed for dynamic grid units) Fixes: #1573532
Approved by: Unity8 CI Bot, Daniel d'Andrada

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2013-2015 Canonical, Ltd.
 
2
 * Copyright (C) 2013-2016 Canonical, Ltd.
3
3
 *
4
4
 * This program is free software: you can redistribute it and/or modify it under
5
5
 * the terms of the GNU Lesser General Public License version 3, as published by
17
17
// local
18
18
#include "screen.h"
19
19
#include "logging.h"
 
20
#include "nativeinterface.h"
20
21
 
21
22
// Mir
22
23
#include "mir/geometry/size.h"
26
27
#include <mir/renderer/gl/render_target.h>
27
28
 
28
29
// Qt
29
 
#include <QCoreApplication>
 
30
#include <QGuiApplication>
30
31
#include <qpa/qwindowsysteminterface.h>
31
32
#include <QThread>
 
33
#include <QtMath>
32
34
 
33
35
// Qt sensors
34
36
#include <QtSensors/QOrientationReading>
96
98
    }
97
99
}
98
100
 
 
101
QString displayTypeToString(enum mir::graphics::DisplayConfigurationOutputType type)
 
102
{
 
103
    typedef mir::graphics::DisplayConfigurationOutputType Type;
 
104
    switch (type) {
 
105
    case Type::vga:           return QStringLiteral("VGP");
 
106
    case Type::dvii:          return QStringLiteral("DVI-I");
 
107
    case Type::dvid:          return QStringLiteral("DVI-D");
 
108
    case Type::dvia:          return QStringLiteral("DVI-A");
 
109
    case Type::composite:     return QStringLiteral("Composite");
 
110
    case Type::svideo:        return QStringLiteral("S-Video");
 
111
    case Type::lvds:          return QStringLiteral("LVDS");
 
112
    case Type::component:     return QStringLiteral("Component");
 
113
    case Type::ninepindin:    return QStringLiteral("9 Pin DIN");
 
114
    case Type::displayport:   return QStringLiteral("DisplayPort");
 
115
    case Type::hdmia:         return QStringLiteral("HDMI-A");
 
116
    case Type::hdmib:         return QStringLiteral("HDMI-B");
 
117
    case Type::tv:            return QStringLiteral("TV");
 
118
    case Type::edp:           return QStringLiteral("EDP");
 
119
    case Type::unknown:
 
120
    default:
 
121
        return QStringLiteral("Unknown");
 
122
    } //switch
 
123
}
99
124
} // namespace {
100
125
 
101
126
 
117
142
 
118
143
Screen::Screen(const mir::graphics::DisplayConfigurationOutput &screen)
119
144
    : QObject(nullptr)
 
145
    , m_refreshRate(-1.0)
 
146
    , m_scale(1.0)
 
147
    , m_formFactor(mir_form_factor_unknown)
120
148
    , m_renderTarget(nullptr)
121
149
    , m_displayGroup(nullptr)
122
150
    , m_orientationSensor(new QOrientationSensor(this))
123
151
    , m_screenWindow(nullptr)
124
152
    , m_unityScreen(nullptr)
125
153
{
126
 
    setMirDisplayConfiguration(screen);
 
154
    setMirDisplayConfiguration(screen, false);
127
155
 
128
156
    // Set the default orientation based on the initial screen dimmensions.
129
157
    m_nativeOrientation = (m_geometry.width() >= m_geometry.height())
178
206
    }
179
207
}
180
208
 
181
 
void Screen::setMirDisplayConfiguration(const mir::graphics::DisplayConfigurationOutput &screen)
 
209
void Screen::setMirDisplayConfiguration(const mir::graphics::DisplayConfigurationOutput &screen,
 
210
                                        bool notify)
182
211
{
183
212
    // Note: DisplayConfigurationOutput will be destroyed after this function returns
184
213
 
191
220
    m_physicalSize.setWidth(screen.physical_size_mm.width.as_float());
192
221
    m_physicalSize.setHeight(screen.physical_size_mm.height.as_float());
193
222
 
194
 
    // Pixel Format
 
223
    // Screen capabilities
 
224
    m_modes = screen.modes;
 
225
    m_currentModeIndex = screen.current_mode_index;
 
226
    m_preferredModeIndex = screen.preferred_mode_index;
 
227
    m_pixelFormats = screen.pixel_formats;
 
228
 
 
229
    // Current Pixel Format & depth
195
230
    m_format = qImageFormatFromMirPixelFormat(screen.current_format);
196
 
 
197
 
    // Pixel depth
198
231
    m_depth = 8 * MIR_BYTES_PER_PIXEL(screen.current_format);
199
232
 
200
233
    // Power mode
206
239
    m_geometry.setLeft(screen.top_left.x.as_int());
207
240
 
208
241
    // Mode = current resolution & refresh rate
209
 
    mir::graphics::DisplayConfigurationMode mode = screen.modes.at(screen.current_mode_index);
 
242
    mir::graphics::DisplayConfigurationMode mode = screen.modes.at(m_currentModeIndex);
210
243
    m_geometry.setWidth(mode.size.width.as_int());
211
244
    m_geometry.setHeight(mode.size.height.as_int());
212
245
 
214
247
 
215
248
    // Check for Screen geometry change
216
249
    if (m_geometry != oldGeometry) {
217
 
        QWindowSystemInterface::handleScreenGeometryChange(this->screen(), m_geometry, m_geometry);
 
250
        if (notify) {
 
251
            QWindowSystemInterface::handleScreenGeometryChange(this->screen(), m_geometry, m_geometry);
 
252
        }
218
253
        if (m_screenWindow) { // resize corresponding window immediately
219
254
            m_screenWindow->setGeometry(m_geometry);
220
255
        }
223
258
    // Refresh rate
224
259
    if (m_refreshRate != mode.vrefresh_hz) {
225
260
        m_refreshRate = mode.vrefresh_hz;
226
 
        QWindowSystemInterface::handleScreenRefreshRateChange(this->screen(), mode.vrefresh_hz);
 
261
        if (notify) {
 
262
            QWindowSystemInterface::handleScreenRefreshRateChange(this->screen(), mode.vrefresh_hz);
 
263
        }
 
264
    }
 
265
 
 
266
    // Scale, DPR & Form Factor
 
267
    // Update the scale & form factor native-interface properties for the windows affected
 
268
    // as there is no convenient way to emit signals for those custom properties on a QScreen
 
269
    m_devicePixelRatio = 1.0; //qCeil(m_scale); // FIXME: I need to announce this changing, probably by delete/recreate Screen
 
270
 
 
271
    auto w = window(); // usually there is no Window associated with this Screen at this time.
 
272
    auto nativeInterface = qGuiApp->platformNativeInterface();
 
273
    if (screen.form_factor != m_formFactor) {
 
274
        m_formFactor = screen.form_factor;
 
275
        if (w && notify) {
 
276
            Q_EMIT nativeInterface->windowPropertyChanged(w, QStringLiteral("formFactor"));
 
277
        }
 
278
    }
 
279
 
 
280
    if (!qFuzzyCompare(screen.scale, m_scale)) {
 
281
        m_scale = screen.scale;
 
282
        if (w && notify) {
 
283
            Q_EMIT nativeInterface->windowPropertyChanged(w, QStringLiteral("scale"));
 
284
        }
227
285
    }
228
286
}
229
287
 
290
348
    return const_cast<QPlatformCursor *>(platformCursor);
291
349
}
292
350
 
 
351
QString Screen::name() const
 
352
{
 
353
    return displayTypeToString(m_type);
 
354
}
 
355
 
293
356
ScreenWindow *Screen::window() const
294
357
{
295
358
    return m_screenWindow;
298
361
void Screen::setWindow(ScreenWindow *window)
299
362
{
300
363
    if (window && m_screenWindow) {
301
 
        qCDebug(QTMIR_SENSOR_MESSAGES) << "Screen::setWindow - overwriting existing ScreenWindow";
 
364
        qCDebug(QTMIR_SCREENS) << "Screen::setWindow - overwriting existing ScreenWindow";
302
365
    }
303
366
    m_screenWindow = window;
304
367
 
305
368
    if (m_screenWindow) {
 
369
        auto nativeInterface = qGuiApp->platformNativeInterface();
 
370
        Q_EMIT nativeInterface->windowPropertyChanged(m_screenWindow, QStringLiteral("formFactor"));
 
371
        Q_EMIT nativeInterface->windowPropertyChanged(m_screenWindow, QStringLiteral("scale"));
 
372
 
306
373
        if (m_screenWindow->geometry() != geometry()) {
307
374
            qCDebug(QTMIR_SCREENS) << "Screen::setWindow - new geometry for shell surface" << window->window() << geometry();
308
375
            m_screenWindow->setGeometry(geometry());
312
379
 
313
380
void Screen::setMirDisplayBuffer(mir::graphics::DisplayBuffer *buffer, mir::graphics::DisplaySyncGroup *group)
314
381
{
315
 
    qCDebug(QTMIR_SCREENS) << "Screen::setMirDisplayBuffer" << buffer << group;
 
382
    qCDebug(QTMIR_SCREENS) << "Screen::setMirDisplayBuffer" << this << as_render_target(buffer) << group;
316
383
    // This operation should only be performed while rendering is stopped
317
384
    m_renderTarget = as_render_target(buffer);
318
385
    m_displayGroup = group;