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

Commit c2f90780 authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Add automatic HDR transition animation" into main

parents d6fd96f0 15e666c8
Loading
Loading
Loading
Loading
+121 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.os.SystemClock;

import com.android.graphics.hwui.flags.Flags;

import java.util.function.Consumer;

/** @hide */
class HdrRenderState implements Consumer<Display> {
    // Targeting an animation from 1x to 5x over 400ms means we need to increase by 0.01/ms
    private static final float TRANSITION_PER_MS = 0.01f;

    private static final boolean FLAG_ANIMATE_ENABLED = Flags.animateHdrTransitions();

    private final ViewRootImpl mViewRoot;

    private boolean mIsListenerRegistered = false;
    private boolean mUpdateHdrSdrRatioInfo = false;
    private float mDesiredHdrSdrRatio = 1f;
    private float mTargetHdrSdrRatio = 1f;
    private float mRenderHdrSdrRatio = 1f;
    private float mPreviousRenderRatio = 1f;
    private long mLastUpdateMillis = -1;

    HdrRenderState(ViewRootImpl viewRoot) {
        mViewRoot = viewRoot;
    }

    @Override
    public void accept(Display display) {
        forceUpdateHdrSdrRatio();
        mViewRoot.invalidate();
    }

    boolean isHdrEnabled() {
        return mDesiredHdrSdrRatio >= 1.01f;
    }

    void stopListening() {
        if (mIsListenerRegistered) {
            mViewRoot.mDisplay.unregisterHdrSdrRatioChangedListener(this);
            mIsListenerRegistered = false;
        }
    }

    void startListening() {
        if (isHdrEnabled() && !mIsListenerRegistered && mViewRoot.mDisplay != null) {
            mViewRoot.mDisplay.registerHdrSdrRatioChangedListener(mViewRoot.mExecutor, this);
        }
    }

    /** @return true if something changed, else false */
    boolean updateForFrame(long frameTimeMillis) {
        boolean hasUpdate = mUpdateHdrSdrRatioInfo;
        mUpdateHdrSdrRatioInfo = false;
        mRenderHdrSdrRatio = mTargetHdrSdrRatio;
        long timeDelta = Math.max(Math.min(32, frameTimeMillis - mLastUpdateMillis), 8);
        final float maxStep = timeDelta * TRANSITION_PER_MS;
        mLastUpdateMillis = frameTimeMillis;
        if (hasUpdate && FLAG_ANIMATE_ENABLED) {
            if (mTargetHdrSdrRatio == 1.0f) {
                mPreviousRenderRatio = mTargetHdrSdrRatio;
            } else {
                float delta = mTargetHdrSdrRatio - mPreviousRenderRatio;
                if (delta > maxStep) {
                    mRenderHdrSdrRatio = mPreviousRenderRatio + maxStep;
                    mUpdateHdrSdrRatioInfo = true;
                    mViewRoot.invalidate();
                }
                mPreviousRenderRatio = mRenderHdrSdrRatio;
            }
        }
        return hasUpdate;
    }

    float getDesiredHdrSdrRatio() {
        return mDesiredHdrSdrRatio;
    }

    float getRenderHdrSdrRatio() {
        return mRenderHdrSdrRatio;
    }

    void forceUpdateHdrSdrRatio() {
        mTargetHdrSdrRatio = Math.min(mDesiredHdrSdrRatio, mViewRoot.mDisplay.getHdrSdrRatio());
        mUpdateHdrSdrRatioInfo = true;
    }

    void setDesiredHdrSdrRatio(float desiredRatio) {
        mLastUpdateMillis = SystemClock.uptimeMillis();
        // TODO: When decreasing the desired ratio we need to animate it downwards
        if (desiredRatio != mDesiredHdrSdrRatio) {
            mDesiredHdrSdrRatio = desiredRatio;
            forceUpdateHdrSdrRatio();
            mViewRoot.invalidate();

            if (isHdrEnabled()) {
                startListening();
            } else {
                stopListening();
            }
        }
    }
}
+13 −40
Original line number Diff line number Diff line
@@ -735,10 +735,7 @@ public final class ViewRootImpl implements ViewParent,

    private BLASTBufferQueue mBlastBufferQueue;

    private boolean mUpdateHdrSdrRatioInfo = false;
    private float mDesiredHdrSdrRatio = 1f;
    private float mRenderHdrSdrRatio = 1f;
    private Consumer<Display> mHdrSdrRatioChangedListener = null;
    private final HdrRenderState mHdrRenderState = new HdrRenderState(this);

    /**
     * Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to
@@ -1813,7 +1810,7 @@ public final class ViewRootImpl implements ViewParent,
                mAttachInfo.mThreadedRenderer = renderer;
                renderer.setSurfaceControl(mSurfaceControl, mBlastBufferQueue);
                updateColorModeIfNeeded(attrs.getColorMode(), attrs.getDesiredHdrHeadroom());
                updateRenderHdrSdrRatio();
                mHdrRenderState.forceUpdateHdrSdrRatio();
                updateForceDarkMode();
                mAttachInfo.mHardwareAccelerated = true;
                mAttachInfo.mHardwareAccelerationRequested = true;
@@ -2156,9 +2153,7 @@ public final class ViewRootImpl implements ViewParent,
    private void updateInternalDisplay(int displayId, Resources resources) {
        final Display preferredDisplay =
                ResourcesManager.getInstance().getAdjustedDisplay(displayId, resources);
        if (mHdrSdrRatioChangedListener != null && mDisplay != null) {
            mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
        }
        mHdrRenderState.stopListening();
        if (preferredDisplay == null) {
            // Fallback to use default display.
            Slog.w(TAG, "Cannot get desired display with Id: " + displayId);
@@ -2167,9 +2162,7 @@ public final class ViewRootImpl implements ViewParent,
        } else {
            mDisplay = preferredDisplay;
        }
        if (mHdrSdrRatioChangedListener != null && mDisplay != null) {
            mDisplay.registerHdrSdrRatioChangedListener(mExecutor, mHdrSdrRatioChangedListener);
        }
        mHdrRenderState.startListening();
        mContext.updateDisplay(mDisplay.getDisplayId());
    }

@@ -5154,11 +5147,12 @@ public final class ViewRootImpl implements ViewParent,

                useAsyncReport = true;

                if (mUpdateHdrSdrRatioInfo) {
                    mUpdateHdrSdrRatioInfo = false;
                if (mHdrRenderState.updateForFrame(mAttachInfo.mDrawingTime)) {
                    final float renderRatio = mHdrRenderState.getRenderHdrSdrRatio();
                    applyTransactionOnDraw(mTransaction.setExtendedRangeBrightness(
                            getSurfaceControl(), mRenderHdrSdrRatio, mDesiredHdrSdrRatio));
                    mAttachInfo.mThreadedRenderer.setTargetHdrSdrRatio(mRenderHdrSdrRatio);
                            getSurfaceControl(), renderRatio,
                            mHdrRenderState.getDesiredHdrSdrRatio()));
                    mAttachInfo.mThreadedRenderer.setTargetHdrSdrRatio(renderRatio);
                }

                if (activeSyncGroup != null) {
@@ -5769,11 +5763,6 @@ public final class ViewRootImpl implements ViewParent,
        }
    }

    private void updateRenderHdrSdrRatio() {
        mRenderHdrSdrRatio = Math.min(mDesiredHdrSdrRatio, mDisplay.getHdrSdrRatio());
        mUpdateHdrSdrRatioInfo = true;
    }

    private void updateColorModeIfNeeded(@ActivityInfo.ColorMode int colorMode,
            float desiredRatio) {
        if (mAttachInfo.mThreadedRenderer == null) {
@@ -5793,22 +5782,8 @@ public final class ViewRootImpl implements ViewParent,
        if (desiredRatio == 0 || desiredRatio > automaticRatio) {
            desiredRatio = automaticRatio;
        }
        if (desiredRatio != mDesiredHdrSdrRatio) {
            mDesiredHdrSdrRatio = desiredRatio;
            updateRenderHdrSdrRatio();
            invalidate();

            if (mDesiredHdrSdrRatio < 1.01f) {
                mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
                mHdrSdrRatioChangedListener = null;
            } else {
                mHdrSdrRatioChangedListener = display -> {
                    updateRenderHdrSdrRatio();
                    invalidate();
                };
                mDisplay.registerHdrSdrRatioChangedListener(mExecutor, mHdrSdrRatioChangedListener);
            }
        }
        mHdrRenderState.setDesiredHdrSdrRatio(desiredRatio);
    }

    @Override
@@ -6428,7 +6403,7 @@ public final class ViewRootImpl implements ViewParent,
    }

    final ViewRootHandler mHandler = new ViewRootHandler();
    private final Executor mExecutor = (Runnable r) -> {
    final Executor mExecutor = (Runnable r) -> {
        mHandler.post(r);
    };

@@ -8764,7 +8739,7 @@ public final class ViewRootImpl implements ViewParent,
            if (mAttachInfo.mThreadedRenderer != null) {
                mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl, mBlastBufferQueue);
            }
            updateRenderHdrSdrRatio();
            mHdrRenderState.forceUpdateHdrSdrRatio();
            if (mPreviousTransformHint != transformHint) {
                mPreviousTransformHint = transformHint;
                dispatchTransformHintChanged(transformHint);
@@ -9312,9 +9287,7 @@ public final class ViewRootImpl implements ViewParent,
    private void destroyHardwareRenderer() {
        ThreadedRenderer hardwareRenderer = mAttachInfo.mThreadedRenderer;

        if (mHdrSdrRatioChangedListener != null) {
            mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
        }
        mHdrRenderState.stopListening();

        if (hardwareRenderer != null) {
            if (mHardwareRendererObserver != null) {
+7 −0
Original line number Diff line number Diff line
@@ -48,3 +48,10 @@ flag {
  description: "Enable r_8, r_16_uint, rg_1616_uint, and rgba_10101010 in the SDK"
  bug: "292545615"
}

flag {
  name: "animate_hdr_transitions"
  namespace: "core_graphics"
  description: "Automatically animate all changes in HDR headroom"
  bug: "314810174"
}