Loading sensors/AlsCorrection.cpp +20 −10 Original line number Diff line number Diff line Loading @@ -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 Loading sensors/als_correction_service.cpp +24 −8 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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(); } Loading Loading
sensors/AlsCorrection.cpp +20 −10 Original line number Diff line number Diff line Loading @@ -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 Loading
sensors/als_correction_service.cpp +24 −8 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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(); } Loading