fix: add backlight modulation support for hybrid graphics laptops

This commit is contained in:
daniel committed 2026-10-02 14:54:00 +02:00
1 parent 7979acc2eb
commit f9e21e0f13
6 files changed
+381 -12

No files matched your search

+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once
#define MONTAUK_BUILD_NUMBER 287
#define MONTAUK_BUILD_NUMBER 288
+21 -11
View File
@@ -12,6 +12,7 @@
#include <Graphics/Framebuffer.hpp>
#include <Drivers/Graphics/IntelGPU.hpp>
#include <ACPI/AcpiVideo.hpp>
#include <ACPI/WmiEcBacklight.hpp>
#include <Terminal/Terminal.hpp>
#include "Syscall.hpp"
@@ -129,29 +130,38 @@ namespace montauk::abi {
return GPU::Flip((int)index, (flags & 1) != 0, proc->pid);
}
// The firmware's ACPI brightness methods drive the built-in panel, so
// they stand in only when that panel is what is on screen (or no native
// driver knows what is): never for an external monitor without DDC/CI.
static bool AcpiBrightnessApplies() {
// Firmware brightness interfaces (EC via WMI, ACPI _BCM) drive the
// built-in panel, so they apply only while that panel is what is on
// screen (or no native driver knows what is): never for an external
// monitor, where they would silently dim a closed lid instead.
static bool PanelIsActiveOutput() {
if (!Drivers::Graphics::IntelGPU::IsInitialized()) return true;
uint8_t type = Drivers::Graphics::IntelGPU::ActiveConnectorType();
return type == DISPLAY_CONNECTOR_EDP || type == DISPLAY_CONNECTOR_LVDS;
}
// Order follows who actually owns the backlight. A firmware that names
// the EC as the source has taken it away from the GPU, whose PWM then
// still accepts writes that reach nothing; so the EC interface goes
// first, then the GPU's own controls, then ACPI _BCM as a last resort.
static int DisplayBrightness(int percent) {
bool panel = PanelIsActiveOutput();
if (panel) {
int rc = Hal::WmiEcBacklight::Brightness(percent);
if (rc != -1) return rc;
}
int rc = Drivers::Graphics::IntelGPU::Brightness(percent);
if (rc == -1 && AcpiBrightnessApplies())
rc = Hal::AcpiVideo::Brightness(percent);
if (rc == -1 && panel) rc = Hal::AcpiVideo::Brightness(percent);
return rc;
}
static int64_t Sys_DisplayInfo(DisplayInfo* out) {
if (!Drivers::Graphics::IntelGPU::GetDisplayInfo(out)) return NoDevice;
if (out->brightness < 0 && AcpiBrightnessApplies()) {
out->brightness = Hal::AcpiVideo::Brightness(-1);
if (out->brightness >= 0) out->capabilities |= DISPLAY_CAP_BRIGHTNESS;
else out->brightness = -1;
}
// The driver only knows its own backends; report what a set would use.
int level = DisplayBrightness(-1);
out->brightness = level >= 0 ? level : -1;
if (level >= 0) out->capabilities |= DISPLAY_CAP_BRIGHTNESS;
else out->capabilities &= ~DISPLAY_CAP_BRIGHTNESS;
return Success;
}