1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.display.config; 18 19 import android.annotation.Nullable; 20 import android.util.Slog; 21 import android.util.Spline; 22 23 import com.android.internal.annotations.VisibleForTesting; 24 25 import java.util.Arrays; 26 import java.util.List; 27 28 /** 29 * Brightness config for even dimmer 30 */ 31 public class EvenDimmerBrightnessData { 32 private static final String TAG = "EvenDimmerBrightnessData"; 33 34 /** 35 * Brightness value at which even dimmer methods are used. 36 */ 37 public final float mTransitionPoint; 38 39 /** 40 * Nits array, maps to mBacklight 41 */ 42 public final float[] mNits; 43 44 /** 45 * Backlight array, maps to mBrightness and mNits 46 */ 47 public final float[] mBacklight; 48 49 /** 50 * Brightness array, maps to mBacklight 51 */ 52 public final float[] mBrightness; 53 /** 54 * Spline, mapping between backlight and nits 55 */ 56 public final Spline mBacklightToNits; 57 /** 58 * Spline, mapping between nits and backlight 59 */ 60 public final Spline mNitsToBacklight; 61 /** 62 * Spline, mapping between brightness and backlight 63 */ 64 public final Spline mBrightnessToBacklight; 65 /** 66 * Spline, mapping between backlight and brightness 67 */ 68 public final Spline mBacklightToBrightness; 69 70 /** 71 * Spline, mapping the minimum nits for each lux condition. 72 */ 73 public final Spline mMinLuxToNits; 74 75 @VisibleForTesting EvenDimmerBrightnessData(float transitionPoint, float[] nits, float[] backlight, float[] brightness, Spline backlightToNits, Spline nitsToBacklight, Spline brightnessToBacklight, Spline backlightToBrightness, Spline minLuxToNits)76 public EvenDimmerBrightnessData(float transitionPoint, float[] nits, 77 float[] backlight, float[] brightness, Spline backlightToNits, 78 Spline nitsToBacklight, Spline brightnessToBacklight, Spline backlightToBrightness, 79 Spline minLuxToNits) { 80 mTransitionPoint = transitionPoint; 81 mNits = nits; 82 mBacklight = backlight; 83 mBrightness = brightness; 84 mBacklightToNits = backlightToNits; 85 mNitsToBacklight = nitsToBacklight; 86 mBrightnessToBacklight = brightnessToBacklight; 87 mBacklightToBrightness = backlightToBrightness; 88 mMinLuxToNits = minLuxToNits; 89 } 90 91 @Override toString()92 public String toString() { 93 return "EvenDimmerBrightnessData {" 94 + "mTransitionPoint: " + mTransitionPoint 95 + ", mNits: " + Arrays.toString(mNits) 96 + ", mBacklight: " + Arrays.toString(mBacklight) 97 + ", mBrightness: " + Arrays.toString(mBrightness) 98 + ", mBacklightToNits: " + mBacklightToNits 99 + ", mNitsToBacklight: " + mNitsToBacklight 100 + ", mBrightnessToBacklight: " + mBrightnessToBacklight 101 + ", mBacklightToBrightness: " + mBacklightToBrightness 102 + ", mMinLuxToNits: " + mMinLuxToNits 103 + "} "; 104 } 105 106 /** 107 * Loads EvenDimmerBrightnessData from DisplayConfiguration 108 */ 109 @Nullable loadConfig(DisplayConfiguration config)110 public static EvenDimmerBrightnessData loadConfig(DisplayConfiguration config) { 111 final EvenDimmerMode lbm = config.getEvenDimmer(); 112 if (lbm == null) { 113 return null; 114 } 115 116 boolean lbmIsEnabled = lbm.getEnabled(); 117 if (!lbmIsEnabled) { 118 return null; 119 } 120 121 ComprehensiveBrightnessMap map = lbm.getBrightnessMapping(); 122 if (map == null) { 123 return null; 124 } 125 String interpolation = map.getInterpolation(); 126 127 List<BrightnessPoint> brightnessPoints = map.getBrightnessPoint(); 128 if (brightnessPoints.isEmpty()) { 129 return null; 130 } 131 132 float[] nits = new float[brightnessPoints.size()]; 133 float[] backlight = new float[brightnessPoints.size()]; 134 float[] brightness = new float[brightnessPoints.size()]; 135 136 for (int i = 0; i < brightnessPoints.size(); i++) { 137 BrightnessPoint val = brightnessPoints.get(i); 138 nits[i] = val.getNits().floatValue(); 139 backlight[i] = val.getBacklight().floatValue(); 140 brightness[i] = val.getBrightness().floatValue(); 141 } 142 143 float transitionPoint = lbm.getTransitionPoint().floatValue(); 144 final NitsMap minimumNitsMap = lbm.getLuxToMinimumNitsMap(); 145 if (minimumNitsMap == null) { 146 Slog.e(TAG, "Invalid min lux to nits mapping"); 147 return null; 148 } 149 final List<Point> points = minimumNitsMap.getPoint(); 150 final int size = points.size(); 151 152 float[] minLux = new float[size]; 153 float[] minNits = new float[size]; 154 155 int i = 0; 156 for (Point point : points) { 157 minLux[i] = point.getValue().floatValue(); 158 minNits[i] = point.getNits().floatValue(); 159 if (i > 0) { 160 if (minLux[i] < minLux[i - 1]) { 161 Slog.e(TAG, "minLuxToNitsSpline must be non-decreasing, ignoring rest " 162 + " of configuration. Value: " + minLux[i] + " < " + minLux[i - 1]); 163 } 164 if (minNits[i] < minNits[i - 1]) { 165 Slog.e(TAG, "minLuxToNitsSpline must be non-decreasing, ignoring rest " 166 + " of configuration. Nits: " + minNits[i] + " < " + minNits[i - 1]); 167 } 168 } 169 ++i; 170 } 171 172 // Explicitly choose linear interpolation. 173 if ("linear".equals(interpolation)) { 174 return new EvenDimmerBrightnessData(transitionPoint, nits, backlight, brightness, 175 new Spline.LinearSpline(backlight, nits), 176 new Spline.LinearSpline(nits, backlight), 177 new Spline.LinearSpline(brightness, backlight), 178 new Spline.LinearSpline(backlight, brightness), 179 new Spline.LinearSpline(minLux, minNits) 180 ); 181 } 182 183 return new EvenDimmerBrightnessData(transitionPoint, nits, backlight, brightness, 184 Spline.createSpline(backlight, nits), 185 Spline.createSpline(nits, backlight), 186 Spline.createSpline(brightness, backlight), 187 Spline.createSpline(backlight, brightness), 188 Spline.createSpline(minLux, minNits) 189 ); 190 } 191 } 192