Wire up colorMode="hdr" on VRI

Test: silkfx
Bug: 266628247
Change-Id: I6633436f38d83a0fc5bfa59a29e684a9f1712843
This commit is contained in:
John Reck
2023-02-01 20:10:12 -05:00
parent d0dc3211f0
commit 01472127c0
4 changed files with 79 additions and 89 deletions

View File

@@ -350,7 +350,14 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
* @see android.R.attr#colorMode
*/
public static final int COLOR_MODE_HDR = 2;
// 3 Corresponds to android::uirenderer::ColorMode::Hdr10.
/**
* Comparison point against COLOR_MODE_HDR that uses 1010102
* Only for internal test usages
* @hide
*/
public static final int COLOR_MODE_HDR10 = 3;
/**
* Value of {@link #colorMode} indicating that the activity should use an
* 8 bit alpha buffer if the presentation display supports it.

View File

@@ -683,9 +683,10 @@ public final class ViewRootImpl implements ViewParent,
private BLASTBufferQueue mBlastBufferQueue;
private boolean mUpdateSdrHdrRatioInfo = false;
private float mDesiredSdrHdrRatio = 1f;
private float mRenderSdrHdrRatio = 1f;
private boolean mUpdateHdrSdrRatioInfo = false;
private float mDesiredHdrSdrRatio = 1f;
private float mRenderHdrSdrRatio = 1f;
private Consumer<Display> mHdrSdrRatioChangedListener = null;
/**
* Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to
@@ -1947,6 +1948,9 @@ 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);
}
if (preferredDisplay == null) {
// Fallback to use default display.
Slog.w(TAG, "Cannot get desired display with Id: " + displayId);
@@ -1955,6 +1959,9 @@ public final class ViewRootImpl implements ViewParent,
} else {
mDisplay = preferredDisplay;
}
if (mHdrSdrRatioChangedListener != null && mDisplay != null) {
mDisplay.registerHdrSdrRatioChangedListener(mExecutor, mHdrSdrRatioChangedListener);
}
mContext.updateDisplay(mDisplay.getDisplayId());
}
@@ -4838,11 +4845,11 @@ public final class ViewRootImpl implements ViewParent,
useAsyncReport = true;
if (mUpdateSdrHdrRatioInfo) {
mUpdateSdrHdrRatioInfo = false;
if (mUpdateHdrSdrRatioInfo) {
mUpdateHdrSdrRatioInfo = false;
applyTransactionOnDraw(mTransaction.setExtendedRangeBrightness(
getSurfaceControl(), mRenderSdrHdrRatio, mDesiredSdrHdrRatio));
mAttachInfo.mThreadedRenderer.setTargetSdrHdrRatio(mRenderSdrHdrRatio);
getSurfaceControl(), mRenderHdrSdrRatio, mDesiredHdrSdrRatio));
mAttachInfo.mThreadedRenderer.setTargetHdrSdrRatio(mRenderHdrSdrRatio);
}
if (forceDraw) {
@@ -5372,6 +5379,10 @@ public final class ViewRootImpl implements ViewParent,
if (mAttachInfo.mThreadedRenderer == null) {
return;
}
if ((colorMode == ActivityInfo.COLOR_MODE_HDR || colorMode == ActivityInfo.COLOR_MODE_HDR10)
&& !mDisplay.isHdrSdrRatioAvailable()) {
colorMode = ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
}
// TODO: Centralize this sanitization? Why do we let setting bad modes?
// Alternatively, can we just let HWUI figure it out? Do we need to care here?
if (colorMode != ActivityInfo.COLOR_MODE_A8
@@ -5379,17 +5390,28 @@ public final class ViewRootImpl implements ViewParent,
colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
}
float desiredRatio = mAttachInfo.mThreadedRenderer.setColorMode(colorMode);
if (desiredRatio != mDesiredSdrHdrRatio) {
mDesiredSdrHdrRatio = desiredRatio;
mUpdateSdrHdrRatioInfo = true;
if (desiredRatio != mDesiredHdrSdrRatio) {
mDesiredHdrSdrRatio = desiredRatio;
mRenderHdrSdrRatio = mDisplay.getHdrSdrRatio();
mUpdateHdrSdrRatioInfo = true;
if (mDesiredHdrSdrRatio < 1.01f) {
mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
mHdrSdrRatioChangedListener = null;
} else {
mHdrSdrRatioChangedListener = display -> {
setTargetHdrSdrRatio(display.getHdrSdrRatio());
};
mDisplay.registerHdrSdrRatioChangedListener(mExecutor, mHdrSdrRatioChangedListener);
}
}
}
/** happylint */
public void setTargetSdrHdrRatio(float ratio) {
if (mRenderSdrHdrRatio != ratio) {
mRenderSdrHdrRatio = ratio;
mUpdateSdrHdrRatioInfo = true;
public void setTargetHdrSdrRatio(float ratio) {
if (mRenderHdrSdrRatio != ratio) {
mRenderHdrSdrRatio = ratio;
mUpdateHdrSdrRatioInfo = true;
invalidate();
}
}
@@ -5965,6 +5987,9 @@ public final class ViewRootImpl implements ViewParent,
}
final ViewRootHandler mHandler = new ViewRootHandler();
private final Executor mExecutor = (Runnable r) -> {
mHandler.post(r);
};
/**
* Something in the current window tells us we need to change the touch mode. For
@@ -8950,6 +8975,10 @@ public final class ViewRootImpl implements ViewParent,
private void destroyHardwareRenderer() {
ThreadedRenderer hardwareRenderer = mAttachInfo.mThreadedRenderer;
if (mHdrSdrRatioChangedListener != null) {
mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
}
if (hardwareRenderer != null) {
if (mHardwareRendererObserver != null) {
hardwareRenderer.removeObserver(mHardwareRendererObserver);

View File

@@ -667,7 +667,7 @@ public class HardwareRenderer {
}
/** @hide */
public void setTargetSdrHdrRatio(float ratio) {
public void setTargetHdrSdrRatio(float ratio) {
if (ratio < 1.f || !Float.isFinite(ratio)) ratio = 1.f;
nSetTargetSdrHdrRatio(mNativeProxy, ratio);
}

View File

@@ -18,10 +18,10 @@ package com.android.test.silkfx.common
import android.content.Context
import android.content.pm.ActivityInfo
import android.hardware.display.DisplayManager
import android.util.AttributeSet
import android.util.Log
import android.view.Display
import android.view.View
import android.view.Window
import android.widget.Button
import android.widget.LinearLayout
@@ -31,22 +31,11 @@ import com.android.test.silkfx.app.WindowObserver
import java.util.function.Consumer
class ColorModeControls : LinearLayout, WindowObserver {
private val COLOR_MODE_HDR10 = 3
private val SDR_WHITE_POINTS = floatArrayOf(200f, 250f, 300f, 350f, 400f, 100f, 150f)
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
displayManager = context.getSystemService(DisplayManager::class.java)!!
displayId = context.getDisplayId()
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
private var window: Window? = null
private var currentModeDisplay: TextView? = null
private val displayManager: DisplayManager
private var targetSdrWhitePointIndex = 0
private var displayId: Int
private val whitePoint get() = SDR_WHITE_POINTS[targetSdrWhitePointIndex]
override fun onFinishInflate() {
super.onFinishInflate()
@@ -65,88 +54,53 @@ class ColorModeControls : LinearLayout, WindowObserver {
setColorMode(ActivityInfo.COLOR_MODE_HDR)
}
findViewById<Button>(R.id.mode_hdr10)!!.setOnClickListener {
setColorMode(COLOR_MODE_HDR10)
setColorMode(ActivityInfo.COLOR_MODE_HDR10)
}
}
private val hdrsdrListener = Consumer<Display> { display ->
private val hdrSdrListener = Consumer<Display> { display ->
Log.d("SilkFX", "HDR/SDR changed ${display.hdrSdrRatio}")
}
private val displayChangedListener = object : DisplayManager.DisplayListener {
override fun onDisplayAdded(displayId: Int) {
Log.d("SilkFX", "onDisplayAdded")
}
override fun onDisplayRemoved(displayId: Int) {
Log.d("SilkFX", "onDisplayRemoved")
}
override fun onDisplayChanged(displayId: Int) {
Log.d("SilkFX", "onDisplayChanged")
post {
updateModeInfoDisplay()
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
Log.d("SilkFX", "is hdr/sdr available: ${display.isHdrSdrRatioAvailable}; " +
"current ration = ${display.hdrSdrRatio}")
display.registerHdrSdrRatioChangedListener({ it.run() }, hdrsdrListener)
displayManager.registerDisplayListener(displayChangedListener, handler)
val hdrVis = if (display.isHdrSdrRatioAvailable) {
display.registerHdrSdrRatioChangedListener({ it.run() }, hdrSdrListener)
View.VISIBLE
} else {
View.GONE
}
findViewById<Button>(R.id.mode_hdr)!!.visibility = hdrVis
findViewById<Button>(R.id.mode_hdr10)!!.visibility = hdrVis
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
display.unregisterHdrSdrRatioChangedListener(hdrsdrListener)
displayManager.unregisterDisplayListener(displayChangedListener)
display.unregisterHdrSdrRatioChangedListener(hdrSdrListener)
}
private fun setColorMode(newMode: Int) {
val window = window!!
var sdrWhitepointChanged = false
// Need to do this before setting the colorMode, as setting the colorMode will
// trigger the attribute change listener
if (newMode == ActivityInfo.COLOR_MODE_HDR ||
newMode == COLOR_MODE_HDR10) {
if (window.colorMode == newMode) {
targetSdrWhitePointIndex = (targetSdrWhitePointIndex + 1) % SDR_WHITE_POINTS.size
sdrWhitepointChanged = true
}
setBrightness(1.0f)
} else {
setBrightness(.4f)
}
window.colorMode = newMode
if (sdrWhitepointChanged) {
threadedRenderer?.setColorMode(newMode, whitePoint)
}
val whitePoint = whitePoint.toInt()
currentModeDisplay?.run {
text = "Current Mode: " + when (newMode) {
ActivityInfo.COLOR_MODE_DEFAULT -> "Default/SRGB"
ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT -> "Wide Gamut"
ActivityInfo.COLOR_MODE_HDR -> "HDR (sdr white point $whitePoint)"
COLOR_MODE_HDR10 -> "HDR10 (sdr white point $whitePoint)"
else -> "Unknown"
}
}
window!!.colorMode = newMode
updateModeInfoDisplay()
}
override fun setWindow(window: Window) {
this.window = window
}
private fun setBrightness(level: Float) {
// To keep window state in sync
window?.attributes?.screenBrightness = level
invalidate()
// To force an 'immediate' snap to what we want
// Imperfect, but close enough, synchronization by waiting for frame commit to set the value
viewTreeObserver.registerFrameCommitCallback {
try {
displayManager.setTemporaryBrightness(displayId, level)
} catch (ex: Exception) {
// Ignore a permission denied rejection - it doesn't meaningfully change much
private fun updateModeInfoDisplay() {
val sdrHdrRatio = display?.hdrSdrRatio ?: 1.0f
val colormode = window!!.colorMode
currentModeDisplay?.run {
text = "Current Mode: " + when (colormode) {
ActivityInfo.COLOR_MODE_DEFAULT -> "Default/SRGB"
ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT -> "Wide Gamut"
ActivityInfo.COLOR_MODE_HDR -> "HDR (sdr/hdr ratio $sdrHdrRatio)"
ActivityInfo.COLOR_MODE_HDR10 -> "HDR10 (sdr/hdr ratio $sdrHdrRatio)"
else -> "Unknown"
}
}
}