Wire up colorMode="hdr" on VRI
Test: silkfx
Bug: 266628247
Change-Id: I6633436f38d83a0fc5bfa59a29e684a9f1712843
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index db72e29..f8f2663 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -350,7 +350,14 @@
* @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.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 480abe0..6b0f850 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -683,9 +683,10 @@
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 @@
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 @@
} else {
mDisplay = preferredDisplay;
}
+ if (mHdrSdrRatioChangedListener != null && mDisplay != null) {
+ mDisplay.registerHdrSdrRatioChangedListener(mExecutor, mHdrSdrRatioChangedListener);
+ }
mContext.updateDisplay(mDisplay.getDisplayId());
}
@@ -4838,11 +4845,11 @@
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 @@
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 @@
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 @@
}
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 @@
private void destroyHardwareRenderer() {
ThreadedRenderer hardwareRenderer = mAttachInfo.mThreadedRenderer;
+ if (mHdrSdrRatioChangedListener != null) {
+ mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
+ }
+
if (hardwareRenderer != null) {
if (mHardwareRendererObserver != null) {
hardwareRenderer.removeObserver(mHardwareRendererObserver);
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 0488b9d..9ed3d9c 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -667,7 +667,7 @@
}
/** @hide */
- public void setTargetSdrHdrRatio(float ratio) {
+ public void setTargetHdrSdrRatio(float ratio) {
if (ratio < 1.f || !Float.isFinite(ratio)) ratio = 1.f;
nSetTargetSdrHdrRatio(mNativeProxy, ratio);
}
diff --git a/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt b/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt
index 1bd8f6a..56ab755 100644
--- a/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt
+++ b/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt
@@ -18,10 +18,10 @@
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 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 @@
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"
}
}
}