Android在SurfaceFlinger中修改全局RGB数值(色温调节)

Android在SurfaceFlinger中修改全局RGB数值

前言

需求:通过软件层修改,改变屏幕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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值