diff --git a/plugins/platforms/hwcomposer/hwcomposer_backend.cpp b/plugins/platforms/hwcomposer/hwcomposer_backend.cpp
index 6cc024fa95..651d1e5756 100644
--- a/plugins/platforms/hwcomposer/hwcomposer_backend.cpp
+++ b/plugins/platforms/hwcomposer/hwcomposer_backend.cpp
@@ -26,8 +26,7 @@ along with this program. If not, see .
#include "main.h"
#include "wayland_server.h"
// KWayland
-#include
-#include
+#include
// Qt
#include
#include
@@ -39,6 +38,8 @@ along with this program. If not, see .
// based on test_hwcomposer.c from libhybris project (Apache 2 licensed)
+using namespace KWayland::Server;
+
namespace KWin
{
@@ -157,50 +158,6 @@ HwcomposerBackend::~HwcomposerBackend()
if (!m_outputBlank) {
toggleBlankOutput();
}
- if (m_device) {
- hwc_close_1(m_device);
- }
-}
-
-KWayland::Server::OutputInterface* HwcomposerBackend::createOutput(hwc_composer_device_1_t *device)
-{
- uint32_t configs[5];
- size_t numConfigs = 5;
- if (device->getDisplayConfigs(device, 0, configs, &numConfigs) != 0) {
- qCWarning(KWIN_HWCOMPOSER) << "Failed to get hwcomposer display configurations";
- return nullptr;
- }
-
- int32_t attr_values[5];
- uint32_t attributes[] = {
- HWC_DISPLAY_WIDTH,
- HWC_DISPLAY_HEIGHT,
- HWC_DISPLAY_DPI_X,
- HWC_DISPLAY_DPI_Y,
- HWC_DISPLAY_VSYNC_PERIOD ,
- HWC_DISPLAY_NO_ATTRIBUTE
- };
- device->getDisplayAttributes(device, 0, configs[0], attributes, attr_values);
- QSize pixel(attr_values[0], attr_values[1]);
- if (pixel.isEmpty()) {
- return nullptr;
- }
-
- using namespace KWayland::Server;
- OutputInterface *o = waylandServer()->display()->createOutput(waylandServer()->display());
- o->addMode(pixel, OutputInterface::ModeFlag::Current | OutputInterface::ModeFlag::Preferred, (attr_values[4] == 0) ? 60000 : 10E11/attr_values[4]);
-
- if (attr_values[2] != 0 && attr_values[3] != 0) {
- static const qreal factor = 25.4;
- m_physicalSize = QSizeF(qreal(pixel.width() * 1000) / qreal(attr_values[2]) * factor,
- qreal(pixel.height() * 1000) / qreal(attr_values[3]) * factor);
- o->setPhysicalSize(m_physicalSize.toSize());
- } else {
- // couldn't read physical size, assume 96 dpi
- o->setPhysicalSize(pixel / 3.8);
- }
- o->create();
- return o;
}
void HwcomposerBackend::init()
@@ -249,31 +206,35 @@ void HwcomposerBackend::init()
};
m_device->registerProcs(m_device, procs);
+ //move to HwcomposerOutput + signal
+
initLights();
toggleBlankOutput();
m_filter.reset(new BacklightInputEventFilter(this));
input()->prependInputEventFilter(m_filter.data());
// get display configuration
- auto output = createOutput(hwcDevice);
- if (!output) {
+ m_output.reset(new HwcomposerOutput(hwcDevice));
+ if (!m_output->isValid()) {
emit initFailed();
return;
}
- m_displaySize = output->pixelSize();
- m_refreshRate = output->refreshRate();
- if (m_refreshRate != 0) {
- m_vsyncInterval = 1000000/m_refreshRate;
+
+ if (m_output->refreshRate() != 0) {
+ m_vsyncInterval = 1000000/m_output->refreshRate();
}
+
if (m_lights) {
using namespace KWayland::Server;
- output->setDpmsSupported(true);
- auto updateDpms = [this, output] {
- output->setDpmsMode(m_outputBlank ? OutputInterface::DpmsMode::Off : OutputInterface::DpmsMode::On);
+
+ auto updateDpms = [this] {
+ if (!m_output || !m_output->waylandOutput()) {
+ m_output->waylandOutput()->setDpmsMode(m_outputBlank ? OutputInterface::DpmsMode::Off : OutputInterface::DpmsMode::On);
+ }
};
- updateDpms();
connect(this, &HwcomposerBackend::outputBlankChanged, this, updateDpms);
- connect(output, &OutputInterface::dpmsModeRequested, this,
+
+ connect(m_output.data(), &HwcomposerOutput::dpmsModeRequested, this,
[this] (KWayland::Server::OutputInterface::DpmsMode mode) {
if (mode == OutputInterface::DpmsMode::On) {
if (m_outputBlank) {
@@ -287,13 +248,19 @@ void HwcomposerBackend::init()
}
);
}
- qCDebug(KWIN_HWCOMPOSER) << "Display size:" << m_displaySize;
- qCDebug(KWIN_HWCOMPOSER) << "Refresh rate:" << m_refreshRate;
emit screensQueried();
setReady(true);
}
+QSize HwcomposerBackend::screenSize() const
+{
+ if (m_output) {
+ return m_output->pixelSize();
+ }
+ return QSize();
+}
+
void HwcomposerBackend::initLights()
{
hw_module_t *lightsModule = nullptr;
@@ -372,6 +339,20 @@ Screens *HwcomposerBackend::createScreens(QObject *parent)
return new HwcomposerScreens(this, parent);
}
+Outputs HwcomposerBackend::outputs() const
+{
+ if (!m_output.isNull()) {
+ return QVector({m_output.data()});
+ }
+ return {};
+}
+
+Outputs HwcomposerBackend::enabledOutputs() const
+{
+ return outputs();
+}
+
+
OpenGLBackend *HwcomposerBackend::createOpenGLBackend()
{
return new EglHwcomposerBackend(this);
@@ -482,4 +463,74 @@ void HwcomposerWindow::present(HWComposerNativeWindowBuffer *buffer)
m_list[0]->flags = 0;
}
+HwcomposerOutput::HwcomposerOutput(hwc_composer_device_1_t *device)
+ : AbstractOutput()
+ , m_device(device)
+{
+ uint32_t configs[5];
+ size_t numConfigs = 5;
+ if (device->getDisplayConfigs(device, 0, configs, &numConfigs) != 0) {
+ qCWarning(KWIN_HWCOMPOSER) << "Failed to get hwcomposer display configurations";
+ return;
+ }
+
+ int32_t attr_values[5];
+ uint32_t attributes[] = {
+ HWC_DISPLAY_WIDTH,
+ HWC_DISPLAY_HEIGHT,
+ HWC_DISPLAY_DPI_X,
+ HWC_DISPLAY_DPI_Y,
+ HWC_DISPLAY_VSYNC_PERIOD ,
+ HWC_DISPLAY_NO_ATTRIBUTE
+ };
+ device->getDisplayAttributes(device, 0, configs[0], attributes, attr_values);
+ QSize pixel(attr_values[0], attr_values[1]);
+ if (pixel.isEmpty()) {
+ return;
+ }
+ m_pixelSize = pixel;
+
+ if (attr_values[2] != 0 && attr_values[3] != 0) {
+ static const qreal factor = 25.4;
+ auto physicalSize = QSizeF(qreal(pixel.width() * 1000) / qreal(attr_values[2]) * factor,
+ qreal(pixel.height() * 1000) / qreal(attr_values[3]) * factor);
+ setRawPhysicalSize(physicalSize.toSize());
+ } else {
+ // couldn't read physical size, assume 96 dpi
+ setRawPhysicalSize(pixel / 3.8);
+ }
+
+ OutputDeviceInterface::Mode mode;
+ mode.id = 0;
+ mode.size = pixel;
+ mode.flags = OutputDeviceInterface::ModeFlag::Current | OutputDeviceInterface::ModeFlag::Preferred;
+ mode.refreshRate = (attr_values[4] == 0) ? 60000 : 10E11/attr_values[4];
+
+ initWaylandOutputDevice(QString(), QString(), QByteArray(), {mode});
+ setInternal(true);
+ setEnabled(true);
+ setDpmsSupported(true);
+ setWaylandMode(m_pixelSize, mode.refreshRate);
+}
+
+HwcomposerOutput::~HwcomposerOutput()
+{
+ hwc_close_1(m_device);
+}
+
+QSize HwcomposerOutput::pixelSize() const
+{
+ return m_pixelSize;
+}
+
+bool HwcomposerOutput::isValid() const
+{
+ return m_pixelSize.isValid();
+}
+
+void HwcomposerOutput::updateDpms(KWayland::Server::OutputInterface::DpmsMode mode)
+{
+ emit dpmsModeRequested(mode);
+}
+
}
diff --git a/plugins/platforms/hwcomposer/hwcomposer_backend.h b/plugins/platforms/hwcomposer/hwcomposer_backend.h
index 29ae5a5f8e..32d3dd7fc9 100644
--- a/plugins/platforms/hwcomposer/hwcomposer_backend.h
+++ b/plugins/platforms/hwcomposer/hwcomposer_backend.h
@@ -20,6 +20,7 @@ along with this program. If not, see .
#ifndef KWIN_HWCOMPOSER_BACKEND_H
#define KWIN_HWCOMPOSER_BACKEND_H
#include "platform.h"
+#include "abstract_output.h"
#include "input.h"
#include
@@ -33,8 +34,6 @@ along with this program. If not, see .
// needed as hwcomposer_window.h includes EGL which on non-arm includes Xlib
#include
-#include
-
typedef struct hwc_display_contents_1 hwc_display_contents_1_t;
typedef struct hwc_layer_1 hwc_layer_1_t;
typedef struct hwc_composer_device_1 hwc_composer_device_1_t;
@@ -48,6 +47,23 @@ namespace KWin
class HwcomposerWindow;
class BacklightInputEventFilter;
+class HwcomposerOutput : public AbstractOutput
+{
+ Q_OBJECT
+public:
+ HwcomposerOutput(hwc_composer_device_1_t *device);
+ ~HwcomposerOutput() override;
+ bool isValid() const;
+
+ QSize pixelSize() const override;
+ void updateDpms(KWayland::Server::OutputInterface::DpmsMode mode) override;
+Q_SIGNALS:
+ void dpmsModeRequested(KWayland::Server::OutputInterface::DpmsMode mode);
+private:
+ QSize m_pixelSize;
+ hwc_composer_device_1_t *m_device;
+};
+
class HwcomposerBackend : public Platform
{
Q_OBJECT
@@ -61,22 +77,19 @@ public:
Screens *createScreens(QObject *parent = nullptr) override;
OpenGLBackend *createOpenGLBackend() override;
- QSize screenSize() const override {
- return m_displaySize;
+ Outputs outputs() const override;
+ Outputs enabledOutputs() const override;
+
+ QSize size() const {
+ return screenSize();
}
+ QSize screenSize() const override;
HwcomposerWindow *createSurface();
- QSize size() const {
- return m_displaySize;
- }
-
hwc_composer_device_1_t *device() const {
return m_device;
}
- int refreshRate() const {
- return m_refreshRate;
- }
void enableVSync(bool enable);
void waitVSync();
void wakeVSync();
@@ -88,9 +101,6 @@ public:
QVector supportedCompositors() const override {
return QVector{OpenGLCompositing};
}
- QSizeF physicalSize() const {
- return m_physicalSize;
- }
Q_SIGNALS:
void outputBlankChanged();
@@ -104,12 +114,9 @@ private Q_SLOTS:
private:
void initLights();
void toggleScreenBrightness();
- KWayland::Server::OutputInterface* createOutput(hwc_composer_device_1_t *device);
- QSize m_displaySize;
hwc_composer_device_1_t *m_device = nullptr;
light_device_t *m_lights = nullptr;
bool m_outputBlank = true;
- int m_refreshRate = 60000;
int m_vsyncInterval = 16;
uint32_t m_hwcVersion;
int m_oldScreenBrightness = 0x7f;
@@ -117,7 +124,7 @@ private:
QMutex m_vsyncMutex;
QWaitCondition m_vsyncWaitCondition;
QScopedPointer m_filter;
- QSizeF m_physicalSize;
+ QScopedPointer m_output;
};
class HwcomposerWindow : public HWComposerNativeWindow
diff --git a/plugins/platforms/hwcomposer/screens_hwcomposer.cpp b/plugins/platforms/hwcomposer/screens_hwcomposer.cpp
index be14e7d31c..f8e6147fcf 100644
--- a/plugins/platforms/hwcomposer/screens_hwcomposer.cpp
+++ b/plugins/platforms/hwcomposer/screens_hwcomposer.cpp
@@ -24,26 +24,11 @@ namespace KWin
{
HwcomposerScreens::HwcomposerScreens(HwcomposerBackend *backend, QObject *parent)
- : BasicScreens(backend, parent)
+ : OutputScreens(backend, parent)
, m_backend(backend)
{
-}
-
-HwcomposerScreens::~HwcomposerScreens() = default;
-
-float HwcomposerScreens::refreshRate(int screen) const
-{
- Q_UNUSED(screen)
- return m_backend->refreshRate() / 1000.0f;
-}
-
-QSizeF HwcomposerScreens::physicalSize(int screen) const
-{
- const QSizeF size = m_backend->physicalSize();
- if (size.isValid()) {
- return size;
- }
- return Screens::physicalSize(screen);
+ connect(m_backend, &HwcomposerBackend::screensQueried, this, &OutputScreens::updateCount);
+ connect(m_backend, &HwcomposerBackend::screensQueried, this, &OutputScreens::changed);
}
}
diff --git a/plugins/platforms/hwcomposer/screens_hwcomposer.h b/plugins/platforms/hwcomposer/screens_hwcomposer.h
index 384236d9ad..a40dc83c7b 100644
--- a/plugins/platforms/hwcomposer/screens_hwcomposer.h
+++ b/plugins/platforms/hwcomposer/screens_hwcomposer.h
@@ -19,20 +19,18 @@ along with this program. If not, see .
*********************************************************************/
#ifndef KWIN_SCREENS_HWCOMPOSER_H
#define KWIN_SCREENS_HWCOMPOSER_H
-#include "screens.h"
+#include "outputscreens.h"
namespace KWin
{
class HwcomposerBackend;
-class HwcomposerScreens : public BasicScreens
+class HwcomposerScreens : public OutputScreens
{
Q_OBJECT
public:
HwcomposerScreens(HwcomposerBackend *backend, QObject *parent = nullptr);
- virtual ~HwcomposerScreens();
- float refreshRate(int screen) const override;
- QSizeF physicalSize(int screen) const override;
+ virtual ~HwcomposerScreens() = default;
private:
HwcomposerBackend *m_backend;