Loading core/java/android/view/HdrRenderState.java 0 → 100644 +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(); } } } } core/java/android/view/ViewRootImpl.java +13 −40 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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()); } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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 Loading Loading @@ -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); }; Loading Loading @@ -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); Loading Loading @@ -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) { Loading libs/hwui/aconfig/hwui_flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -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" } Loading
core/java/android/view/HdrRenderState.java 0 → 100644 +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(); } } } }
core/java/android/view/ViewRootImpl.java +13 −40 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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()); } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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 Loading Loading @@ -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); }; Loading Loading @@ -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); Loading Loading @@ -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) { Loading
libs/hwui/aconfig/hwui_flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -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" }