Merge "Use the primaryDisplayRotationFlags for the source crop calculation" into tm-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 397d432..b4aa88e 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -2976,13 +2976,15 @@
// Dumps the contents of a profile file, using pkgname's dex files for pretty
// printing the result.
binder::Status InstalldNativeService::dumpProfiles(int32_t uid, const std::string& packageName,
- const std::string& profileName, const std::string& codePath, bool* _aidl_return) {
+ const std::string& profileName,
+ const std::string& codePath,
+ bool dumpClassesAndMethods, bool* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
CHECK_ARGUMENT_PATH(codePath);
LOCK_PACKAGE();
- *_aidl_return = dump_profiles(uid, packageName, profileName, codePath);
+ *_aidl_return = dump_profiles(uid, packageName, profileName, codePath, dumpClassesAndMethods);
return ok();
}
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 0432222..521afc3 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -134,7 +134,8 @@
binder::Status mergeProfiles(int32_t uid, const std::string& packageName,
const std::string& profileName, int* _aidl_return);
binder::Status dumpProfiles(int32_t uid, const std::string& packageName,
- const std::string& profileName, const std::string& codePath, bool* _aidl_return);
+ const std::string& profileName, const std::string& codePath,
+ bool dumpClassesAndMethods, bool* _aidl_return);
binder::Status copySystemProfile(const std::string& systemProfile,
int32_t uid, const std::string& packageName, const std::string& profileName,
bool* _aidl_return);
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index db03411..9ad853b 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -77,7 +77,7 @@
int mergeProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String profileName);
boolean dumpProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String profileName,
- @utf8InCpp String codePath);
+ @utf8InCpp String codePath, boolean dumpClassesAndMethods);
boolean copySystemProfile(@utf8InCpp String systemProfile, int uid,
@utf8InCpp String packageName, @utf8InCpp String profileName);
void clearAppProfiles(@utf8InCpp String packageName, @utf8InCpp String profileName);
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 894c7d3..ebb7891 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -624,12 +624,15 @@
/*for_boot_image*/false);
}
- void SetupDump(const std::vector<unique_fd>& profiles_fd,
- const unique_fd& reference_profile_fd,
+ void SetupDump(const std::vector<unique_fd>& profiles_fd, const unique_fd& reference_profile_fd,
const std::vector<std::string>& dex_locations,
- const std::vector<unique_fd>& apk_fds,
+ const std::vector<unique_fd>& apk_fds, bool dump_classes_and_methods,
const unique_fd& output_fd) {
- AddArg("--dump-only");
+ if (dump_classes_and_methods) {
+ AddArg("--dump-classes-and-methods");
+ } else {
+ AddArg("--dump-only");
+ }
AddArg(StringPrintf("--dump-output-to-fd=%d", output_fd.get()));
SetupArgs(profiles_fd,
reference_profile_fd,
@@ -772,7 +775,7 @@
}
bool dump_profiles(int32_t uid, const std::string& pkgname, const std::string& profile_name,
- const std::string& code_path) {
+ const std::string& code_path, bool dump_classes_and_methods) {
std::vector<unique_fd> profile_fds;
unique_fd reference_profile_fd;
std::string out_file_name = StringPrintf("/data/misc/profman/%s-%s.txt",
@@ -808,7 +811,8 @@
RunProfman profman_dump;
- profman_dump.SetupDump(profile_fds, reference_profile_fd, dex_locations, apk_fds, output_fd);
+ profman_dump.SetupDump(profile_fds, reference_profile_fd, dex_locations, apk_fds,
+ dump_classes_and_methods, output_fd);
pid_t pid = fork();
if (pid == 0) {
/* child -- drop privileges before continuing */
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index f7af929..5cf402c 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -88,10 +88,8 @@
const std::string& profile_name,
const std::string& classpath);
-bool dump_profiles(int32_t uid,
- const std::string& pkgname,
- const std::string& profile_name,
- const std::string& code_path);
+bool dump_profiles(int32_t uid, const std::string& pkgname, const std::string& profile_name,
+ const std::string& code_path, bool dump_classes_and_methods);
bool copy_system_profile(const std::string& system_profile,
uid_t packageUid,
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index aaa812b..6b31812 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -77,7 +77,7 @@
* have
*/
[[nodiscard]] status_t setupInetServer(const char* address, unsigned int port,
- unsigned int* assignedPort);
+ unsigned int* assignedPort = nullptr);
/**
* If setup*Server has been successful, return true. Otherwise return false.
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 1d4fc1f..5d7874a 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -103,9 +103,6 @@
sanitize: {
misc_undefined: ["integer"],
- diag: {
- misc_undefined: ["integer"],
- },
},
},
host: {
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index bf50644..a5e0879 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/graphics/composer3/DimmingStage.h>
+#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
#include <iosfwd>
#include <math/mat4.h>
@@ -73,6 +74,10 @@
// Configures when dimming should be applied for each layer.
aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage =
aidl::android::hardware::graphics::composer3::DimmingStage::NONE;
+
+ // Configures the rendering intent of the output display. This is used for tonemapping.
+ aidl::android::hardware::graphics::composer3::RenderIntent renderIntent =
+ aidl::android::hardware::graphics::composer3::RenderIntent::TONE_MAP_COLORIMETRIC;
};
static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index a3a1969..5c137a4 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -96,7 +96,6 @@
.alpha = 1,
};
- auto layers = std::vector<LayerSettings>{layer, caster};
// Four combinations of settings are used (two transforms here, and drawShadowLayers is
// called with two different destination data spaces) They're all rounded rect.
// Three of these are cache misses that generate new shaders.
@@ -115,6 +114,8 @@
for (auto transform : {mat4(), kFlip}) {
layer.geometry.positionTransform = transform;
caster.geometry.positionTransform = transform;
+
+ auto layers = std::vector<LayerSettings>{layer, caster};
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd());
}
@@ -141,7 +142,6 @@
}},
};
- auto layers = std::vector<LayerSettings>{layer};
for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
layer.sourceDataspace = dataspace;
// Cache shaders for both rects and round rects.
@@ -153,6 +153,7 @@
layer.source.buffer.isOpaque = isOpaque;
for (auto alpha : {half(.2f), half(1.0f)}) {
layer.alpha = alpha;
+ auto layers = std::vector<LayerSettings>{layer};
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd());
}
@@ -177,11 +178,11 @@
.alpha = 0.5,
};
- auto layers = std::vector<LayerSettings>{layer};
for (auto transform : {mat4(), kScaleAndTranslate}) {
layer.geometry.positionTransform = transform;
for (float roundedCornersRadius : {0.0f, 50.f}) {
layer.geometry.roundedCornersRadius = roundedCornersRadius;
+ auto layers = std::vector<LayerSettings>{layer};
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd());
}
@@ -202,10 +203,10 @@
.skipContentDraw = true,
};
- auto layers = std::vector<LayerSettings>{layer};
// Different blur code is invoked for radii less and greater than 30 pixels
for (int radius : {9, 60}) {
layer.backgroundBlurRadius = radius;
+ auto layers = std::vector<LayerSettings>{layer};
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd());
}
@@ -243,7 +244,6 @@
},
};
- auto layers = std::vector<LayerSettings>{layer};
for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) {
layer.source = pixelSource;
for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
@@ -252,7 +252,8 @@
for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) {
layer.geometry.positionTransform = transform;
for (float alpha : {0.5f, 1.f}) {
- layer.alpha = alpha,
+ layer.alpha = alpha;
+ auto layers = std::vector<LayerSettings>{layer};
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
base::unique_fd());
}
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index a77a798..f440f4a 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -292,6 +292,8 @@
void SkiaGLRenderEngine::SkSLCacheMonitor::store(const SkData& key, const SkData& data,
const SkString& description) {
mShadersCachedSinceLastCall++;
+ mTotalShadersCompiled++;
+ ATRACE_FORMAT("SF cache: %i shaders", mTotalShadersCompiled);
}
void SkiaGLRenderEngine::assertShadersCompiled(int numShaders) {
@@ -662,7 +664,7 @@
parameters.display.maxLuminance,
parameters.display.currentLuminanceNits,
parameters.layer.source.buffer.maxLuminanceNits,
- hardwareBuffer);
+ hardwareBuffer, parameters.display.renderIntent);
}
return parameters.shader;
}
@@ -1190,11 +1192,15 @@
static constexpr float kInverseGamma22 = 1.f / 2.2f;
const auto gammaCorrectedDimmingRatio =
std::pow(layerDimmingRatio, kInverseGamma22);
- const auto dimmingMatrix =
+ auto dimmingMatrix =
mat4::scale(vec4(gammaCorrectedDimmingRatio, gammaCorrectedDimmingRatio,
gammaCorrectedDimmingRatio, 1.f));
- paint.setColorFilter(SkColorFilters::Matrix(
- toSkColorMatrix(display.colorTransform * dimmingMatrix)));
+
+ const auto colorFilter =
+ SkColorFilters::Matrix(toSkColorMatrix(std::move(dimmingMatrix)));
+ paint.setColorFilter(displayColorTransform
+ ? displayColorTransform->makeComposed(colorFilter)
+ : colorFilter);
} else {
paint.setColorFilter(displayColorTransform);
}
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index a650313..56815fe 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -180,6 +180,7 @@
private:
int mShadersCachedSinceLastCall = 0;
+ int mTotalShadersCompiled = 0;
};
SkSLCacheMonitor mSkSLCacheMonitor;
diff --git a/libs/renderengine/skia/filters/LinearEffect.cpp b/libs/renderengine/skia/filters/LinearEffect.cpp
index d479606..f7dcd3a 100644
--- a/libs/renderengine/skia/filters/LinearEffect.cpp
+++ b/libs/renderengine/skia/filters/LinearEffect.cpp
@@ -40,12 +40,11 @@
return shader;
}
-sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> shader,
- const shaders::LinearEffect& linearEffect,
- sk_sp<SkRuntimeEffect> runtimeEffect,
- const mat4& colorTransform, float maxDisplayLuminance,
- float currentDisplayLuminanceNits, float maxLuminance,
- AHardwareBuffer* buffer) {
+sk_sp<SkShader> createLinearEffectShader(
+ sk_sp<SkShader> shader, const shaders::LinearEffect& linearEffect,
+ sk_sp<SkRuntimeEffect> runtimeEffect, const mat4& colorTransform, float maxDisplayLuminance,
+ float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
+ aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
ATRACE_CALL();
SkRuntimeShaderBuilder effectBuilder(runtimeEffect);
@@ -53,7 +52,8 @@
const auto uniforms =
shaders::buildLinearEffectUniforms(linearEffect, colorTransform, maxDisplayLuminance,
- currentDisplayLuminanceNits, maxLuminance, buffer);
+ currentDisplayLuminanceNits, maxLuminance, buffer,
+ renderIntent);
for (const auto& uniform : uniforms) {
effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size());
diff --git a/libs/renderengine/skia/filters/LinearEffect.h b/libs/renderengine/skia/filters/LinearEffect.h
index 26bae3b..3c66c51 100644
--- a/libs/renderengine/skia/filters/LinearEffect.h
+++ b/libs/renderengine/skia/filters/LinearEffect.h
@@ -42,12 +42,13 @@
// or as the max light level from the CTA 861.3 standard.
// * An AHardwareBuffer for implementations that support gralloc4 metadata for
// communicating any HDR metadata.
-sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> inputShader,
- const shaders::LinearEffect& linearEffect,
- sk_sp<SkRuntimeEffect> runtimeEffect,
- const mat4& colorTransform, float maxDisplayLuminance,
- float currentDisplayLuminanceNits, float maxLuminance,
- AHardwareBuffer* buffer);
+// * A RenderIntent that communicates the downstream renderintent for a physical display, for image
+// quality compensation.
+sk_sp<SkShader> createLinearEffectShader(
+ sk_sp<SkShader> inputShader, const shaders::LinearEffect& linearEffect,
+ sk_sp<SkRuntimeEffect> runtimeEffect, const mat4& colorTransform, float maxDisplayLuminance,
+ float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
+ aidl::android::hardware::graphics::composer3::RenderIntent renderIntent);
} // namespace skia
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 2493242..31598e3 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -91,6 +91,14 @@
sign(linear.b) * OETF_sRGB(linear.b));
}
+// clang-format off
+// Converts red channels to green channels, and zeroes out an existing green channel.
+static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1);
+// clang-format on
+
} // namespace
class RenderEngineFactory {
@@ -2557,6 +2565,133 @@
expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
}
+TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
+ if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
+ GTEST_SKIP();
+ }
+ initializeRenderEngine();
+
+ const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
+ ui::Dataspace::TRANSFER_GAMMA2_2 |
+ ui::Dataspace::RANGE_FULL);
+
+ const auto displayRect = Rect(3, 1);
+ const renderengine::DisplaySettings display{
+ .physicalDisplay = displayRect,
+ .clip = displayRect,
+ .outputDataspace = dataspace,
+ .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
+ .targetLuminanceNits = 1000.f,
+ .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+ };
+
+ const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
+ const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
+ const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
+
+ const renderengine::LayerSettings greenLayer{
+ .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
+ .source =
+ renderengine::PixelSource{
+ .buffer =
+ renderengine::Buffer{
+ .buffer = greenBuffer,
+ .usePremultipliedAlpha = true,
+ },
+ },
+ .alpha = 1.0f,
+ .sourceDataspace = dataspace,
+ .whitePointNits = 200.f,
+ };
+
+ const renderengine::LayerSettings redLayer{
+ .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
+ .source =
+ renderengine::PixelSource{
+ .buffer =
+ renderengine::Buffer{
+ .buffer = redBuffer,
+ .usePremultipliedAlpha = true,
+ },
+ },
+ .alpha = 1.0f,
+ .sourceDataspace = dataspace,
+ // When the white point is not set for a layer, just ignore it and treat it as the same
+ // as the max layer
+ .whitePointNits = -1.f,
+ };
+
+ std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
+ invokeDraw(display, layers);
+
+ expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
+ expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
+}
+
+TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
+ if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
+ GTEST_SKIP();
+ }
+ initializeRenderEngine();
+
+ const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
+ ui::Dataspace::TRANSFER_GAMMA2_2 |
+ ui::Dataspace::RANGE_FULL);
+
+ const auto displayRect = Rect(3, 1);
+ const renderengine::DisplaySettings display{
+ .physicalDisplay = displayRect,
+ .clip = displayRect,
+ .outputDataspace = dataspace,
+ .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
+ .deviceHandlesColorTransform = true,
+ .targetLuminanceNits = 1000.f,
+ .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+ };
+
+ const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
+ const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
+ const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
+
+ const renderengine::LayerSettings greenLayer{
+ .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
+ .source =
+ renderengine::PixelSource{
+ .buffer =
+ renderengine::Buffer{
+ .buffer = greenBuffer,
+ .usePremultipliedAlpha = true,
+ },
+ },
+ .alpha = 1.0f,
+ .sourceDataspace = dataspace,
+ .whitePointNits = 200.f,
+ };
+
+ const renderengine::LayerSettings redLayer{
+ .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
+ .source =
+ renderengine::PixelSource{
+ .buffer =
+ renderengine::Buffer{
+ .buffer = redBuffer,
+ .usePremultipliedAlpha = true,
+ },
+ },
+ .alpha = 1.0f,
+ .sourceDataspace = dataspace,
+ // When the white point is not set for a layer, just ignore it and treat it as the same
+ // as the max layer
+ .whitePointNits = -1.f,
+ };
+
+ std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
+ invokeDraw(display, layers);
+
+ expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
+ expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
+}
+
TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
initializeRenderEngine();
if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
@@ -2796,10 +2931,7 @@
// pure red to pure green. That will occur when the R8 buffer is
// 255. When the R8 buffer is 0, it will still change to black, as
// with r8_behaves_as_mask.
- .colorTransform = mat4(0, 1, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1),
+ .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
.deviceHandlesColorTransform = false,
};
diff --git a/libs/shaders/Android.bp b/libs/shaders/Android.bp
index 2f8bf49..6b936de 100644
--- a/libs/shaders/Android.bp
+++ b/libs/shaders/Android.bp
@@ -29,6 +29,7 @@
shared_libs: [
"android.hardware.graphics.common-V3-ndk",
+ "android.hardware.graphics.composer3-V1-ndk",
"android.hardware.graphics.common@1.2",
"libnativewindow",
],
diff --git a/libs/shaders/include/shaders/shaders.h b/libs/shaders/include/shaders/shaders.h
index 4ec7594..2a4a370 100644
--- a/libs/shaders/include/shaders/shaders.h
+++ b/libs/shaders/include/shaders/shaders.h
@@ -97,11 +97,10 @@
std::string buildLinearEffectSkSL(const LinearEffect& linearEffect);
// Generates a list of uniforms to set on the LinearEffect shader above.
-std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
- const mat4& colorTransform,
- float maxDisplayLuminance,
- float currentDisplayLuminanceNits,
- float maxLuminance,
- AHardwareBuffer* buffer = nullptr);
+std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(
+ const LinearEffect& linearEffect, const mat4& colorTransform, float maxDisplayLuminance,
+ float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer = nullptr,
+ aidl::android::hardware::graphics::composer3::RenderIntent renderIntent =
+ aidl::android::hardware::graphics::composer3::RenderIntent::TONE_MAP_COLORIMETRIC);
} // namespace android::shaders
diff --git a/libs/shaders/shaders.cpp b/libs/shaders/shaders.cpp
index 5935589..f0d45c2 100644
--- a/libs/shaders/shaders.cpp
+++ b/libs/shaders/shaders.cpp
@@ -464,12 +464,10 @@
}
// Generates a list of uniforms to set on the LinearEffect shader above.
-std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(const LinearEffect& linearEffect,
- const mat4& colorTransform,
- float maxDisplayLuminance,
- float currentDisplayLuminanceNits,
- float maxLuminance,
- AHardwareBuffer* buffer) {
+std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(
+ const LinearEffect& linearEffect, const mat4& colorTransform, float maxDisplayLuminance,
+ float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
+ aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
std::vector<tonemap::ShaderUniform> uniforms;
if (linearEffect.inputDataspace == linearEffect.outputDataspace) {
uniforms.push_back({.name = "in_rgbToXyz", .value = buildUniformValue<mat4>(mat4())});
@@ -495,7 +493,8 @@
.currentDisplayLuminance = currentDisplayLuminanceNits > 0
? currentDisplayLuminanceNits
: maxDisplayLuminance,
- .buffer = buffer};
+ .buffer = buffer,
+ .renderIntent = renderIntent};
for (const auto uniform : tonemap::getToneMapper()->generateShaderSkSLUniforms(metadata)) {
uniforms.push_back(uniform);
diff --git a/libs/tonemap/Android.bp b/libs/tonemap/Android.bp
index dc55586..37c9824 100644
--- a/libs/tonemap/Android.bp
+++ b/libs/tonemap/Android.bp
@@ -29,6 +29,7 @@
shared_libs: [
"android.hardware.graphics.common-V3-ndk",
+ "android.hardware.graphics.composer3-V1-ndk",
"liblog",
"libnativewindow",
],
diff --git a/libs/tonemap/include/tonemap/tonemap.h b/libs/tonemap/include/tonemap/tonemap.h
index c51016d..852fc87 100644
--- a/libs/tonemap/include/tonemap/tonemap.h
+++ b/libs/tonemap/include/tonemap/tonemap.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
#include <android/hardware_buffer.h>
#include <math/vec3.h>
@@ -41,7 +42,7 @@
// Describes metadata which may be used for constructing the shader uniforms.
// This metadata should not be used for manipulating the source code of the shader program directly,
-// as otherwise caching by other system of these shaders may break.
+// as otherwise caching by other parts of the system using these shaders may break.
struct Metadata {
// The maximum luminance of the display in nits
float displayMaxLuminance = 0.0;
@@ -61,6 +62,17 @@
// texture that does not have associated metadata. As such, implementations
// must support nullptr.
AHardwareBuffer* buffer = nullptr;
+
+ // RenderIntent of the destination display.
+ // Non-colorimetric render-intents may be defined in order to take advantage of the full display
+ // gamut. Various contrast-enhancement mechanisms may be employed on SDR content as a result,
+ // which means that HDR content may need to be compensated in order to achieve correct blending
+ // behavior. This default is effectively optional - the display render intent may not be
+ // available to clients such as HWUI which are display-agnostic. For those clients, tone-map
+ // colorimetric may be assumed so that the luminance range may be converted to the correct range
+ // based on the output dataspace.
+ aidl::android::hardware::graphics::composer3::RenderIntent renderIntent =
+ aidl::android::hardware::graphics::composer3::RenderIntent::TONE_MAP_COLORIMETRIC;
};
// Utility class containing pre-processed conversions for a particular color
diff --git a/libs/tonemap/tests/Android.bp b/libs/tonemap/tests/Android.bp
index 26a1d79..58851b4 100644
--- a/libs/tonemap/tests/Android.bp
+++ b/libs/tonemap/tests/Android.bp
@@ -32,6 +32,7 @@
],
shared_libs: [
"android.hardware.graphics.common-V3-ndk",
+ "android.hardware.graphics.composer3-V1-ndk",
"libnativewindow",
],
static_libs: [
diff --git a/libs/ui/DeviceProductInfo.cpp b/libs/ui/DeviceProductInfo.cpp
index 4d6ce43..04d9d3c 100644
--- a/libs/ui/DeviceProductInfo.cpp
+++ b/libs/ui/DeviceProductInfo.cpp
@@ -57,7 +57,7 @@
}
void DeviceProductInfo::dump(std::string& result) const {
- StringAppendF(&result, "{name=%s, ", name.c_str());
+ StringAppendF(&result, "{name=\"%s\", ", name.c_str());
StringAppendF(&result, "manufacturerPnpId=%s, ", manufacturerPnpId.data());
StringAppendF(&result, "productId=%s, ", productId.c_str());
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index 1fce31d..f6ab7b2 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -1193,10 +1193,6 @@
Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
mAllocator = IAllocator::getService();
- if (mAllocator == nullptr) {
- ALOGW("allocator 4.x is not supported");
- return;
- }
if (__builtin_available(android 31, *)) {
if (hasIAllocatorAidl()) {
mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder(
@@ -1204,10 +1200,14 @@
ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service");
}
}
+ if (mAllocator == nullptr && mAidlAllocator == nullptr) {
+ ALOGW("allocator 4.x is not supported");
+ return;
+ }
}
bool Gralloc4Allocator::isLoaded() const {
- return mAllocator != nullptr;
+ return mAllocator != nullptr || mAidlAllocator != nullptr;
}
std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
@@ -1245,8 +1245,9 @@
} else {
if (importBuffers) {
for (uint32_t i = 0; i < bufferCount; i++) {
- error = mMapper.importBuffer(makeFromAidl(result.buffers[i]),
- &outBufferHandles[i]);
+ auto handle = makeFromAidl(result.buffers[i]);
+ error = mMapper.importBuffer(handle, &outBufferHandles[i]);
+ native_handle_delete(handle);
if (error != NO_ERROR) {
for (uint32_t j = 0; j < i; j++) {
mMapper.freeBuffer(outBufferHandles[j]);
diff --git a/libs/ui/include/ui/Size.h b/libs/ui/include/ui/Size.h
index ecc192d..bdcbd56 100644
--- a/libs/ui/include/ui/Size.h
+++ b/libs/ui/include/ui/Size.h
@@ -23,6 +23,8 @@
#include <type_traits>
#include <utility>
+#include <ui/Rotation.h>
+
namespace android::ui {
// A simple value type representing a two-dimensional size.
@@ -61,6 +63,16 @@
set(Size(w, h));
}
+ // Applies a rotation onto the size
+ void rotate(Rotation rotation) {
+ if (rotation == ROTATION_90 || rotation == ROTATION_270) {
+ transpose();
+ }
+ }
+
+ // Swaps the width and height, emulating a 90 degree rotation.
+ void transpose() { std::swap(width, height); }
+
// Sets the value to kInvalidSize
void makeInvalid();
diff --git a/libs/ui/tests/Size_test.cpp b/libs/ui/tests/Size_test.cpp
index acef47f..0a236e6 100644
--- a/libs/ui/tests/Size_test.cpp
+++ b/libs/ui/tests/Size_test.cpp
@@ -61,6 +61,38 @@
EXPECT_FALSE(Size(1, 1) < Size(1, 1));
}
+TEST(SizeTest, Transpose) {
+ Size s(123, 456);
+ s.transpose();
+ EXPECT_EQ(s, Size(456, 123));
+}
+
+TEST(SizeTest, Rotate) {
+ {
+ Size s(123, 456);
+ s.rotate(Rotation::Rotation0);
+ EXPECT_EQ(s, Size(123, 456));
+ }
+
+ {
+ Size s(123, 456);
+ s.rotate(Rotation::Rotation90);
+ EXPECT_EQ(s, Size(456, 123));
+ }
+
+ {
+ Size s(123, 456);
+ s.rotate(Rotation::Rotation180);
+ EXPECT_EQ(s, Size(123, 456));
+ }
+
+ {
+ Size s(123, 456);
+ s.rotate(Rotation::Rotation270);
+ EXPECT_EQ(s, Size(456, 123));
+ }
+}
+
TEST(SizeTest, ValidAndEmpty) {
{
Size s;
diff --git a/libs/vr/libbroadcastring/Android.bp b/libs/vr/libbroadcastring/Android.bp
index d4538f1..fa449ae 100644
--- a/libs/vr/libbroadcastring/Android.bp
+++ b/libs/vr/libbroadcastring/Android.bp
@@ -9,7 +9,7 @@
cc_library_static {
name: "libbroadcastring",
- clang: true,
+
cflags: [
"-Wall",
"-Wextra",
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index a9a4c71..dc5fcec 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -27,9 +27,6 @@
namespace android {
-// The default velocity control parameters that has no effect.
-static const VelocityControlParameters FLAT_VELOCITY_CONTROL_PARAMS{};
-
// --- CursorMotionAccumulator ---
CursorMotionAccumulator::CursorMotionAccumulator() {
@@ -157,9 +154,8 @@
mHWheelScale = 1.0f;
}
- const bool configurePointerCapture = (!changes && config->pointerCaptureRequest.enable) ||
- (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
- if (configurePointerCapture) {
+ if ((!changes && config->pointerCaptureRequest.enable) ||
+ (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) {
if (config->pointerCaptureRequest.enable) {
if (mParameters.mode == Parameters::MODE_POINTER) {
mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
@@ -184,18 +180,10 @@
}
}
- if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED) ||
- configurePointerCapture) {
- if (config->pointerCaptureRequest.enable) {
- // Disable any acceleration or scaling when Pointer Capture is enabled.
- mPointerVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
- mWheelXVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
- mWheelYVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
- } else {
- mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
- mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
- mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
- }
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
+ mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
+ mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index b29a0a2..bda7755 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -375,11 +375,6 @@
float getPointerGestureMovementSpeedRatio() { return mConfig.pointerGestureMovementSpeedRatio; }
- void setVelocityControlParams(const VelocityControlParameters& params) {
- mConfig.pointerVelocityControlParameters = params;
- mConfig.wheelVelocityControlParameters = params;
- }
-
private:
uint32_t mNextPointerCaptureSequenceNumber = 0;
@@ -2954,10 +2949,7 @@
}
void configureDevice(uint32_t changes) {
- if (!changes ||
- (changes &
- (InputReaderConfiguration::CHANGE_DISPLAY_INFO |
- InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) {
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
mReader->requestRefreshConfiguration(changes);
mReader->loopOnce();
}
@@ -4922,54 +4914,6 @@
ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
}
-/**
- * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
- * pointer acceleration or speed processing should not be applied.
- */
-TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
- addConfigurationProperty("cursor.mode", "pointer");
- const VelocityControlParameters testParams(5.f /*scale*/, 0.f /*low threshold*/,
- 100.f /*high threshold*/, 10.f /*acceleration*/);
- mFakePolicy->setVelocityControlParams(testParams);
- CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
-
- NotifyDeviceResetArgs resetArgs;
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
- ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
- ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
-
- NotifyMotionArgs args;
-
- // Move and verify scale is applied.
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
- ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
- ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
- const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
- const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
- ASSERT_GT(relX, 10);
- ASSERT_GT(relY, 20);
-
- // Enable Pointer Capture
- mFakePolicy->setPointerCapture(true);
- configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
- NotifyPointerCaptureChangedArgs captureArgs;
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
- ASSERT_TRUE(captureArgs.request.enable);
-
- // Move and verify scale is not applied.
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
- ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
- ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
- ASSERT_EQ(10, args.pointerCoords[0].getX());
- ASSERT_EQ(20, args.pointerCoords[0].getY());
-}
-
TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h
index a63145a..49013e0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h
@@ -120,16 +120,16 @@
} // namespace compositionengine
-inline std::string to_string(const android::compositionengine::ProjectionSpace& space) {
- return android::base::
- StringPrintf("ProjectionSpace(bounds = %s, content = %s, orientation = %s)",
- to_string(space.getBoundsAsRect()).c_str(),
- to_string(space.getContent()).c_str(), toCString(space.getOrientation()));
+inline std::string to_string(const compositionengine::ProjectionSpace& space) {
+ return base::StringPrintf("ProjectionSpace{bounds=%s, content=%s, orientation=%s}",
+ to_string(space.getBoundsAsRect()).c_str(),
+ to_string(space.getContent()).c_str(),
+ toCString(space.getOrientation()));
}
// Defining PrintTo helps with Google Tests.
-inline void PrintTo(const android::compositionengine::ProjectionSpace& space, ::std::ostream* os) {
+inline void PrintTo(const compositionengine::ProjectionSpace& space, std::ostream* os) {
*os << to_string(space);
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index 5fa0d67..61be983 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -155,6 +155,8 @@
SUCCESS = 1,
// Composition strategy prediction failed for this frame.
FAIL = 2,
+
+ ftl_last = FAIL
};
CompositionStrategyPredictionState strategyPrediction =
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index f545886..b79b46b 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -131,15 +131,11 @@
}
void Display::dump(std::string& out) const {
- using android::base::StringAppendF;
+ const char* const type = isVirtual() ? "virtual" : "physical";
+ base::StringAppendF(&out, "Display %s (%s, \"%s\")", to_string(mId).c_str(), type,
+ getName().c_str());
- StringAppendF(&out, " Composition Display State: [\"%s\"]", getName().c_str());
-
- out.append("\n ");
- dumpVal(out, "isVirtual", isVirtual());
- dumpVal(out, "DisplayId", to_string(mId));
- out.append("\n");
-
+ out.append("\n Composition Display State:\n");
Output::dumpBase(out);
}
diff --git a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
index 01c368d..290c710 100644
--- a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
@@ -89,7 +89,6 @@
void dumpVal(std::string& out, const char* name, const ui::Transform& transform) {
transform.dump(out, name);
- out.append(" ");
}
void dumpVal(std::string& out, const char* name, const mat4& tr) {
@@ -99,7 +98,7 @@
"[%0.3f,%0.3f,%0.3f,%0.3f]"
"[%0.3f,%0.3f,%0.3f,%0.3f]"
"[%0.3f,%0.3f,%0.3f,%0.3f]"
- "[%0.3f,%0.3f,%0.3f,%0.3f]]",
+ "[%0.3f,%0.3f,%0.3f,%0.3f]] ",
name,
tr[0][0], tr[1][0], tr[2][0], tr[3][0],
tr[0][1], tr[1][1], tr[2][1], tr[3][1],
@@ -109,9 +108,9 @@
}
void dumpVal(std::string& out, const char* name, const StretchEffect& effect) {
- StringAppendF(&out, "%s={ width =%f, height = %f, vec=(%f, %f), max=(%f, %f) } ", name,
- effect.width, effect.height,
- effect.vectorX, effect.vectorY, effect.maxAmountX, effect.maxAmountY);
+ StringAppendF(&out, "%s={width=%f, height=%f, vec=(%f, %f), max=(%f, %f)} ", name, effect.width,
+ effect.height, effect.vectorX, effect.vectorY, effect.maxAmountX,
+ effect.maxAmountY);
}
} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index e99b70f..ec86731 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -294,17 +294,15 @@
}
void Output::dump(std::string& out) const {
- using android::base::StringAppendF;
-
- StringAppendF(&out, " Composition Output State: [\"%s\"]", mName.c_str());
-
- out.append("\n ");
+ base::StringAppendF(&out, "Output \"%s\"", mName.c_str());
+ out.append("\n Composition Output State:\n");
dumpBase(out);
}
void Output::dumpBase(std::string& out) const {
dumpState(out);
+ out += '\n';
if (mDisplayColorProfile) {
mDisplayColorProfile->dump(out);
@@ -312,13 +310,15 @@
out.append(" No display color profile!\n");
}
+ out += '\n';
+
if (mRenderSurface) {
mRenderSurface->dump(out);
} else {
out.append(" No render surface!\n");
}
- android::base::StringAppendF(&out, "\n %zu Layers\n", getOutputLayerCount());
+ base::StringAppendF(&out, "\n %zu Layers\n", getOutputLayerCount());
for (const auto* outputLayer : getOutputLayersOrderedByZ()) {
if (!outputLayer) {
continue;
@@ -329,7 +329,7 @@
void Output::dumpPlannerInfo(const Vector<String16>& args, std::string& out) const {
if (!mPlanner) {
- base::StringAppendF(&out, "Planner is disabled\n");
+ out.append("Planner is disabled\n");
return;
}
base::StringAppendF(&out, "Planner info for display [%s]\n", mName.c_str());
@@ -1177,6 +1177,9 @@
clientCompositionDisplay.targetLuminanceNits =
outputState.clientTargetBrightness * outputState.displayBrightnessNits;
clientCompositionDisplay.dimmingStage = outputState.clientTargetDimmingStage;
+ clientCompositionDisplay.renderIntent =
+ static_cast<aidl::android::hardware::graphics::composer3::RenderIntent>(
+ outputState.renderIntent);
// Compute the global color transform matrix.
clientCompositionDisplay.colorTransform = outputState.colorTransformMatrix;
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
index 7188281..3b85e3b 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
@@ -14,40 +14,30 @@
* limitations under the License.
*/
+#include <ftl/enum.h>
+
#include <compositionengine/impl/DumpHelpers.h>
#include <compositionengine/impl/OutputCompositionState.h>
namespace android::compositionengine::impl {
-using CompositionStrategyPredictionState =
- OutputCompositionState::CompositionStrategyPredictionState;
-
-std::string toString(CompositionStrategyPredictionState state) {
- switch (state) {
- case CompositionStrategyPredictionState::DISABLED:
- return "Disabled";
- case CompositionStrategyPredictionState::SUCCESS:
- return "Success";
- case CompositionStrategyPredictionState::FAIL:
- return "Fail";
- }
-}
void OutputCompositionState::dump(std::string& out) const {
out.append(" ");
dumpVal(out, "isEnabled", isEnabled);
dumpVal(out, "isSecure", isSecure);
-
- dumpVal(out, "usesClientComposition", usesClientComposition);
dumpVal(out, "usesDeviceComposition", usesDeviceComposition);
+
+ out.append("\n ");
+ dumpVal(out, "usesClientComposition", usesClientComposition);
dumpVal(out, "flipClientTarget", flipClientTarget);
dumpVal(out, "reusedClientComposition", reusedClientComposition);
- dumpVal(out, "layerFilter", layerFilter);
out.append("\n ");
-
+ dumpVal(out, "layerFilter", layerFilter);
+ out.append("\n ");
dumpVal(out, "transform", transform);
- out.append("\n ");
+ out.append(" "); // ui::Transform::dump appends EOL.
dumpVal(out, "layerStackSpace", to_string(layerStackSpace));
out.append("\n ");
dumpVal(out, "framebufferSpace", to_string(framebufferSpace));
@@ -59,19 +49,24 @@
dumpVal(out, "needsFiltering", needsFiltering);
out.append("\n ");
-
dumpVal(out, "colorMode", toString(colorMode), colorMode);
dumpVal(out, "renderIntent", toString(renderIntent), renderIntent);
dumpVal(out, "dataspace", toString(dataspace), dataspace);
+ dumpVal(out, "targetDataspace", toString(targetDataspace), targetDataspace);
+
+ out.append("\n ");
dumpVal(out, "colorTransformMatrix", colorTransformMatrix);
- dumpVal(out, "target dataspace", toString(targetDataspace), targetDataspace);
+
+ out.append("\n ");
dumpVal(out, "displayBrightnessNits", displayBrightnessNits);
dumpVal(out, "sdrWhitePointNits", sdrWhitePointNits);
dumpVal(out, "clientTargetBrightness", clientTargetBrightness);
dumpVal(out, "displayBrightness", displayBrightness);
- dumpVal(out, "compositionStrategyPredictionState", toString(strategyPrediction));
- out.append("\n");
+ out.append("\n ");
+ dumpVal(out, "compositionStrategyPredictionState", ftl::enum_string(strategyPrediction));
+
+ out += '\n';
}
} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 31a89af..42c8b37 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3711,6 +3711,16 @@
auto withDimmingStage(
aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
+ return nextState<OutputWithRenderIntent>();
+ }
+ };
+
+ struct OutputWithRenderIntent
+ : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
+ auto withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
+ getInstance()->mOutput.mState.renderIntent =
+ static_cast<ui::RenderIntent>(renderIntent);
return nextState<SkipColorTransformState>();
}
};
@@ -3744,6 +3754,8 @@
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kUnknownLuminance)
.withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+ .withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed(
{.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3756,7 +3768,9 @@
.orientation = kDefaultOutputOrientationFlags,
.targetLuminanceNits = kClientTargetLuminanceNits,
.dimmingStage =
- aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+ .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+ COLORIMETRIC})
.execute()
.expectAFenceWasReturned();
}
@@ -3767,7 +3781,8 @@
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kDisplayLuminance)
.withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+ .withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed(
{.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3780,7 +3795,9 @@
.orientation = kDefaultOutputOrientationFlags,
.targetLuminanceNits = kClientTargetLuminanceNits,
.dimmingStage =
- aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+ .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+ COLORIMETRIC})
.execute()
.expectAFenceWasReturned();
}
@@ -3792,29 +3809,8 @@
.withDisplayBrightnessNits(kUnknownLuminance)
.withDimmingStage(
aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
-
- .andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
- .clip = kDefaultOutputViewport,
- .maxLuminance = kDefaultMaxLuminance,
- .currentLuminanceNits = kDefaultMaxLuminance,
- .outputDataspace = kDefaultOutputDataspace,
- .colorTransform = kDefaultColorTransformMat,
- .deviceHandlesColorTransform = true,
- .orientation = kDefaultOutputOrientationFlags,
- .targetLuminanceNits = kClientTargetLuminanceNits,
- .dimmingStage = aidl::android::hardware::graphics::
- composer3::DimmingStage::GAMMA_OETF})
- .execute()
- .expectAFenceWasReturned();
-}
-
-TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
- verify().ifMixedCompositionIs(true)
- .andIfUsesHdr(false)
- .withDisplayBrightnessNits(kUnknownLuminance)
- .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+ .withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed(
{.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3827,7 +3823,61 @@
.orientation = kDefaultOutputOrientationFlags,
.targetLuminanceNits = kClientTargetLuminanceNits,
.dimmingStage =
- aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+ aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+ .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+ COLORIMETRIC})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
+ forHdrMixedCompositionWithRenderIntent) {
+ verify().ifMixedCompositionIs(true)
+ .andIfUsesHdr(true)
+ .withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+ .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = true,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+ .renderIntent =
+ aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
+ verify().ifMixedCompositionIs(true)
+ .andIfUsesHdr(false)
+ .withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+ .withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = true,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+ .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+ COLORIMETRIC})
.execute()
.expectAFenceWasReturned();
}
@@ -3837,7 +3887,8 @@
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kUnknownLuminance)
.withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+ .withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed(
{.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3850,7 +3901,9 @@
.orientation = kDefaultOutputOrientationFlags,
.targetLuminanceNits = kClientTargetLuminanceNits,
.dimmingStage =
- aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+ .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+ COLORIMETRIC})
.execute()
.expectAFenceWasReturned();
}
@@ -3860,7 +3913,8 @@
.andIfUsesHdr(false)
.withDisplayBrightnessNits(kUnknownLuminance)
.withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+ .withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed(
{.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3873,7 +3927,9 @@
.orientation = kDefaultOutputOrientationFlags,
.targetLuminanceNits = kClientTargetLuminanceNits,
.dimmingStage =
- aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+ .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+ COLORIMETRIC})
.execute()
.expectAFenceWasReturned();
}
@@ -3884,7 +3940,8 @@
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kUnknownLuminance)
.withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
-
+ .withRenderIntent(
+ aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
.andIfSkipColorTransform(true)
.thenExpectDisplaySettingsUsed(
{.physicalDisplay = kDefaultOutputDestinationClip,
@@ -3897,7 +3954,9 @@
.orientation = kDefaultOutputOrientationFlags,
.targetLuminanceNits = kClientTargetLuminanceNits,
.dimmingStage =
- aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
+ .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
+ COLORIMETRIC})
.execute()
.expectAFenceWasReturned();
}
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 3651c8b..52529d6 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -24,7 +24,6 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <android-base/stringprintf.h>
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/Display.h>
#include <compositionengine/DisplayColorProfile.h>
@@ -49,8 +48,6 @@
namespace hal = hardware::graphics::composer::hal;
-using android::base::StringAppendF;
-
ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0;
DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
@@ -299,26 +296,24 @@
sPrimaryDisplayRotationFlags = ui::Transform::toRotationFlags(orientation);
}
- if (!orientedDisplaySpaceRect.isValid()) {
- // The destination frame can be invalid if it has never been set,
- // in that case we assume the whole display size.
- orientedDisplaySpaceRect =
- getCompositionDisplay()->getState().displaySpace.getBoundsAsRect();
- }
-
- if (layerStackSpaceRect.isEmpty()) {
- // The layerStackSpaceRect can be invalid if it has never been set, in that case
- // we assume the whole framebuffer size.
- layerStackSpaceRect =
- getCompositionDisplay()->getState().framebufferSpace.getBoundsAsRect();
- if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) {
- std::swap(layerStackSpaceRect.right, layerStackSpaceRect.bottom);
- }
- }
-
// We need to take care of display rotation for globalTransform for case if the panel is not
// installed aligned with device orientation.
const auto transformOrientation = orientation + mPhysicalOrientation;
+
+ const auto& state = getCompositionDisplay()->getState();
+
+ // If the layer stack and destination frames have never been set, then configure them to be the
+ // same as the physical device, taking into account the total transform.
+ if (!orientedDisplaySpaceRect.isValid()) {
+ ui::Size bounds = state.displaySpace.getBounds();
+ bounds.rotate(transformOrientation);
+ orientedDisplaySpaceRect = Rect(bounds);
+ }
+ if (layerStackSpaceRect.isEmpty()) {
+ ui::Size bounds = state.framebufferSpace.getBounds();
+ bounds.rotate(transformOrientation);
+ layerStackSpaceRect = Rect(bounds);
+ }
getCompositionDisplay()->setProjection(transformOrientation, layerStackSpaceRect,
orientedDisplaySpaceRect);
}
@@ -344,38 +339,40 @@
}
std::string DisplayDevice::getDebugName() const {
- const char* type = "virtual";
+ using namespace std::string_literals;
+
+ std::string name = "Display "s + to_string(getId()) + " ("s;
+
if (mConnectionType) {
- type = isInternal() ? "internal" : "external";
+ name += isInternal() ? "internal"s : "external"s;
+ } else {
+ name += "virtual"s;
}
- return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
- isPrimary() ? ", primary" : "", mDisplayName.c_str());
+ if (isPrimary()) {
+ name += ", primary"s;
+ }
+
+ return name + ", \""s + mDisplayName + "\")"s;
}
void DisplayDevice::dump(std::string& result) const {
- StringAppendF(&result, "+ %s\n", getDebugName().c_str());
- StringAppendF(&result, " powerMode=%s (%d)\n", to_string(mPowerMode).c_str(),
- static_cast<int32_t>(mPowerMode));
- const auto activeMode = getActiveMode();
- StringAppendF(&result, " activeMode=%s\n",
- activeMode ? to_string(*activeMode).c_str() : "none");
+ using namespace std::string_literals;
- result.append(" supportedModes=\n");
- for (const auto& [id, mode] : mSupportedModes) {
- result.append(" ");
- result.append(to_string(*mode));
- result.push_back('\n');
+ result += getDebugName();
+
+ if (!isVirtual()) {
+ result += "\n deviceProductInfo="s;
+ if (mDeviceProductInfo) {
+ mDeviceProductInfo->dump(result);
+ } else {
+ result += "{}"s;
+ }
}
- StringAppendF(&result, " deviceProductInfo=");
- if (mDeviceProductInfo) {
- mDeviceProductInfo->dump(result);
- } else {
- result.append("{}");
- }
- result.append("\n");
- getCompositionDisplay()->dump(result);
+ result += "\n powerMode="s;
+ result += to_string(mPowerMode);
+ result += '\n';
if (mRefreshRateConfigs) {
mRefreshRateConfigs->dump(result);
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 8d685cf..eb14933 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -44,18 +44,10 @@
#include "HWComposer.h"
#include "../SurfaceFlinger.h"
-// ----------------------------------------------------------------------------
namespace android {
-// ----------------------------------------------------------------------------
using ui::Dataspace;
-/*
- * This implements the (main) framebuffer management. This class is used
- * mostly by SurfaceFlinger, but also by command line GL application.
- *
- */
-
FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
const sp<IGraphicBufferConsumer>& consumer,
const ui::Size& size, const ui::Size& maxSize)
@@ -205,14 +197,14 @@
void FramebufferSurface::dumpAsString(String8& result) const {
Mutex::Autolock lock(mMutex);
- result.appendFormat(" FramebufferSurface: dataspace: %s(%d)\n",
+ result.append(" FramebufferSurface\n");
+ result.appendFormat(" mDataSpace=%s (%d)\n",
dataspaceDetails(static_cast<android_dataspace>(mDataSpace)).c_str(),
mDataSpace);
- ConsumerBase::dumpLocked(result, " ");
+ ConsumerBase::dumpLocked(result, " ");
}
-void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const
-{
+void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const {
ConsumerBase::dumpLocked(result, prefix);
}
@@ -220,9 +212,7 @@
return mCurrentFence;
}
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
+} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 670233a..79e4c75 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -376,11 +376,6 @@
}
ATRACE_CALL();
- if (displayData.powerMode == hal::PowerMode::DOZE && enabled == hal::Vsync::ENABLE) {
- ALOGV("%s will not enable vsync for display %s due to power mode %s", __FUNCTION__,
- to_string(displayId).c_str(), to_string(displayData.powerMode).c_str());
- return;
- }
auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
RETURN_IF_HWC_ERROR(error, displayId);
@@ -557,7 +552,6 @@
setVsyncEnabled(displayId, hal::Vsync::DISABLE);
}
- mDisplayData[displayId].powerMode = mode;
const auto& displayData = mDisplayData[displayId];
auto& hwcDisplay = displayData.hwcDisplay;
switch (mode) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 8d67589..7dc10ea 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -462,8 +462,6 @@
std::mutex vsyncEnabledLock;
hal::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = hal::Vsync::DISABLE;
- hal::PowerMode powerMode = hal::PowerMode::ON;
-
nsecs_t lastHwVsync = 0;
};
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index cbafdd3..659efd8 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -564,6 +564,7 @@
if (!wrapper->shouldReconnectHAL()) {
return wrapper;
}
+ ALOGD("Reconnecting Power HAL");
sHalWrapper = nullptr;
}
@@ -576,7 +577,9 @@
// If that didn't succeed, attempt to connect to the HIDL Power HAL
if (sHalWrapper == nullptr) {
sHalWrapper = HidlPowerHalWrapper::connect();
- } else { // if AIDL, pass on any existing hint session values
+ } else {
+ ALOGD("Successfully connecting AIDL Power HAL");
+ // if AIDL, pass on any existing hint session values
// thread ids always safe to set
sHalWrapper->setPowerHintSessionThreadIds(oldPowerHintSessionThreadIds);
// only set duration and start if duration is defined
diff --git a/services/surfaceflinger/FlagManager.cpp b/services/surfaceflinger/FlagManager.cpp
index bd3cf74..f8ad8f6 100644
--- a/services/surfaceflinger/FlagManager.cpp
+++ b/services/surfaceflinger/FlagManager.cpp
@@ -96,7 +96,8 @@
}
bool FlagManager::use_adpf_cpu_hint() const {
- std::optional<bool> sysPropVal = std::nullopt;
+ std::optional<bool> sysPropVal =
+ doParse<bool>(base::GetProperty("debug.sf.enable_adpf_cpu_hint", "").c_str());
return getValue("AdpfFeature__adpf_cpu_hint", sysPropVal, false);
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d8a5601..3a92ca4 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2664,6 +2664,18 @@
mDrawingState.callbackHandles = {};
}
+bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) {
+ if (handles.empty()) {
+ return false;
+ }
+
+ for (const auto& handle : handles) {
+ mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle);
+ }
+
+ return true;
+}
+
// ---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 565a6ff..ecea744 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -431,9 +431,7 @@
virtual bool setApi(int32_t /*api*/) { return false; };
virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; };
virtual bool setTransactionCompletedListeners(
- const std::vector<sp<CallbackHandle>>& /*handles*/) {
- return false;
- };
+ const std::vector<sp<CallbackHandle>>& /*handles*/);
virtual bool addFrameEvent(const sp<Fence>& /*acquireFence*/, nsecs_t /*postedTime*/,
nsecs_t /*requestedPresentTime*/) {
return false;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 3226f22..ca83496 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -133,9 +133,9 @@
} // namespace
std::string RefreshRateConfigs::Policy::toString() const {
- return base::StringPrintf("default mode ID: %d, allowGroupSwitching = %d"
- ", primary range: %s, app request range: %s",
- defaultMode.value(), allowGroupSwitching,
+ return base::StringPrintf("{defaultModeId=%d, allowGroupSwitching=%s"
+ ", primaryRange=%s, appRequestRange=%s}",
+ defaultMode.value(), allowGroupSwitching ? "true" : "false",
to_string(primaryRange).c_str(), to_string(appRequestRange).c_str());
}
@@ -922,41 +922,46 @@
}
void RefreshRateConfigs::dump(std::string& result) const {
+ using namespace std::string_literals;
+
std::lock_guard lock(mLock);
- base::StringAppendF(&result, "DesiredDisplayModeSpecs (DisplayManager): %s\n\n",
- mDisplayManagerPolicy.toString().c_str());
- scheduler::RefreshRateConfigs::Policy currentPolicy = *getCurrentPolicyLocked();
- if (mOverridePolicy && currentPolicy != mDisplayManagerPolicy) {
- base::StringAppendF(&result, "DesiredDisplayModeSpecs (Override): %s\n\n",
- currentPolicy.toString().c_str());
- }
- base::StringAppendF(&result, "Active mode: %s\n", to_string(*mActiveModeIt->second).c_str());
+ const auto activeModeId = mActiveModeIt->first;
+ result += " activeModeId="s;
+ result += std::to_string(activeModeId.value());
- result.append("Display modes:\n");
+ result += "\n displayModes=\n"s;
for (const auto& [id, mode] : mDisplayModes) {
- result.push_back('\t');
- result.append(to_string(*mode));
- result.push_back('\n');
+ result += " "s;
+ result += to_string(*mode);
+ result += '\n';
}
- base::StringAppendF(&result, "Supports Frame Rate Override By Content: %s\n",
- mSupportsFrameRateOverrideByContent ? "yes" : "no");
+ base::StringAppendF(&result, " displayManagerPolicy=%s\n",
+ mDisplayManagerPolicy.toString().c_str());
- result.append("Idle timer: ");
- if (const auto controller = mConfig.kernelIdleTimerController) {
- base::StringAppendF(&result, "(kernel via %s) ", ftl::enum_string(*controller).c_str());
- } else {
- result.append("(platform) ");
+ if (const Policy& currentPolicy = *getCurrentPolicyLocked();
+ mOverridePolicy && currentPolicy != mDisplayManagerPolicy) {
+ base::StringAppendF(&result, " overridePolicy=%s\n", currentPolicy.toString().c_str());
}
+ base::StringAppendF(&result, " supportsFrameRateOverrideByContent=%s\n",
+ mSupportsFrameRateOverrideByContent ? "true" : "false");
+
+ result += " idleTimer="s;
if (mIdleTimer) {
- result.append(mIdleTimer->dump());
+ result += mIdleTimer->dump();
} else {
- result.append("off");
+ result += "off"s;
}
- result.append("\n\n");
+ if (const auto controller = mConfig.kernelIdleTimerController) {
+ base::StringAppendF(&result, " (kernel via %s)", ftl::enum_string(*controller).c_str());
+ } else {
+ result += " (platform)"s;
+ }
+
+ result += '\n';
}
std::chrono::milliseconds RefreshRateConfigs::getIdleTimerTimeout() {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3bfc2cc..d39176b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -148,6 +148,7 @@
#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
+#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
#undef NO_THREAD_SAFETY_ANALYSIS
#define NO_THREAD_SAFETY_ANALYSIS \
@@ -582,14 +583,8 @@
std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
std::vector<PhysicalDisplayId> displayIds;
displayIds.reserve(mPhysicalDisplayTokens.size());
- const auto defaultDisplayId = [this]() REQUIRES(mStateLock) {
- if (const auto display = getDefaultDisplayDeviceLocked()) {
- return display->getPhysicalId();
- }
- // fallback to the internal display id if the active display is unknown
- return getInternalDisplayIdLocked();
- }();
+ const auto defaultDisplayId = getDefaultDisplayDeviceLocked()->getPhysicalId();
displayIds.push_back(defaultDisplayId);
for (const auto& [id, token] : mPhysicalDisplayTokens) {
@@ -603,7 +598,7 @@
status_t SurfaceFlinger::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) const {
Mutex::Autolock lock(mStateLock);
- *id = getInternalDisplayIdLocked();
+ *id = getPrimaryDisplayIdLocked();
return NO_ERROR;
}
@@ -680,8 +675,12 @@
readPersistentProperties();
mPowerAdvisor->onBootFinished();
- mPowerAdvisor->enablePowerHint(mFlagManager.use_adpf_cpu_hint());
- if (mPowerAdvisor->usePowerHintSession()) {
+ const bool powerHintEnabled = mFlagManager.use_adpf_cpu_hint();
+ mPowerAdvisor->enablePowerHint(powerHintEnabled);
+ const bool powerHintUsed = mPowerAdvisor->usePowerHintSession();
+ ALOGD("Power hint is %s",
+ powerHintUsed ? "supported" : (powerHintEnabled ? "unsupported" : "disabled"));
+ if (powerHintUsed) {
std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid();
std::vector<int32_t> tidList;
tidList.emplace_back(gettid());
@@ -1314,17 +1313,25 @@
}
status_t SurfaceFlinger::getDisplayNativePrimaries(const sp<IBinder>& displayToken,
- ui::DisplayPrimaries &primaries) {
+ ui::DisplayPrimaries& primaries) {
if (!displayToken) {
return BAD_VALUE;
}
- // Currently we only support this API for a single internal display.
- if (getInternalDisplayToken() != displayToken) {
+ Mutex::Autolock lock(mStateLock);
+
+ const auto display = getDisplayDeviceLocked(displayToken);
+ if (!display) {
return NAME_NOT_FOUND;
}
- memcpy(&primaries, &mInternalDisplayPrimaries, sizeof(ui::DisplayPrimaries));
+ const auto connectionType = display->getConnectionType();
+ if (connectionType != ui::DisplayConnectionType::Internal) {
+ return INVALID_OPERATION;
+ }
+
+ // TODO(b/229846990): For now, assume that all internal displays have the same primaries.
+ primaries = mInternalDisplayPrimaries;
return NO_ERROR;
}
@@ -2346,7 +2353,12 @@
}
bool SurfaceFlinger::isHdrLayer(Layer* layer) const {
- if (!isHdrDataspace(layer->getDataSpace())) {
+ // Treat all layers as non-HDR if:
+ // 1. They do not have a valid HDR dataspace. Currently we treat those as PQ or HLG. and
+ // 2. The layer is allowed to be dimmed. WindowManager may disable dimming in order to
+ // keep animations invoking SDR screenshots of HDR layers seamless. Treat such tagged
+ // layers as HDR so that DisplayManagerService does not try to change the screen brightness
+ if (!isHdrDataspace(layer->getDataSpace()) && layer->isDimmingEnabled()) {
return false;
}
if (mIgnoreHdrCameraLayers) {
@@ -2820,7 +2832,7 @@
}
if (const auto id = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
- creationArgs.isPrimary = id == getInternalDisplayIdLocked();
+ creationArgs.isPrimary = id == getPrimaryDisplayIdLocked();
if (useColorManagement) {
std::vector<ColorMode> modes = getHwComposer().getColorModes(*id);
@@ -4939,7 +4951,9 @@
pid, uid);
} else {
static const std::unordered_map<std::string, Dumper> dumpers = {
+ {"--comp-displays"s, dumper(&SurfaceFlinger::dumpCompositionDisplays)},
{"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
+ {"--displays"s, dumper(&SurfaceFlinger::dumpDisplays)},
{"--dispsync"s, dumper([this](std::string& s) { mScheduler->dumpVsync(s); })},
{"--edid"s, argsDumper(&SurfaceFlinger::dumpRawDisplayIdentificationData)},
{"--frame-events"s, dumper(&SurfaceFlinger::dumpFrameEventsLocked)},
@@ -5116,6 +5130,20 @@
[&] (Layer* layer) { layer->dumpFrameEvents(result); });
}
+void SurfaceFlinger::dumpCompositionDisplays(std::string& result) const {
+ for (const auto& [token, display] : mDisplays) {
+ display->getCompositionDisplay()->dump(result);
+ result += '\n';
+ }
+}
+
+void SurfaceFlinger::dumpDisplays(std::string& result) const {
+ for (const auto& [token, display] : mDisplays) {
+ display->dump(result);
+ result += '\n';
+ }
+}
+
void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
const auto displayId = PhysicalDisplayId::tryCast(display->getId());
@@ -5324,21 +5352,12 @@
});
}
- /*
- * Dump Display state
- */
-
colorizer.bold(result);
StringAppendF(&result, "Displays (%zu entries)\n", mDisplays.size());
colorizer.reset(result);
- for (const auto& [token, display] : mDisplays) {
- display->dump(result);
- }
- result.append("\n");
-
- /*
- * Dump CompositionEngine state
- */
+ dumpDisplays(result);
+ dumpCompositionDisplays(result);
+ result.push_back('\n');
mCompositionEngine->dump(result);
@@ -6689,6 +6708,7 @@
captureResults.buffer = buffer->getBuffer();
auto dataspace = renderArea.getReqDataSpace();
auto parent = renderArea.getParentLayer();
+ auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC;
if ((dataspace == ui::Dataspace::UNKNOWN) && (parent != nullptr)) {
Mutex::Autolock lock(mStateLock);
auto display = findDisplay([layerStack = parent->getLayerStack()](const auto& display) {
@@ -6701,6 +6721,7 @@
const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
dataspace = pickDataspaceFromColorMode(colorMode);
+ renderIntent = display->getCompositionDisplay()->getState().renderIntent;
}
captureResults.capturedDataspace = dataspace;
@@ -6722,6 +6743,8 @@
clientCompositionDisplay.outputDataspace = dataspace;
clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance;
+ clientCompositionDisplay.renderIntent =
+ static_cast<aidl::android::hardware::graphics::composer3::RenderIntent>(renderIntent);
const float colorSaturation = grayscale ? 0 : 1;
clientCompositionDisplay.colorTransform = calculateColorMatrix(colorSaturation);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 011aaef..74e0407 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -525,19 +525,6 @@
bool callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache = true)
EXCLUDES(mStateLock);
- // the following two methods are moved from ISurfaceComposer.h
- // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
- std::optional<PhysicalDisplayId> getInternalDisplayId() const {
- const auto displayIds = getPhysicalDisplayIds();
- return displayIds.empty() ? std::nullopt : std::make_optional(displayIds.front());
- }
-
- // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
- sp<IBinder> getInternalDisplayToken() const {
- const auto displayId = getInternalDisplayId();
- return displayId ? getPhysicalDisplayToken(*displayId) : nullptr;
- }
-
// Implements ISurfaceComposer
sp<ISurfaceComposerClient> createConnection() override;
sp<IBinder> createDisplay(const String8& displayName, bool secure);
@@ -922,6 +909,13 @@
return nullptr;
}
+ sp<const DisplayDevice> getDisplayDeviceLocked(DisplayId id) const REQUIRES(mStateLock) {
+ // TODO(b/182939859): Replace tokens with IDs for display lookup.
+ return findDisplay([id](const auto& display) { return display.getId() == id; });
+ }
+
+ // Returns the primary display or (for foldables) the active display, assuming that the inner
+ // and outer displays have mutually exclusive power states.
sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) {
return const_cast<SurfaceFlinger*>(this)->getDefaultDisplayDeviceLocked();
}
@@ -930,12 +924,9 @@
if (const auto display = getDisplayDeviceLocked(mActiveDisplayToken)) {
return display;
}
- // The active display is outdated, fall back to the internal display
+ // The active display is outdated, so fall back to the primary display.
mActiveDisplayToken.clear();
- if (const auto token = getInternalDisplayTokenLocked()) {
- return getDisplayDeviceLocked(token);
- }
- return nullptr;
+ return getDisplayDeviceLocked(getPrimaryDisplayTokenLocked());
}
sp<const DisplayDevice> getDefaultDisplayDevice() const EXCLUDES(mStateLock) {
@@ -952,11 +943,6 @@
return it == mDisplays.end() ? nullptr : it->second;
}
- sp<const DisplayDevice> getDisplayDeviceLocked(DisplayId id) const REQUIRES(mStateLock) {
- // TODO(b/182939859): Replace tokens with IDs for display lookup.
- return findDisplay([id](const auto& display) { return display.getId() == id; });
- }
-
std::vector<PhysicalDisplayId> getPhysicalDisplayIdsLocked() const REQUIRES(mStateLock);
// mark a region of a layer stack dirty. this updates the dirty
@@ -1066,18 +1052,17 @@
return {};
}
- // TODO(b/182939859): SF conflates the primary (a.k.a. default) display with the first display
- // connected at boot, which is typically internal. (Theoretically, it must be internal because
- // SF does not support disconnecting it, though in practice HWC may circumvent this limitation.)
+ // Returns the first display connected at boot.
//
- // SF inherits getInternalDisplayToken and getInternalDisplayId from ISurfaceComposer, so these
- // locked counterparts are named consistently. Once SF supports headless mode and can designate
- // any display as primary, the "internal" misnomer will be phased out.
- sp<IBinder> getInternalDisplayTokenLocked() const REQUIRES(mStateLock) {
- return getPhysicalDisplayTokenLocked(getInternalDisplayIdLocked());
+ // TODO(b/229851933): SF conflates the primary display with the first display connected at boot,
+ // which typically has DisplayConnectionType::Internal. (Theoretically, it must be an internal
+ // display because SF does not support disconnecting it, though in practice HWC may circumvent
+ // this limitation.)
+ sp<IBinder> getPrimaryDisplayTokenLocked() const REQUIRES(mStateLock) {
+ return getPhysicalDisplayTokenLocked(getPrimaryDisplayIdLocked());
}
- PhysicalDisplayId getInternalDisplayIdLocked() const REQUIRES(mStateLock) {
+ PhysicalDisplayId getPrimaryDisplayIdLocked() const REQUIRES(mStateLock) {
return getHwComposer().getPrimaryDisplayId();
}
@@ -1109,9 +1094,13 @@
void dumpStaticScreenStats(std::string& result) const;
// Not const because each Layer needs to query Fences and cache timestamps.
void dumpFrameEventsLocked(std::string& result);
+
+ void dumpCompositionDisplays(std::string& result) const REQUIRES(mStateLock);
+ void dumpDisplays(std::string& result) const REQUIRES(mStateLock);
void dumpDisplayIdentificationData(std::string& result) const REQUIRES(mStateLock);
void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
void dumpWideColorInfo(std::string& result) const REQUIRES(mStateLock);
+
LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
void dumpOffscreenLayersProto(LayersProto& layersProto,
uint32_t traceFlags = LayerTracing::TRACE_ALL) const;
diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp
index 8a2305b..219db8c 100644
--- a/services/surfaceflinger/tests/LayerCallback_test.cpp
+++ b/services/surfaceflinger/tests/LayerCallback_test.cpp
@@ -55,24 +55,34 @@
return createLayer(mClient, "test", 0, 0, ISurfaceComposerClient::eFXSurfaceBufferState);
}
+ static int fillBuffer(Transaction& transaction, const sp<SurfaceControl>& layer,
+ bool setBuffer = true, bool setBackgroundColor = false) {
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ if (setBuffer) {
+ int err = getBuffer(&buffer, &fence);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ transaction.setBuffer(layer, buffer, fence);
+ }
+
+ if (setBackgroundColor) {
+ transaction.setBackgroundColor(layer, /*color*/ half3(1.0f, 0, 0), /*alpha*/ 1.0f,
+ ui::Dataspace::UNKNOWN);
+ }
+
+ return NO_ERROR;
+ }
+
static int fillTransaction(Transaction& transaction, CallbackHelper* callbackHelper,
const sp<SurfaceControl>& layer = nullptr, bool setBuffer = true,
bool setBackgroundColor = false) {
if (layer) {
- sp<GraphicBuffer> buffer;
- sp<Fence> fence;
- if (setBuffer) {
- int err = getBuffer(&buffer, &fence);
- if (err != NO_ERROR) {
- return err;
- }
-
- transaction.setBuffer(layer, buffer, fence);
- }
-
- if (setBackgroundColor) {
- transaction.setBackgroundColor(layer, /*color*/ half3(1.0f, 0, 0), /*alpha*/ 1.0f,
- ui::Dataspace::UNKNOWN);
+ int err = fillBuffer(transaction, layer, setBuffer, setBackgroundColor);
+ if (err != NO_ERROR) {
+ return err;
}
}
@@ -1115,7 +1125,7 @@
Transaction transaction;
CallbackHelper callback;
int err = fillTransaction(transaction, &callback, layer, true);
- err |= fillTransaction(transaction, &callback, offscreenLayer, true);
+ err |= fillBuffer(transaction, offscreenLayer);
if (err) {
GTEST_SUCCEED() << "test not supported";
return;
@@ -1129,5 +1139,86 @@
committedSc.insert(layer);
committedSc.insert(offscreenLayer);
EXPECT_NO_FATAL_FAILURE(waitForCommitCallback(callback, committedSc));
+
+ ExpectedResult expected;
+ expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
+ expected.addSurface(ExpectedResult::Transaction::PRESENTED, offscreenLayer);
+ EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
}
+
+TEST_F(LayerCallbackTest, TransactionCommittedCallback_BSL) {
+ sp<SurfaceControl> layer;
+ ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+
+ Transaction transaction;
+ CallbackHelper callback;
+ int err = fillTransaction(transaction, &callback, layer, true);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ transaction.addTransactionCommittedCallback(callback.function, callback.getContext()).apply();
+ std::unordered_set<sp<SurfaceControl>, SCHash> committedSc;
+ committedSc.insert(layer);
+ EXPECT_NO_FATAL_FAILURE(waitForCommitCallback(callback, committedSc));
+ ExpectedResult expected;
+ expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
+ EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
+}
+
+TEST_F(LayerCallbackTest, TransactionCommittedCallback_EffectLayer) {
+ sp<SurfaceControl> layer;
+ ASSERT_NO_FATAL_FAILURE(layer = createColorLayer("ColorLayer", Color::RED));
+
+ Transaction transaction;
+ CallbackHelper callback;
+ int err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ transaction.addTransactionCommittedCallback(callback.function, callback.getContext()).apply();
+ std::unordered_set<sp<SurfaceControl>, SCHash> committedSc;
+ EXPECT_NO_FATAL_FAILURE(waitForCommitCallback(callback, committedSc));
+
+ ExpectedResult expected;
+ EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
+}
+
+TEST_F(LayerCallbackTest, TransactionCommittedCallback_ContainerLayer) {
+ sp<SurfaceControl> layer;
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer(mClient, "Container Layer", 0, 0,
+ ISurfaceComposerClient::eFXSurfaceContainer));
+
+ Transaction transaction;
+ CallbackHelper callback;
+ int err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ transaction.addTransactionCommittedCallback(callback.function, callback.getContext()).apply();
+ std::unordered_set<sp<SurfaceControl>, SCHash> committedSc;
+ EXPECT_NO_FATAL_FAILURE(waitForCommitCallback(callback, committedSc));
+
+ ExpectedResult expected;
+ EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
+}
+
+TEST_F(LayerCallbackTest, TransactionCommittedCallback_NoLayer) {
+ Transaction transaction;
+ CallbackHelper callback;
+ int err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ transaction.addTransactionCommittedCallback(callback.function, callback.getContext()).apply();
+ std::unordered_set<sp<SurfaceControl>, SCHash> committedSc;
+ EXPECT_NO_FATAL_FAILURE(waitForCommitCallback(callback, committedSc));
+
+ ExpectedResult expected;
+ EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
+}
+
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp
index 3d24ecb..5734d34 100644
--- a/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayDevice_SetProjectionTest.cpp
@@ -21,6 +21,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <ui/Rotation.h>
namespace android {
namespace {
@@ -53,6 +54,11 @@
ui::Size swapWH(const ui::Size size) const { return ui::Size(size.height, size.width); }
+ void setDefaultProjection() {
+ // INVALID_RECT pulls from the physical display dimensions.
+ mDisplayDevice->setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
+ }
+
void setProjectionForRotation0() {
// A logical rotation of 0 uses the SurfaceFlinger display size
mDisplayDevice->setProjection(ui::ROTATION_0, Rect(mFlingerDisplaySize),
@@ -79,6 +85,30 @@
Rect(swapWH(mFlingerDisplaySize)));
}
+ void expectDefaultState() {
+ const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
+ EXPECT_EQ(ui::Transform(ui::Transform::toRotationFlags(mPhysicalOrientation),
+ mHardwareDisplaySize.width, mHardwareDisplaySize.height),
+ compositionState.transform);
+ EXPECT_EQ(mPhysicalOrientation, compositionState.displaySpace.getOrientation());
+ EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.displaySpace.getContent());
+ EXPECT_EQ(mHardwareDisplaySize, compositionState.displaySpace.getBounds());
+ EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.framebufferSpace.getContent());
+ EXPECT_EQ(mHardwareDisplaySize, compositionState.framebufferSpace.getBounds());
+
+ const ui::Size expectedLogicalSize = (mPhysicalOrientation == ui::ROTATION_270 ||
+ mPhysicalOrientation == ui::ROTATION_90)
+ ? swapWH(mHardwareDisplaySize)
+ : mHardwareDisplaySize;
+
+ EXPECT_EQ(Rect(expectedLogicalSize), compositionState.orientedDisplaySpace.getContent());
+ EXPECT_EQ(expectedLogicalSize, compositionState.orientedDisplaySpace.getBounds());
+ EXPECT_EQ(Rect(expectedLogicalSize), compositionState.layerStackSpace.getContent());
+ EXPECT_EQ(expectedLogicalSize, compositionState.layerStackSpace.getBounds());
+
+ EXPECT_EQ(false, compositionState.needsFiltering);
+ }
+
void expectStateForHardwareTransform0() {
const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_0, mHardwareDisplaySize.width,
@@ -147,6 +177,11 @@
ui::ROTATION_0) {}
};
+TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkDefaultProjection) {
+ setDefaultProjection();
+ expectDefaultState();
+}
+
TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith0OutputRotation) {
setProjectionForRotation0();
expectStateForHardwareTransform0();
@@ -174,6 +209,11 @@
ui::ROTATION_90) {}
};
+TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkDefaultProjection) {
+ setDefaultProjection();
+ expectDefaultState();
+}
+
TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith0OutputRotation) {
setProjectionForRotation0();
expectStateForHardwareTransform90();
@@ -201,6 +241,11 @@
ui::ROTATION_180) {}
};
+TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkDefaultProjection) {
+ setDefaultProjection();
+ expectDefaultState();
+}
+
TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith0OutputRotation) {
setProjectionForRotation0();
expectStateForHardwareTransform180();
@@ -228,6 +273,11 @@
ui::ROTATION_270) {}
};
+TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkDefaultProjection) {
+ setDefaultProjection();
+ expectDefaultState();
+}
+
TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith0OutputRotation) {
setProjectionForRotation0();
expectStateForHardwareTransform270();
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
index 0a157c4..8de9e4b 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
@@ -130,8 +130,7 @@
ON_CALL(*mPowerAdvisor, usePowerHintSession()).WillByDefault(Return(true));
const std::chrono::nanoseconds mockVsyncPeriod = 15ms;
- const std::chrono::nanoseconds expectedTargetTime = 14ms;
- EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(Gt(expectedTargetTime.count()))).Times(1);
+ EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(_)).Times(1);
const nsecs_t now = systemTime();
const std::chrono::nanoseconds mockHwcRunTime = 20ms;