From e71a230213db70cd834565002ebda48853145146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 16 Nov 2015 09:01:48 +0100 Subject: [PATCH] [hwcomposer] Add support for backlight through light_device_t We use the hw module's backlight and set the color to either 0 or FF depending on whetehr we want to have the screen on or off. This turns the backlight off properly. It is bound to the toggleBlank functionality so that we always turn on/off the backlight depending on whether our compositor is on or off. In addition we listen to key release events on the power button to toggle the state. REVIEW: 126083 --- backends/hwcomposer/hwcomposer_backend.cpp | 44 ++++++++++++++++++++++ backends/hwcomposer/hwcomposer_backend.h | 4 ++ 2 files changed, 48 insertions(+) diff --git a/backends/hwcomposer/hwcomposer_backend.cpp b/backends/hwcomposer/hwcomposer_backend.cpp index c73a95af64..8cb972d62e 100644 --- a/backends/hwcomposer/hwcomposer_backend.cpp +++ b/backends/hwcomposer/hwcomposer_backend.cpp @@ -22,6 +22,7 @@ along with this program. If not, see . #include "logging.h" #include "screens_hwcomposer.h" #include "composite.h" +#include "input.h" #include "virtual_terminal.h" #include "wayland_server.h" // KWayland @@ -31,6 +32,7 @@ along with this program. If not, see . // hybris/android #include #include +#include // linux #include @@ -133,7 +135,18 @@ void HwcomposerBackend::init() }; m_device->registerProcs(m_device, procs); + initLights(); toggleBlankOutput(); + connect(input(), &InputRedirection::keyStateChanged, this, + [this] (quint32 key, InputRedirection::KeyboardKeyState state) { + if (state != InputRedirection::KeyboardKeyState::KeyboardKeyReleased) { + return; + } + if (key == KEY_POWER) { + toggleBlankOutput(); + } + } + ); // get display configuration auto output = createOutput(hwcDevice); @@ -155,12 +168,28 @@ void HwcomposerBackend::init() setReady(true); } +void HwcomposerBackend::initLights() +{ + hw_module_t *lightsModule = nullptr; + if (hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (const hw_module_t **)&lightsModule) != 0) { + qCWarning(KWIN_HWCOMPOSER) << "Failed to get lights module"; + return; + } + light_device_t *lightsDevice = nullptr; + if (lightsModule->methods->open(lightsModule, LIGHT_ID_BACKLIGHT, (hw_device_t **)&lightsDevice) != 0) { + qCWarning(KWIN_HWCOMPOSER) << "Failed to create lights device"; + return; + } + m_lights = lightsDevice; +} + void HwcomposerBackend::toggleBlankOutput() { if (!m_device) { return; } m_outputBlank = !m_outputBlank; + toggleScreenBrightness(); m_device->blank(m_device, 0, m_outputBlank ? 1 : 0); // only disable Vsycn, enable happens after next frame rendered if (m_outputBlank) { @@ -175,6 +204,21 @@ void HwcomposerBackend::toggleBlankOutput() } } +void HwcomposerBackend::toggleScreenBrightness() +{ + if (!m_lights) { + return; + } + const int brightness = m_outputBlank ? 0 : 0xFF; + struct light_state_t state; + state.flashMode = LIGHT_FLASH_NONE; + state.brightnessMode = BRIGHTNESS_MODE_USER; + + state.color = (int)((0xffU << 24) | (brightness << 16) | + (brightness << 8) | brightness); + m_lights->set_light(m_lights, &state); +} + void HwcomposerBackend::enableVSync(bool enable) { if (m_hasVsync == enable) { diff --git a/backends/hwcomposer/hwcomposer_backend.h b/backends/hwcomposer/hwcomposer_backend.h index 27efc38aab..3fa40c2ce3 100644 --- a/backends/hwcomposer/hwcomposer_backend.h +++ b/backends/hwcomposer/hwcomposer_backend.h @@ -32,6 +32,7 @@ along with this program. If not, see . 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; +struct light_device_t; class HWComposerNativeWindowBuffer; @@ -77,8 +78,11 @@ private Q_SLOTS: void toggleBlankOutput(); private: + void initLights(); + void toggleScreenBrightness(); 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;