前言
需求:通过软件层修改,改变屏幕rgb偏差值完成一个色温调节模式的功能
系统版本:android11
修改思路
参考原生colormode切换流程,新加一个SurfaceFlinger的接口;
接口中遍历所有layer设置颜色transform矩阵,其中r、g、b的值对应的是三原色的偏转值,0就是不变,正负就是加强或减弱
修改完成后通过doTransaction接口刷新画面
mat4 rgbTransformMatrix = mat4(
vec4{1.0f + r , 0.0f , 0.0f , 0.0f},
vec4{0.0f , 1.0f + g , 0.0f , 0.0f},
vec4{0.0f , 0.0f , 1.0f + b , 0.0f},
vec4{0.0f , 0.0f , 0.0f , 1.0f}
);
java层的修改
frameworks/base/services/core/java/com/android/server/display/color/ColorDisplayService.java
settingprovider值
public static final String RGB_RED_ADJUSTMENT = "rgb_red_adjustment";
public static final String RGB_GREEN_ADJUSTMENT = "rgb_green_adjustment";
public static final String RGB_BLUE_ADJUSTMENT = "rgb_blue_adjustment";
在原有的注册监听的地方追加新的监听
private void setUp() {
......
cr.registerContentObserver(Global.getUriFor(RGB_RED_ADJUSTMENT),
false /* notifyForDescendants */, mContentObserver, mCurrentUser);
cr.registerContentObserver(Global.getUriFor(RGB_GREEN_ADJUSTMENT),
false /* notifyForDescendants */, mContentObserver, mCurrentUser);
cr.registerContentObserver(Global.getUriFor(RGB_BLUE_ADJUSTMENT),
false /* notifyForDescendants */, mContentObserver, mCurrentUser);
处理收到settingprovider变化的通知
private void setUp() {
......
@Override
public void onChange(boolean selfChange, Uri uri) {
......
case RGB_RED_ADJUSTMENT:
updateRgbMatrix();
break;
case RGB_GREEN_ADJUSTMENT:
updateRgbMatrix();
break;
case RGB_BLUE_ADJUSTMENT:
updateRgbMatrix();
break;
private void updateRgbMatrix() {
Slog.i(TAG, "updateRgbMatrix");
final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
final ContentResolver cr = getContext().getContentResolver();
String strR = Settings.Global.getString(cr, RGB_RED_ADJUSTMENT);
String strG = Settings.Global.getString(cr, RGB_GREEN_ADJUSTMENT);
String strB = Settings.Global.getString(cr, RGB_BLUE_ADJUSTMENT);
float r, g, b;
if (strR != null) {
r = Float.parseFloat(strR);
} else {
r = 0;
}
if (strG != null) {
g = Float.parseFloat(strG);
} else {
g = 0;
}
if (strB != null) {
b = Float.parseFloat(strB);
} else {
b = 0;
}
dtm.applyRgbMatrix(r, g, b);
}
frameworks/base/services/core/java/com/android/server/display/color/DisplayTransformManager.java
private static final int SURFACE_FLINGER_TRANSACTION_RGB_MATRIX = 1037;
public void applyRgbMatrix(float r, float g, float b) {
Slog.i(TAG, "applyRgbMatrix r: " + r + " g: " + g + " b: " + b);
final Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
data.writeInt(1);
data.writeFloat(r);
data.writeFloat(g);
data.writeFloat(b);
try {
sFlinger.transact(SURFACE_FLINGER_TRANSACTION_RGB_MATRIX, data, null, 0);
} catch (RemoteException ex) {
Slog.e(TAG, "Failed to set rgb transform", ex);
} finally {
data.recycle();
}
}
C++层修改
frameworks/base/services/surfaceflinger/SurfaceFlinger.h
新增接口
void updateRgbMatrixLocked(float r, float g, float b);
frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
......
if (code >= 1000 && code <= 1037) {
// if (code >= 1000 && code <= 1036) {
......
status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
......
case 1037: {
Mutex::Autolock _l(mStateLock);
// apply a RGB matrix
n = data.readInt32();
if (n) {
float r = data.readFloat();
float g = data.readFloat();
float b = data.readFloat();
updateRgbMatrixLocked(r, g, b);
}
return NO_ERROR;
}
......
void SurfaceFlinger::updateRgbMatrixLocked(float r, float g, float b) {
ALOGI("updateRgbMatrixLocked r: %f, g: %f, b: %f", r, g, b);
mat4 colorMatrix;
mat4 rgbTransformMatrix = mat4(
vec4{1.0f + r, 0.0f , 0.0f , 0.0f},
vec4{0.0f , 1.0f + g, 0.0f , 0.0f},
vec4{0.0f , 0.0f , 1.0f + b, 0.0f},
vec4{0.0f , 0.0f , 0.0f , 1.0f}
);
colorMatrix = mClientColorMatrix * rgbTransformMatrix;
mCurrentState.traverse([&](Layer* layer) {
layer->setColorTransform(rgbTransformMatrix);
// const nsecs_t expectedPresentTime = mExpectedPresentTime.load();
// layer->notifyAvailableFrames(expectedPresentTime);
layer->doTransaction(0);
});
// if (mCurrentState.colorMatrix != colorMatrix) {
// mCurrentState.colorMatrix = colorMatrix;
// mCurrentState.colorMatrixChanged = true;
// setTransactionFlags(eTransactionNeeded);
// }
// signalLayerUpdate();
// repaintEverything();
}
调试指令
adb shell settings put global rgb_red_adjustment 0.015
adb shell settings put global rgb_green_adjustment 0.015
adb shell settings put global rgb_blue_adjustment 0.015