Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28dc4f49 authored by dantmnf's avatar dantmnf Committed by Scott Warner
Browse files

sm8150-common: Use average linear light for ALS correction

Change-Id: Ia784480462f5a236d0bd75861f1cf5fd170fe3b1
parent e4940223
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -54,28 +54,38 @@ void AlsCorrection::correct(float& light) {
    if (pid != 0) {
        kill(pid, SIGUSR1);
    }
    uint8_t r = property_get_int32("vendor.sensors.als_correction.r", 0);
    uint8_t g = property_get_int32("vendor.sensors.als_correction.g", 0);
    uint8_t b = property_get_int32("vendor.sensors.als_correction.b", 0);
    // TODO: HIDL service and pass float instead
    int r = property_get_int32("vendor.sensors.als_correction.r", 0);
    int g = property_get_int32("vendor.sensors.als_correction.g", 0);
    int b = property_get_int32("vendor.sensors.als_correction.b", 0);
    ALOGV("Screen Color Above Sensor: %d, %d, %d", r, g, b);
    ALOGV("Original reading: %f", light);
    int screen_brightness = get("/sys/class/backlight/panel0-backlight/brightness", 0);
    float correction = 0.0f;
    float correction = 0.0f, correction_scaled = 0.0f;
    if (red_max_lux > 0 && green_max_lux > 0 && blue_max_lux > 0 && white_max_lux > 0) {
        uint8_t rgb_min = std::min({r, g, b});
        correction += ((float) rgb_min) / 255.0f * ((float) white_max_lux);
        constexpr float rgb_scale = 0x7FFFFFFF;
        int rgb_min = std::min({r, g, b});
        r -= rgb_min;
        g -= rgb_min;
        b -= rgb_min;
        correction += ((float) r) / 255.0f * ((float) red_max_lux);
        correction += ((float) g) / 255.0f * ((float) green_max_lux);
        correction += ((float) b) / 255.0f * ((float) blue_max_lux);
        correction += ((float) rgb_min) / rgb_scale * ((float) white_max_lux);
        correction += ((float) r) / rgb_scale * ((float) red_max_lux);
        correction += ((float) g) / rgb_scale * ((float) green_max_lux);
        correction += ((float) b) / rgb_scale * ((float) blue_max_lux);
        correction = correction * (((float) screen_brightness) / ((float) max_brightness));
        correction += als_bias;
        correction_scaled = correction * (((float) white_max_lux) /
                                          (red_max_lux + green_max_lux + blue_max_lux));
    }
    // Do not apply correction if < 0, prevent unstable adaptive brightness
    if (light - correction >= 0) {
        // Apply correction if light - correction >= 0
        light -= correction;
    } else if (light - correction > -4) {
        // Return positive value if light - correction > -4
        light = correction - light;
    } else if (light - correction_scaled >= 0) {
        // Substract scaled correction if light - correction_scaled >= 0
        light -= correction_scaled;
    } else {
        // In low light conditions, sensor is just reporting bad values, using
        // computed correction instead allows to fix the issue
+24 −8
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ using android::ScreenshotClient;
using android::sp;
using android::SurfaceComposerClient;

constexpr int ALS_RADIUS = 64;
constexpr int SCREENSHOT_INTERVAL = 1;

void updateScreenBuffer() {
@@ -42,19 +43,34 @@ void updateScreenBuffer() {

    if (now.tv_sec - lastScreenUpdate >= SCREENSHOT_INTERVAL) {
        // Update Screenshot at most every second
        ScreenshotClient::capture(SurfaceComposerClient::getInternalDisplayToken(),
                                  android::ui::Dataspace::V0_SRGB,
                                  android::ui::PixelFormat::RGBA_8888,
                                  Rect(ALS_POS_X, ALS_POS_Y, ALS_POS_X + 10, ALS_POS_Y + 10),
                                  10, 10, true, android::ui::ROTATION_0, &outBuffer);
        ScreenshotClient::capture(
                SurfaceComposerClient::getInternalDisplayToken(),
                android::ui::Dataspace::DISPLAY_P3_LINEAR, android::ui::PixelFormat::RGBA_8888,
                Rect(ALS_POS_X - ALS_RADIUS, ALS_POS_Y - ALS_RADIUS, ALS_POS_X + ALS_RADIUS,
                     ALS_POS_Y + ALS_RADIUS),
                ALS_RADIUS * 2, ALS_RADIUS * 2, true, android::ui::ROTATION_0, &outBuffer);
        lastScreenUpdate = now.tv_sec;
    }

    uint8_t *out;
    auto resultWidth = outBuffer->getWidth();
    auto resultHeight = outBuffer->getHeight();
    auto stride = outBuffer->getStride();

    outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void **>(&out));
    SetProperty("vendor.sensors.als_correction.r", std::to_string(static_cast<uint8_t>(out[0])));
    SetProperty("vendor.sensors.als_correction.g", std::to_string(static_cast<uint8_t>(out[1])));
    SetProperty("vendor.sensors.als_correction.b", std::to_string(static_cast<uint8_t>(out[2])));
    // we can sum this directly on linear light
    uint32_t rsum = 0, gsum = 0, bsum = 0;
    for (int y = 0; y < resultHeight; y++) {
        for (int x = 0; x < resultWidth; x++) {
            rsum += out[y * (stride * 4) + x * 4];
            gsum += out[y * (stride * 4) + x * 4 + 1];
            bsum += out[y * (stride * 4) + x * 4 + 2];
        }
    }
    uint32_t max = 255 * resultWidth * resultHeight;
    SetProperty("vendor.sensors.als_correction.r", std::to_string(rsum * 0x7FFFFFFFuLL / max));
    SetProperty("vendor.sensors.als_correction.g", std::to_string(gsum * 0x7FFFFFFFuLL / max));
    SetProperty("vendor.sensors.als_correction.b", std::to_string(bsum * 0x7FFFFFFFuLL / max));
    outBuffer->unlock();
}