[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
icc-effect-5.14.5
Martin Gräßlin 2015-11-16 09:01:48 +01:00
parent 8d00355448
commit e71a230213
2 changed files with 48 additions and 0 deletions

View File

@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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 <http://www.gnu.org/licenses/>.
// hybris/android
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <hardware/lights.h>
// linux
#include <linux/input.h>
@ -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) {

View File

@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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;