Merge changes from topic "health_cleanup"
* changes:
libbatteryservice: remove binder details
Remove include/batteryservice
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 80358d2..f5a167c 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -126,6 +126,7 @@
{ OPT, "events/sched/sched_waking/enable" },
{ OPT, "events/sched/sched_blocked_reason/enable" },
{ OPT, "events/sched/sched_cpu_hotplug/enable" },
+ { OPT, "events/sched/sched_pi_setprio/enable" },
{ OPT, "events/cgroup/enable" },
} },
{ "irq", "IRQ Events", 0, {
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 5b60ad2..c6cc8cb 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -1,6 +1,6 @@
## Permissions to allow system-wide tracing to the kernel trace buffer.
##
-on post-fs
+on late-init
# Allow writing to the kernel trace log.
chmod 0222 /sys/kernel/debug/tracing/trace_marker
@@ -29,6 +29,8 @@
chmod 0666 /sys/kernel/tracing/events/sched/sched_blocked_reason/enable
chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_cpu_hotplug/enable
chmod 0666 /sys/kernel/tracing/events/sched/sched_cpu_hotplug/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_pi_setprio/enable
+ chmod 0666 /sys/kernel/tracing/events/sched/sched_pi_setprio/enable
chmod 0666 /sys/kernel/debug/tracing/events/cgroup/enable
chmod 0666 /sys/kernel/tracing/events/cgroup/enable
chmod 0666 /sys/kernel/debug/tracing/events/power/cpu_frequency/enable
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index e3d2690..d93a66e 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -333,7 +333,7 @@
}
// find anrd's pid if it is running.
- pid = GetPidByName("/system/xbin/anrd");
+ pid = GetPidByName("/system/bin/anrd");
if (pid > 0) {
if (stat(trace_path, &st) == 0) {
diff --git a/cmds/rawbu/Android.bp b/cmds/rawbu/Android.bp
new file mode 100644
index 0000000..363ffc1
--- /dev/null
+++ b/cmds/rawbu/Android.bp
@@ -0,0 +1,14 @@
+// Copyright 2009 The Android Open Source Project
+
+cc_binary {
+ name: "rawbu",
+
+ srcs: ["backup.cpp"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: ["libcutils"],
+}
diff --git a/cmds/rawbu/Android.mk b/cmds/rawbu/Android.mk
deleted file mode 100644
index 9322151..0000000
--- a/cmds/rawbu/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= backup.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := libcutils libc
-
-LOCAL_MODULE:= rawbu
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
-
-include $(BUILD_EXECUTABLE)
diff --git a/data/etc/go_handheld_core_hardware.xml b/data/etc/go_handheld_core_hardware.xml
index ffebc9f..8b5a461 100644
--- a/data/etc/go_handheld_core_hardware.xml
+++ b/data/etc/go_handheld_core_hardware.xml
@@ -42,6 +42,7 @@
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
<feature name="android.software.autofill" />
+ <feature name="android.software.cant_save_state" />
<!-- Feature to specify if the device supports adding device admins. -->
<feature name="android.software.device_admin" />
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index c76e611..060a334 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -50,6 +50,7 @@
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
<feature name="android.software.autofill" />
+ <feature name="android.software.cant_save_state" />
<!-- Feature to specify if the device supports adding device admins. -->
<feature name="android.software.device_admin" />
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 9b88648..6db2627 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -50,6 +50,7 @@
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
<feature name="android.software.autofill" />
+ <feature name="android.software.cant_save_state" />
<!-- Feature to specify if the device supports adding device admins. -->
<feature name="android.software.device_admin" />
diff --git a/include/android/hardware_buffer_jni.h b/include/android/hardware_buffer_jni.h
index 6020870..7c4be24 100644
--- a/include/android/hardware_buffer_jni.h
+++ b/include/android/hardware_buffer_jni.h
@@ -31,9 +31,11 @@
/**
* Return the AHardwareBuffer associated with a Java HardwareBuffer object,
- * for interacting with it through native code. This acquires a reference
- * on the AHardwareBuffer that is returned; be sure to use
- * AHardwareBuffer_release() when done with it so that it doesn't leak.
+ * for interacting with it through native code. This method does not acquire any
+ * additional reference to the AHardwareBuffer that is returned. To keep the
+ * AHardwareBuffer live after the Java HardwareBuffer object got garbage
+ * collected, be sure to use AHardwareBuffer_acquire() to acquire an additional
+ * reference.
*/
AHardwareBuffer* AHardwareBuffer_fromHardwareBuffer(JNIEnv* env,
jobject hardwareBufferObj);
diff --git a/libs/vr/libdvr/tests/dvr_tracking-test.cpp b/libs/vr/libdvr/tests/dvr_tracking-test.cpp
index d1ff6df..1ebbc1f 100644
--- a/libs/vr/libdvr/tests/dvr_tracking-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_tracking-test.cpp
@@ -8,8 +8,34 @@
class DvrTrackingTest : public DvrApiTest {};
#if DVR_TRACKING_IMPLEMENTED
-// TODO(b/78173557): Implement dvrTrackingXXX API test.
-#else
+
+TEST_F(DvrTrackingTest, Implemented) {
+ ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
+ ASSERT_TRUE(api_.TrackingCameraStart != nullptr);
+ ASSERT_TRUE(api_.TrackingCameraStop != nullptr);
+}
+
+TEST_F(DvrTrackingTest, CreateFailsForInvalidInput) {
+ int ret;
+ ret = api_.TrackingCameraCreate(nullptr);
+ EXPECT_EQ(ret, -EINVAL);
+
+ DvrTrackingCamera* camera = reinterpret_cast<DvrTrackingCamera*>(42);
+ ret = api_.TrackingCameraCreate(&camera);
+ EXPECT_EQ(ret, -EINVAL);
+}
+
+TEST_F(DvrTrackingTest, CreateDestroy) {
+ DvrTrackingCamera* camera = nullptr;
+ int ret = api_.TrackingCameraCreate(&camera);
+
+ EXPECT_EQ(ret, 0);
+ ASSERT_TRUE(camera != nullptr);
+
+ api_.TrackingCameraDestroy(camera);
+}
+
+#else // !DVR_TRACKING_IMPLEMENTED
TEST_F(DvrTrackingTest, NotImplemented) {
ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 3c3eab6..55023d7 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -519,11 +519,9 @@
recomputeVisibleRegions = true;
}
- // Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are not legacy
- // data space, however since framework doesn't distinguish them out of
- // legacy SRGB, we have to treat them as the same for now.
- // UNKNOWN is treated as legacy SRGB when the connected api is EGL.
ui::Dataspace dataSpace = mConsumer->getCurrentDataSpace();
+ // treat modern dataspaces as legacy dataspaces whenever possible, until
+ // we can trust the buffer producers
switch (dataSpace) {
case ui::Dataspace::V0_SRGB:
dataSpace = ui::Dataspace::SRGB;
@@ -531,10 +529,17 @@
case ui::Dataspace::V0_SRGB_LINEAR:
dataSpace = ui::Dataspace::SRGB_LINEAR;
break;
- case ui::Dataspace::UNKNOWN:
- if (mConsumer->getCurrentApi() == NATIVE_WINDOW_API_EGL) {
- dataSpace = ui::Dataspace::SRGB;
- }
+ case ui::Dataspace::V0_JFIF:
+ dataSpace = ui::Dataspace::JFIF;
+ break;
+ case ui::Dataspace::V0_BT601_625:
+ dataSpace = ui::Dataspace::BT601_625;
+ break;
+ case ui::Dataspace::V0_BT601_525:
+ dataSpace = ui::Dataspace::BT601_525;
+ break;
+ case ui::Dataspace::V0_BT709:
+ dataSpace = ui::Dataspace::BT709;
break;
default:
break;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 346d14c..1d3c003 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -80,6 +80,7 @@
bool hasWideColorGamut,
const HdrCapabilities& hdrCapabilities,
const int32_t supportedPerFrameMetadata,
+ const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
int initialPowerMode)
: lastCompositionHadVisibleLayers(false),
mFlinger(flinger),
@@ -105,7 +106,11 @@
mHasHdr10(false),
mHasHLG(false),
mHasDolbyVision(false),
- mSupportedPerFrameMetadata(supportedPerFrameMetadata)
+ mSupportedPerFrameMetadata(supportedPerFrameMetadata),
+ mHasBT2100PQColorimetric(false),
+ mHasBT2100PQEnhance(false),
+ mHasBT2100HLGColorimetric(false),
+ mHasBT2100HLGEnhance(false)
{
// clang-format on
std::vector<Hdr> types = hdrCapabilities.getSupportedHdrTypes();
@@ -145,6 +150,18 @@
}
mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);
+ auto iter = hdrAndRenderIntents.find(ColorMode::BT2100_PQ);
+ if (iter != hdrAndRenderIntents.end()) {
+ hasToneMapping(iter->second,
+ &mHasBT2100PQColorimetric, &mHasBT2100PQEnhance);
+ }
+
+ iter = hdrAndRenderIntents.find(ColorMode::BT2100_HLG);
+ if (iter != hdrAndRenderIntents.end()) {
+ hasToneMapping(iter->second,
+ &mHasBT2100HLGColorimetric, &mHasBT2100HLGEnhance);
+ }
+
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}
@@ -528,6 +545,22 @@
result.append(surfaceDump);
}
+void DisplayDevice::hasToneMapping(const std::vector<RenderIntent>& renderIntents,
+ bool* outColorimetric, bool *outEnhance) {
+ for (auto intent : renderIntents) {
+ switch (intent) {
+ case RenderIntent::TONE_MAP_COLORIMETRIC:
+ *outColorimetric = true;
+ break;
+ case RenderIntent::TONE_MAP_ENHANCE:
+ *outEnhance = true;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 13caabf..9445274 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -20,6 +20,7 @@
#include "Transform.h"
#include <stdlib.h>
+#include <unordered_map>
#include <math/mat4.h>
@@ -91,6 +92,7 @@
bool hasWideColorGamut,
const HdrCapabilities& hdrCapabilities,
const int32_t supportedPerFrameMetadata,
+ const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
int initialPowerMode);
// clang-format on
@@ -144,6 +146,7 @@
status_t beginFrame(bool mustRecompose) const;
status_t prepareFrame(HWComposer& hwc);
bool hasWideColorGamut() const { return mHasWideColorGamut; }
+ // Whether h/w composer has native support for specific HDR type.
bool hasHDR10Support() const { return mHasHdr10; }
bool hasHLGSupport() const { return mHasHLG; }
bool hasDolbyVisionSupport() const { return mHasDolbyVision; }
@@ -155,6 +158,14 @@
// respectively if hardware composer doesn't return meaningful values.
const HdrCapabilities& getHdrCapabilities() const { return mHdrCapabilities; }
+ // Whether h/w composer has BT2100_PQ color mode.
+ bool hasBT2100PQColorimetricSupport() const { return mHasBT2100PQColorimetric; }
+ bool hasBT2100PQEnhanceSupport() const { return mHasBT2100PQEnhance; }
+
+ // Whether h/w composer has BT2100_HLG color mode.
+ bool hasBT2100HLGColorimetricSupport() const { return mHasBT2100HLGColorimetric; }
+ bool hasBT2100HLGEnhanceSupport() const { return mHasBT2100HLGEnhance; }
+
void swapBuffers(HWComposer& hwc) const;
// called after h/w composer has completed its set() call
@@ -205,6 +216,9 @@
void dump(String8& result) const;
private:
+ void hasToneMapping(const std::vector<ui::RenderIntent>& renderIntents,
+ bool* outColorimetric, bool *outEnhance);
+
/*
* Constants, set during initialization
*/
@@ -276,6 +290,12 @@
bool mHasDolbyVision;
HdrCapabilities mHdrCapabilities;
const int32_t mSupportedPerFrameMetadata;
+ // Whether h/w composer has BT2100_PQ and BT2100_HLG color mode with
+ // colorimetrical tone mapping or enhanced tone mapping.
+ bool mHasBT2100PQColorimetric;
+ bool mHasBT2100PQEnhance;
+ bool mHasBT2100HLGColorimetric;
+ bool mHasBT2100HLGEnhance;
};
struct DisplayDeviceState {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 8e54392..c42dfec 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -624,7 +624,10 @@
ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
{
auto error = hwcDisplay->setPowerMode(mode);
- LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error, displayId);
+ if (error != HWC2::Error::None) {
+ LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
+ error, displayId);
+ }
}
break;
case HWC2::PowerMode::Doze:
@@ -633,14 +636,19 @@
{
bool supportsDoze = false;
auto error = hwcDisplay->supportsDoze(&supportsDoze);
- LOG_HWC_ERROR("supportsDoze", error, displayId);
+ if (error != HWC2::Error::None) {
+ LOG_HWC_ERROR("supportsDoze", error, displayId);
+ }
if (!supportsDoze) {
mode = HWC2::PowerMode::On;
}
error = hwcDisplay->setPowerMode(mode);
- LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error, displayId);
+ if (error != HWC2::Error::None) {
+ LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
+ error, displayId);
+ }
}
break;
default:
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8a90083..8539079 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1646,9 +1646,10 @@
return true;
}
-bool Layer::isLegacySrgbDataSpace() const {
- return mDrawingState.dataSpace == ui::Dataspace::SRGB ||
- mDrawingState.dataSpace == ui::Dataspace::SRGB_LINEAR;
+bool Layer::isLegacyDataSpace() const {
+ // return true when no higher bits are set
+ return !(mDrawingState.dataSpace & (ui::Dataspace::STANDARD_MASK |
+ ui::Dataspace::TRANSFER_MASK | ui::Dataspace::RANGE_MASK));
}
void Layer::setParent(const sp<Layer>& layer) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index eda03dd..b4516a7 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -240,8 +240,8 @@
// desaturated in order to match what they appears like visually.
// With color management, these contents will appear desaturated, thus
// needed to be saturated so that they match what they are designed for
- // visually. When returns true, legacy SRGB data space is passed to HWC.
- bool isLegacySrgbDataSpace() const;
+ // visually.
+ bool isLegacyDataSpace() const;
// If we have received a new buffer this frame, we will pass its surface
// damage down to hardware composer. Otherwise, we must send a region with
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 08cd5b0..64095dd 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -259,10 +259,8 @@
mState.setTexture(texture);
}
-mat4 GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) {
- mat4 oldTransform = mState.getColorMatrix();
+void GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) {
mState.setColorMatrix(colorTransform);
- return oldTransform;
}
void GLES20RenderEngine::disableTexturing() {
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 9acd79b..c9e402d 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -80,7 +80,7 @@
virtual void setupLayerTexturing(const Texture& texture);
virtual void setupLayerBlackedOut();
virtual void setupFillWithColor(float r, float g, float b, float a);
- virtual mat4 setupColorTransform(const mat4& colorTransform);
+ virtual void setupColorTransform(const mat4& colorTransform);
virtual void disableTexturing();
virtual void disableBlending();
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 89ee64b..5f09ac0 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -251,7 +251,7 @@
const float maxMasteringLumi = 1000.0;
const float maxContentLumi = 1000.0;
const float maxInLumi = min(maxMasteringLumi, maxContentLumi);
- const float maxOutLumi = displayMaxLuminance;
+ float maxOutLumi = displayMaxLuminance;
// Calculate Y value in XYZ color space.
float colorY = CalculateY(color);
@@ -269,18 +269,18 @@
// three control points
const float x0 = 10.0;
const float y0 = 17.0;
- const float x1 = maxOutLumi * 0.75;
- const float y1 = x1;
- const float x2 = x1 + (maxInLumi - x1) / 2.0;
- const float y2 = y1 + (maxOutLumi - y1) * 0.75;
+ float x1 = maxOutLumi * 0.75;
+ float y1 = x1;
+ float x2 = x1 + (maxInLumi - x1) / 2.0;
+ float y2 = y1 + (maxOutLumi - y1) * 0.75;
// horizontal distances between the last three control points
- const float h12 = x2 - x1;
- const float h23 = maxInLumi - x2;
+ float h12 = x2 - x1;
+ float h23 = maxInLumi - x2;
// tangents at the last three control points
- const float m1 = (y2 - y1) / h12;
- const float m3 = (maxOutLumi - y2) / h23;
- const float m2 = (m1 + m3) / 2.0;
+ float m1 = (y2 - y1) / h12;
+ float m3 = (maxOutLumi - y2) / h23;
+ float m2 = (m1 + m3) / 2.0;
if (nits < x0) {
// scale [0.0, x0] to [0.0, y0] linearly
@@ -288,7 +288,7 @@
nits *= slope;
} else if (nits < x1) {
// scale [x0, x1] to [y0, y1] linearly
- const float slope = (y1 - y0) / (x1 - x0);
+ float slope = (y1 - y0) / (x1 - x0);
nits = y0 + (nits - x0) * slope;
} else if (nits < x2) {
// scale [x1, x2] to [y1, y2] using Hermite interp
@@ -448,7 +448,7 @@
if (needs.hasTransformMatrix() || (needs.getInputTF() != needs.getOutputTF())) {
// Currently, only the OOTF of BT2020 PQ needs display maximum luminance.
if (needs.getInputTF() == Key::INPUT_TF_ST2084) {
- fs << "uniform float displayMaxLuminance";
+ fs << "uniform float displayMaxLuminance;";
}
if (needs.hasInputTransformMatrix()) {
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index df9e6a7..d559464 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -112,7 +112,7 @@
virtual void setupLayerBlackedOut() = 0;
virtual void setupFillWithColor(float r, float g, float b, float a) = 0;
- virtual mat4 setupColorTransform(const mat4& /* colorTransform */) = 0;
+ virtual void setupColorTransform(const mat4& /* colorTransform */) = 0;
virtual void disableTexturing() = 0;
virtual void disableBlending() = 0;
@@ -224,7 +224,7 @@
void checkErrors() const override;
- mat4 setupColorTransform(const mat4& /* colorTransform */) override { return mat4(); }
+ void setupColorTransform(const mat4& /* colorTransform */) override {}
// internal to RenderEngine
EGLDisplay getEGLDisplay() const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index abd74c1..afa34d0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -245,7 +245,6 @@
mPrimaryDispSync("PrimaryDispSync"),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
- mHasColorMatrix(false),
mHasPoweredOff(false),
mNumLayers(0),
mVrFlingerRequestsDisplay(false),
@@ -726,10 +725,13 @@
}
void SurfaceFlinger::readPersistentProperties() {
+ Mutex::Autolock _l(mStateLock);
+
char value[PROPERTY_VALUE_MAX];
property_get("persist.sys.sf.color_saturation", value, "1.0");
mGlobalSaturationFactor = atof(value);
+ updateColorMatrixLocked();
ALOGV("Saturation is set to %.2f", mGlobalSaturationFactor);
property_get("persist.sys.sf.native_mode", value, "0");
@@ -1019,25 +1021,12 @@
}
void SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
- ColorMode mode, Dataspace dataSpace) {
+ ColorMode mode, Dataspace dataSpace,
+ RenderIntent renderIntent) {
ColorMode currentMode = hw->getActiveColorMode();
Dataspace currentDataSpace = hw->getCompositionDataSpace();
RenderIntent currentRenderIntent = hw->getActiveRenderIntent();
- // Natural Mode means it's color managed and the color must be right,
- // thus we pick RenderIntent::COLORIMETRIC as render intent.
- // Native Mode means the display is not color managed, and whichever
- // render intent is picked doesn't matter, thus return
- // RenderIntent::COLORIMETRIC as default here.
- RenderIntent renderIntent = RenderIntent::COLORIMETRIC;
-
- // In Auto Color Mode, we want to strech to panel color space, right now
- // only the built-in display supports it.
- if (mDisplayColorSetting == DisplayColorSetting::ENHANCED && mBuiltinDisplaySupportsEnhance &&
- hw->isPrimary()) {
- renderIntent = RenderIntent::ENHANCE;
- }
-
if (mode == currentMode && dataSpace == currentDataSpace &&
renderIntent == currentRenderIntent) {
return;
@@ -1087,7 +1076,8 @@
ALOGW("Attempt to set active color mode %s %d for virtual display",
decodeColorMode(mMode).c_str(), mMode);
} else {
- mFlinger.setActiveColorModeInternal(hw, mMode, Dataspace::UNKNOWN);
+ mFlinger.setActiveColorModeInternal(hw, mMode, Dataspace::UNKNOWN,
+ RenderIntent::COLORIMETRIC);
}
return true;
}
@@ -1469,13 +1459,12 @@
(mPreviousPresentFence->getSignalTime() ==
Fence::SIGNAL_TIME_PENDING);
ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
- if (mPropagateBackpressure && frameMissed) {
- mTimeStats.incrementMissedFrames(true);
- signalLayerUpdate();
- break;
- }
if (frameMissed) {
- mTimeStats.incrementMissedFrames(false);
+ mTimeStats.incrementMissedFrames();
+ if (mPropagateBackpressure) {
+ signalLayerUpdate();
+ break;
+ }
}
// Now that we're going to make it to the handleMessageTransaction()
@@ -1868,54 +1857,41 @@
}
}
-mat4 SurfaceFlinger::computeSaturationMatrix() const {
- if (mGlobalSaturationFactor == 1.0f) {
- return mat4();
- }
-
- // Rec.709 luma coefficients
- float3 luminance{0.213f, 0.715f, 0.072f};
- luminance *= 1.0f - mGlobalSaturationFactor;
- return mat4(
- vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f},
- vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f},
- vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f},
- vec4{0.0f, 0.0f, 0.0f, 1.0f}
- );
-}
-
-// Returns a dataspace that fits all visible layers. The returned dataspace
+// Returns a data space that fits all visible layers. The returned data space
// can only be one of
-//
-// - Dataspace::V0_SRGB
+// - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced)
// - Dataspace::DISPLAY_P3
// - Dataspace::V0_SCRGB_LINEAR
-// TODO(b/73825729) Add BT2020 data space.
-ui::Dataspace SurfaceFlinger::getBestDataspace(
- const sp<const DisplayDevice>& displayDevice) const {
- Dataspace bestDataspace = Dataspace::V0_SRGB;
+// The returned HDR data space is one of
+// - Dataspace::UNKNOWN
+// - Dataspace::BT2020_HLG
+// - Dataspace::BT2020_PQ
+Dataspace SurfaceFlinger::getBestDataspace(
+ const sp<const DisplayDevice>& displayDevice, Dataspace* outHdrDataSpace) const {
+ Dataspace bestDataSpace = Dataspace::SRGB;
+ *outHdrDataSpace = Dataspace::UNKNOWN;
+
for (const auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
switch (layer->getDataSpace()) {
case Dataspace::V0_SCRGB:
case Dataspace::V0_SCRGB_LINEAR:
- // return immediately
- return Dataspace::V0_SCRGB_LINEAR;
- case Dataspace::DISPLAY_P3:
- bestDataspace = Dataspace::DISPLAY_P3;
+ bestDataSpace = Dataspace::V0_SCRGB_LINEAR;
break;
- // Historically, HDR dataspaces are ignored by SurfaceFlinger. But
- // since SurfaceFlinger simulates HDR support now, it should honor
- // them unless there is also native support.
+ case Dataspace::DISPLAY_P3:
+ if (bestDataSpace == Dataspace::SRGB) {
+ bestDataSpace = Dataspace::DISPLAY_P3;
+ }
+ break;
case Dataspace::BT2020_PQ:
case Dataspace::BT2020_ITU_PQ:
- if (!displayDevice->hasHDR10Support()) {
- return Dataspace::V0_SCRGB_LINEAR;
- }
+ *outHdrDataSpace = Dataspace::BT2020_PQ;
break;
case Dataspace::BT2020_HLG:
case Dataspace::BT2020_ITU_HLG:
- if (!displayDevice->hasHLGSupport()) {
- return Dataspace::V0_SCRGB_LINEAR;
+ // When there's mixed PQ content and HLG content, we set the HDR
+ // data space to be BT2020_PQ and convert HLG to PQ.
+ if (*outHdrDataSpace == Dataspace::UNKNOWN) {
+ *outHdrDataSpace = Dataspace::BT2020_HLG;
}
break;
default:
@@ -1923,29 +1899,119 @@
}
}
- return bestDataspace;
+ return bestDataSpace;
}
// Pick the ColorMode / Dataspace for the display device.
-// TODO(b/73825729) Add BT2020 color mode.
void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& displayDevice,
- ColorMode* outMode, Dataspace* outDataSpace) const {
+ ColorMode* outMode, Dataspace* outDataSpace,
+ RenderIntent* outRenderIntent) const {
if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) {
*outMode = ColorMode::NATIVE;
*outDataSpace = Dataspace::UNKNOWN;
+ *outRenderIntent = RenderIntent::COLORIMETRIC;
return;
}
- switch (getBestDataspace(displayDevice)) {
- case Dataspace::DISPLAY_P3:
- case Dataspace::V0_SCRGB_LINEAR:
+ Dataspace hdrDataSpace;
+ Dataspace bestDataSpace = getBestDataspace(displayDevice, &hdrDataSpace);
+
+ if (hdrDataSpace == Dataspace::BT2020_PQ) {
+ // Hardware composer can handle BT2100 ColorMode only when
+ // - colorimetrical tone mapping is supported, or
+ // - Auto mode is turned on and enhanced tone mapping is supported.
+ if (displayDevice->hasBT2100PQColorimetricSupport() ||
+ (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
+ displayDevice->hasBT2100PQEnhanceSupport())) {
+ *outMode = ColorMode::BT2100_PQ;
+ *outDataSpace = Dataspace::BT2020_PQ;
+ } else if (displayDevice->hasHDR10Support()) {
+ // Legacy HDR support. HDR layers are treated as UNKNOWN layers.
+ hdrDataSpace = Dataspace::UNKNOWN;
+ } else {
+ // Simulate PQ through RenderEngine, pick DISPLAY_P3 color mode.
*outMode = ColorMode::DISPLAY_P3;
*outDataSpace = Dataspace::DISPLAY_P3;
- break;
+ }
+ } else if (hdrDataSpace == Dataspace::BT2020_HLG) {
+ if (displayDevice->hasBT2100HLGColorimetricSupport() ||
+ (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
+ displayDevice->hasBT2100HLGEnhanceSupport())) {
+ *outMode = ColorMode::BT2100_HLG;
+ *outDataSpace = Dataspace::BT2020_HLG;
+ } else if (displayDevice->hasHLGSupport()) {
+ // Legacy HDR support. HDR layers are treated as UNKNOWN layers.
+ hdrDataSpace = Dataspace::UNKNOWN;
+ } else {
+ // Simulate HLG through RenderEngine, pick DISPLAY_P3 color mode.
+ *outMode = ColorMode::DISPLAY_P3;
+ *outDataSpace = Dataspace::DISPLAY_P3;
+ }
+ }
+
+ // At this point, there's no HDR layer.
+ if (hdrDataSpace == Dataspace::UNKNOWN) {
+ switch (bestDataSpace) {
+ case Dataspace::DISPLAY_P3:
+ case Dataspace::V0_SCRGB_LINEAR:
+ *outMode = ColorMode::DISPLAY_P3;
+ *outDataSpace = Dataspace::DISPLAY_P3;
+ break;
+ default:
+ *outMode = ColorMode::SRGB;
+ *outDataSpace = Dataspace::SRGB;
+ break;
+ }
+ }
+ *outRenderIntent = pickRenderIntent(displayDevice, *outMode);
+}
+
+RenderIntent SurfaceFlinger::pickRenderIntent(const sp<DisplayDevice>& displayDevice,
+ ColorMode colorMode) const {
+ // Native Mode means the display is not color managed, and whichever
+ // render intent is picked doesn't matter, thus return
+ // RenderIntent::COLORIMETRIC as default here.
+ if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) {
+ return RenderIntent::COLORIMETRIC;
+ }
+
+ // In Auto Color Mode, we want to strech to panel color space, right now
+ // only the built-in display supports it.
+ if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
+ mBuiltinDisplaySupportsEnhance && displayDevice->isPrimary()) {
+ switch (colorMode) {
+ case ColorMode::DISPLAY_P3:
+ case ColorMode::SRGB:
+ return RenderIntent::ENHANCE;
+ // In Auto Color Mode, BT2100_PQ and BT2100_HLG will only be picked
+ // when TONE_MAP_ENHANCE or TONE_MAP_COLORIMETRIC is supported.
+ // If TONE_MAP_ENHANCE is not supported, fall back to TONE_MAP_COLORIMETRIC.
+ case ColorMode::BT2100_PQ:
+ return displayDevice->hasBT2100PQEnhanceSupport() ?
+ RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
+ case ColorMode::BT2100_HLG:
+ return displayDevice->hasBT2100HLGEnhanceSupport() ?
+ RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
+ // This statement shouldn't be reached, switch cases will always
+ // cover all possible ColorMode returned by pickColorMode.
+ default:
+ return RenderIntent::COLORIMETRIC;
+ }
+ }
+
+ // Either enhance is not supported or we are in natural mode.
+
+ // Natural Mode means it's color managed and the color must be right,
+ // thus we pick RenderIntent::COLORIMETRIC as render intent for non-HDR
+ // content and pick RenderIntent::TONE_MAP_COLORIMETRIC for HDR content.
+ switch (colorMode) {
+ // In Natural Color Mode, BT2100_PQ and BT2100_HLG will only be picked
+ // when TONE_MAP_COLORIMETRIC is supported.
+ case ColorMode::BT2100_PQ:
+ case ColorMode::BT2100_HLG:
+ return RenderIntent::TONE_MAP_COLORIMETRIC;
default:
- *outMode = ColorMode::SRGB;
- *outDataSpace = Dataspace::V0_SRGB;
- break;
+ return RenderIntent::COLORIMETRIC;
}
}
@@ -2009,9 +2075,6 @@
}
}
-
- mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer();
-
// Set the per-frame data
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
auto& displayDevice = mDisplays[displayId];
@@ -2020,9 +2083,9 @@
if (hwcId < 0) {
continue;
}
- if (colorMatrix != mPreviousColorMatrix) {
- displayDevice->setColorTransform(colorMatrix);
- status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix);
+ if (mDrawingState.colorMatrixChanged) {
+ displayDevice->setColorTransform(mDrawingState.colorMatrix);
+ status_t result = getBE().mHwc->setColorTransform(hwcId, mDrawingState.colorMatrix);
ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
"display %zd: %d", displayId, result);
}
@@ -2050,12 +2113,13 @@
if (hasWideColorDisplay) {
ColorMode colorMode;
Dataspace dataSpace;
- pickColorMode(displayDevice, &colorMode, &dataSpace);
- setActiveColorModeInternal(displayDevice, colorMode, dataSpace);
+ RenderIntent renderIntent;
+ pickColorMode(displayDevice, &colorMode, &dataSpace, &renderIntent);
+ setActiveColorModeInternal(displayDevice, colorMode, dataSpace, renderIntent);
}
}
- mPreviousColorMatrix = colorMatrix;
+ mDrawingState.colorMatrixChanged = false;
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
auto& displayDevice = mDisplays[displayId];
@@ -2265,6 +2329,8 @@
const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
bool hasWideColorGamut = false;
+ std::unordered_map<ColorMode, std::vector<RenderIntent>> hdrAndRenderIntents;
+
if (hasWideColorDisplay) {
std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
for (ColorMode colorMode : modes) {
@@ -2274,7 +2340,6 @@
case ColorMode::DCI_P3:
hasWideColorGamut = true;
break;
- // TODO(lpy) Handle BT2020, BT2100_PQ and BT2100_HLG properly.
default:
break;
}
@@ -2289,6 +2354,10 @@
}
}
}
+
+ if (colorMode == ColorMode::BT2100_PQ || colorMode == ColorMode::BT2100_HLG) {
+ hdrAndRenderIntents.emplace(colorMode, renderIntents);
+ }
}
}
@@ -2327,7 +2396,7 @@
dispSurface, std::move(renderSurface), displayWidth, displayHeight,
hasWideColorGamut, hdrCapabilities,
getHwComposer().getSupportedPerFrameMetadata(hwcId),
- initialPowerMode);
+ hdrAndRenderIntents, initialPowerMode);
if (maxFrameBufferAcquiredBuffers >= 3) {
nativeWindowSurface->preallocateBuffers();
@@ -2339,7 +2408,8 @@
defaultColorMode = ColorMode::SRGB;
defaultDataSpace = Dataspace::V0_SRGB;
}
- setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace);
+ setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace,
+ RenderIntent::COLORIMETRIC);
hw->setLayerStack(state.layerStack);
hw->setProjection(state.orientation, state.viewport, state.frame);
hw->setDisplayName(state.displayName);
@@ -2648,6 +2718,9 @@
mAnimCompositionPending = mAnimTransactionPending;
mDrawingState = mCurrentState;
+ // clear the "changed" flags in current state
+ mCurrentState.colorMatrixChanged = false;
+
mDrawingState.traverseInZOrder([](Layer* layer) {
layer->commitChildList();
});
@@ -2891,19 +2964,13 @@
const DisplayRenderArea renderArea(displayDevice);
const auto hwcId = displayDevice->getHwcDisplayId();
const bool hasClientComposition = getBE().mHwc->hasClientComposition(hwcId);
- const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(hwcId);
- const bool skipClientColorTransform = getBE().mHwc->hasCapability(
- HWC2::Capability::SkipClientColorTransform);
ATRACE_INT("hasClientComposition", hasClientComposition);
- mat4 oldColorMatrix;
- mat4 legacySrgbSaturationMatrix = mLegacySrgbSaturationMatrix;
- const bool applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
- if (applyColorMatrix) {
- mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer();
- oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
- legacySrgbSaturationMatrix = colorMatrix * legacySrgbSaturationMatrix;
- }
+ bool applyColorMatrix = false;
+ bool applyLegacyColorMatrix = false;
+ mat4 colorMatrix;
+ mat4 legacyColorMatrix;
+ const mat4* currentColorMatrix = nullptr;
if (hasClientComposition) {
ALOGV("hasClientComposition");
@@ -2916,6 +2983,26 @@
getBE().mRenderEngine->setDisplayMaxLuminance(
displayDevice->getHdrCapabilities().getDesiredMaxLuminance());
+ const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(hwcId);
+ const bool skipClientColorTransform = getBE().mHwc->hasCapability(
+ HWC2::Capability::SkipClientColorTransform);
+
+ applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
+ if (applyColorMatrix) {
+ colorMatrix = mDrawingState.colorMatrix;
+ }
+
+ applyLegacyColorMatrix = (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
+ outputDataspace != Dataspace::UNKNOWN &&
+ outputDataspace != Dataspace::SRGB);
+ if (applyLegacyColorMatrix) {
+ if (applyColorMatrix) {
+ legacyColorMatrix = colorMatrix * mLegacySrgbSaturationMatrix;
+ } else {
+ legacyColorMatrix = mLegacySrgbSaturationMatrix;
+ }
+ }
+
if (!displayDevice->makeCurrent()) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
displayDevice->getDisplayName().c_str());
@@ -2977,69 +3064,59 @@
ALOGV("Rendering client layers");
const Transform& displayTransform = displayDevice->getTransform();
- if (hwcId >= 0) {
- // we're using h/w composer
- bool firstLayer = true;
- for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
- const Region clip(bounds.intersect(
- displayTransform.transform(layer->visibleRegion)));
- ALOGV("Layer: %s", layer->getName().string());
- ALOGV(" Composition type: %s",
- to_string(layer->getCompositionType(hwcId)).c_str());
- if (!clip.isEmpty()) {
- switch (layer->getCompositionType(hwcId)) {
- case HWC2::Composition::Cursor:
- case HWC2::Composition::Device:
- case HWC2::Composition::Sideband:
- case HWC2::Composition::SolidColor: {
- const Layer::State& state(layer->getDrawingState());
- if (layer->getClearClientTarget(hwcId) && !firstLayer &&
- layer->isOpaque(state) && (state.color.a == 1.0f)
- && hasClientComposition) {
- // never clear the very first layer since we're
- // guaranteed the FB is already cleared
- layer->clearWithOpenGL(renderArea);
- }
- break;
+ bool firstLayer = true;
+ for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
+ const Region clip(bounds.intersect(
+ displayTransform.transform(layer->visibleRegion)));
+ ALOGV("Layer: %s", layer->getName().string());
+ ALOGV(" Composition type: %s",
+ to_string(layer->getCompositionType(hwcId)).c_str());
+ if (!clip.isEmpty()) {
+ switch (layer->getCompositionType(hwcId)) {
+ case HWC2::Composition::Cursor:
+ case HWC2::Composition::Device:
+ case HWC2::Composition::Sideband:
+ case HWC2::Composition::SolidColor: {
+ const Layer::State& state(layer->getDrawingState());
+ if (layer->getClearClientTarget(hwcId) && !firstLayer &&
+ layer->isOpaque(state) && (state.color.a == 1.0f)
+ && hasClientComposition) {
+ // never clear the very first layer since we're
+ // guaranteed the FB is already cleared
+ layer->clearWithOpenGL(renderArea);
}
- case HWC2::Composition::Client: {
- // Only apply saturation matrix layer that is legacy SRGB dataspace
- // when auto color mode is on.
- bool restore = false;
- mat4 savedMatrix;
- if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
- layer->isLegacySrgbDataSpace()) {
- savedMatrix =
- getRenderEngine().setupColorTransform(legacySrgbSaturationMatrix);
- restore = true;
- }
- layer->draw(renderArea, clip);
- if (restore) {
- getRenderEngine().setupColorTransform(savedMatrix);
- }
- break;
- }
- default:
- break;
+ break;
}
- } else {
- ALOGV(" Skipping for empty clip");
+ case HWC2::Composition::Client: {
+ // switch color matrices lazily
+ if (layer->isLegacyDataSpace()) {
+ // TODO(b/78891890) Legacy sRGB saturation matrix should be set
+ // separately.
+ if (applyLegacyColorMatrix && currentColorMatrix != &legacyColorMatrix) {
+ getRenderEngine().setupColorTransform(legacyColorMatrix);
+ currentColorMatrix = &legacyColorMatrix;
+ }
+ } else {
+ if (applyColorMatrix && currentColorMatrix != &colorMatrix) {
+ getRenderEngine().setupColorTransform(colorMatrix);
+ currentColorMatrix = &colorMatrix;
+ }
+ }
+
+ layer->draw(renderArea, clip);
+ break;
+ }
+ default:
+ break;
}
- firstLayer = false;
+ } else {
+ ALOGV(" Skipping for empty clip");
}
- } else {
- // we're not using h/w composer
- for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
- const Region clip(bounds.intersect(
- displayTransform.transform(layer->visibleRegion)));
- if (!clip.isEmpty()) {
- layer->draw(renderArea, clip);
- }
- }
+ firstLayer = false;
}
- if (applyColorMatrix) {
- getRenderEngine().setupColorTransform(oldColorMatrix);
+ if (applyColorMatrix || applyLegacyColorMatrix) {
+ getRenderEngine().setupColorTransform(mat4());
}
// disable scissor at the end of the frame
@@ -4417,6 +4494,30 @@
return true;
}
+void SurfaceFlinger::updateColorMatrixLocked() {
+ mat4 colorMatrix;
+ if (mGlobalSaturationFactor != 1.0f) {
+ // Rec.709 luma coefficients
+ float3 luminance{0.213f, 0.715f, 0.072f};
+ luminance *= 1.0f - mGlobalSaturationFactor;
+ mat4 saturationMatrix = mat4(
+ vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f},
+ vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f},
+ vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f},
+ vec4{0.0f, 0.0f, 0.0f, 1.0f}
+ );
+ colorMatrix = mClientColorMatrix * saturationMatrix * mDaltonizer();
+ } else {
+ colorMatrix = mClientColorMatrix * mDaltonizer();
+ }
+
+ if (mCurrentState.colorMatrix != colorMatrix) {
+ mCurrentState.colorMatrix = colorMatrix;
+ mCurrentState.colorMatrixChanged = true;
+ setTransactionFlags(eTransactionNeeded);
+ }
+}
+
status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
switch (code) {
case CREATE_CONNECTION:
@@ -4551,6 +4652,7 @@
return NO_ERROR;
}
case 1014: {
+ Mutex::Autolock _l(mStateLock);
// daltonize
n = data.readInt32();
switch (n % 10) {
@@ -4572,33 +4674,33 @@
} else {
mDaltonizer.setMode(ColorBlindnessMode::Simulation);
}
- invalidateHwcGeometry();
- repaintEverything();
+
+ updateColorMatrixLocked();
return NO_ERROR;
}
case 1015: {
+ Mutex::Autolock _l(mStateLock);
// apply a color matrix
n = data.readInt32();
if (n) {
// color matrix is sent as a column-major mat4 matrix
for (size_t i = 0 ; i < 4; i++) {
for (size_t j = 0; j < 4; j++) {
- mColorMatrix[i][j] = data.readFloat();
+ mClientColorMatrix[i][j] = data.readFloat();
}
}
} else {
- mColorMatrix = mat4();
+ mClientColorMatrix = mat4();
}
// Check that supplied matrix's last row is {0,0,0,1} so we can avoid
// the division by w in the fragment shader
- float4 lastRow(transpose(mColorMatrix)[3]);
+ float4 lastRow(transpose(mClientColorMatrix)[3]);
if (any(greaterThan(abs(lastRow - float4{0, 0, 0, 1}), float4{1e-4f}))) {
ALOGE("The color transform's last row must be (0, 0, 0, 1)");
}
- invalidateHwcGeometry();
- repaintEverything();
+ updateColorMatrixLocked();
return NO_ERROR;
}
// This is an experimental interface
@@ -4641,10 +4743,10 @@
return NO_ERROR;
}
case 1022: { // Set saturation boost
+ Mutex::Autolock _l(mStateLock);
mGlobalSaturationFactor = std::max(0.0f, std::min(data.readFloat(), 2.0f));
- invalidateHwcGeometry();
- repaintEverything();
+ updateColorMatrixLocked();
return NO_ERROR;
}
case 1023: { // Set native mode
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3152a4e..4bb86c5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -375,6 +375,10 @@
// always uses the Drawing StateSet.
layersSortedByZ = other.layersSortedByZ;
displays = other.displays;
+ colorMatrixChanged = other.colorMatrixChanged;
+ if (colorMatrixChanged) {
+ colorMatrix = other.colorMatrix;
+ }
return *this;
}
@@ -382,6 +386,9 @@
LayerVector layersSortedByZ;
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
+ bool colorMatrixChanged = true;
+ mat4 colorMatrix;
+
void traverseInZOrder(const LayerVector::Visitor& visitor) const;
void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;
};
@@ -476,7 +483,8 @@
// Called on the main thread in response to setActiveColorMode()
void setActiveColorModeInternal(const sp<DisplayDevice>& hw,
ui::ColorMode colorMode,
- ui::Dataspace dataSpace);
+ ui::Dataspace dataSpace,
+ ui::RenderIntent renderIntent);
// Returns whether the transaction actually modified any state
bool handleMessageTransaction();
@@ -648,14 +656,18 @@
nsecs_t compositeToPresentLatency);
void rebuildLayerStacks();
- // Given a dataSpace, returns the appropriate color_mode to use
- // to display that dataSpace.
- ui::Dataspace getBestDataspace(const sp<const DisplayDevice>& displayDevice) const;
+ ui::Dataspace getBestDataspace(const sp<const DisplayDevice>& displayDevice,
+ ui::Dataspace* outHdrDataSpace) const;
+
+ // Returns the appropriate ColorMode, Dataspace and RenderIntent for the
+ // DisplayDevice. The function only returns the supported ColorMode,
+ // Dataspace and RenderIntent.
void pickColorMode(const sp<DisplayDevice>& displayDevice,
ui::ColorMode* outMode,
- ui::Dataspace* outDataSpace) const;
-
- mat4 computeSaturationMatrix() const;
+ ui::Dataspace* outDataSpace,
+ ui::RenderIntent* outRenderIntent) const;
+ ui::RenderIntent pickRenderIntent(const sp<DisplayDevice>& displayDevice,
+ ui::ColorMode colorMode) const;
void setUpHWComposer();
void doComposition();
@@ -744,6 +756,8 @@
// Check to see if we should handoff to vr flinger.
void updateVrFlinger();
+ void updateColorMatrixLocked();
+
/* ------------------------------------------------------------------------
* Attributes
*/
@@ -757,6 +771,11 @@
bool mAnimTransactionPending;
SortedVector< sp<Layer> > mLayersPendingRemoval;
+ // global color transform states
+ Daltonizer mDaltonizer;
+ float mGlobalSaturationFactor = 1.0f;
+ mat4 mClientColorMatrix;
+
// Can't be unordered_set because wp<> isn't hashable
std::set<wp<IBinder>> mGraphicBufferProducerList;
size_t mMaxGraphicBufferProducerListSize = MAX_LAYERS;
@@ -847,12 +866,6 @@
bool mInjectVSyncs;
- Daltonizer mDaltonizer;
-
- mat4 mPreviousColorMatrix;
- mat4 mColorMatrix;
- bool mHasColorMatrix;
-
// Static screen stats
bool mHasPoweredOff;
@@ -870,8 +883,6 @@
DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::MANAGED;
// Applied on sRGB layers when the render intent is non-colorimetric.
mat4 mLegacySrgbSaturationMatrix;
- // Applied globally.
- float mGlobalSaturationFactor = 1.0f;
bool mBuiltinDisplaySupportsEnhance = false;
using CreateBufferQueueFunction =
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index 5f2dd32..a6833a5 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -87,15 +87,12 @@
timeStats.totalFrames++;
}
-void TimeStats::incrementMissedFrames(bool propagateBackpressure) {
+void TimeStats::incrementMissedFrames() {
if (!mEnabled.load()) return;
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mMutex);
- if (propagateBackpressure) {
- timeStats.totalFrames--;
- }
timeStats.missedFrames++;
}
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 2410265..f76a62e 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -64,7 +64,7 @@
static TimeStats& getInstance();
void parseArgs(bool asProto, const Vector<String16>& args, size_t& index, String8& result);
void incrementTotalFrames();
- void incrementMissedFrames(bool propagateBackpressure);
+ void incrementMissedFrames();
void incrementClientCompositionFrames();
void setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime);
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index ec0570d..3e5007c 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -129,8 +129,8 @@
for (auto ele : deltas) {
SFTimeStatsDeltaProto* deltaProto = layerProto.add_deltas();
deltaProto->set_delta_name(ele.first);
- SFTimeStatsHistogramBucketProto* histProto = deltaProto->add_histograms();
for (auto histEle : ele.second.hist) {
+ SFTimeStatsHistogramBucketProto* histProto = deltaProto->add_histograms();
histProto->set_render_millis(histEle.first);
histProto->set_frame_count(histEle.second);
}
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 4aa1f50..0bd0e4a 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -47,10 +47,10 @@
using android::hardware::graphics::common::V1_0::Hdr;
using android::hardware::graphics::common::V1_1::ColorMode;
+using android::hardware::graphics::common::V1_1::RenderIntent;
using android::Hwc2::Error;
using android::Hwc2::IComposer;
using android::Hwc2::IComposerClient;
-using android::Hwc2::RenderIntent;
using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
@@ -496,33 +496,6 @@
}
};
-// For this variant, SurfaceFlinger should configure itself with wide color
-// display support, and the display should respond with an non-empty list of
-// supported color modes.
-template <typename Display>
-struct WideColorP3EnhanceSupportedVariant {
- static constexpr bool WIDE_COLOR_SUPPORTED = true;
-
- static void injectConfigChange(DisplayTransactionTest* test) {
- test->mFlinger.mutableHasWideColorDisplay() = true;
- test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::ENHANCED;
- }
-
- static void setupComposerCallExpectations(DisplayTransactionTest* test) {
- EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
- Return(Error::NONE)));
- EXPECT_CALL(*test->mComposer,
- getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
- .WillOnce(
- DoAll(SetArgPointee<2>(std::vector<RenderIntent>({RenderIntent::ENHANCE})),
- Return(Error::NONE)));
- EXPECT_CALL(*test->mComposer,
- setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB, RenderIntent::ENHANCE))
- .WillOnce(Return(Error::NONE));
- }
-};
-
// For this variant, SurfaceFlinger should configure itself with wide display
// support, but the display should respond with an empty list of supported color
// modes. Wide-color support for the display should not be configured.
@@ -640,9 +613,6 @@
using WideColorP3ColorimetricDisplayCase =
Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
HdrNotSupportedVariant<PrimaryDisplayVariant>>;
-using WideColorP3EnhanceDisplayCase =
- Case<PrimaryDisplayVariant, WideColorP3EnhanceSupportedVariant<PrimaryDisplayVariant>,
- HdrNotSupportedVariant<PrimaryDisplayVariant>>;
using Hdr10DisplayCase =
Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Hdr10SupportedVariant<PrimaryDisplayVariant>>;
@@ -1048,10 +1018,6 @@
setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
}
-TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3EnhanceDisplay) {
- setupNewDisplayDeviceInternalTest<WideColorP3EnhanceDisplayCase>();
-}
-
TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index eeabf28..7a0301d 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -289,10 +289,12 @@
}
sp<DisplayDevice> inject() {
+ std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hdrAndRenderIntents;
sp<DisplayDevice> device =
new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, mSecure, mDisplayToken,
mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
- 0, false, HdrCapabilities(), 0, HWC_POWER_MODE_NORMAL);
+ 0, false, HdrCapabilities(), 0, hdrAndRenderIntents,
+ HWC_POWER_MODE_NORMAL);
mFlinger.mutableDisplays().add(mDisplayToken, device);
DisplayDeviceState state;
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 29cd2d5..93769a5 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -60,7 +60,7 @@
MOCK_METHOD1(setupLayerTexturing, void(const Texture&));
MOCK_METHOD0(setupLayerBlackedOut, void());
MOCK_METHOD4(setupFillWithColor, void(float, float, float, float));
- MOCK_METHOD1(setupColorTransform, mat4(const mat4&));
+ MOCK_METHOD1(setupColorTransform, void(const mat4&));
MOCK_METHOD0(disableTexturing, void());
MOCK_METHOD0(disableBlending, void());
MOCK_METHOD1(setSourceY410BT2020, void(bool));