Loading include/input/Input.h +1 −1 Original line number Diff line number Diff line Loading @@ -534,7 +534,7 @@ public: inline int32_t getActionMasked() const { return getActionMasked(mAction); } static int32_t getActionIndex(int32_t action) { static uint8_t getActionIndex(int32_t action) { return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; } Loading libs/cputimeinstate/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -45,4 +45,5 @@ cc_test { "-Wextra", ], require_root: true, test_suites: ["general-tests"], } libs/cputimeinstate/TEST_MAPPING 0 → 100644 +7 −0 Original line number Diff line number Diff line { "presubmit": [ { "name": "libtimeinstate_test" } ] } libs/cputimeinstate/testtimeinstate.cpp +33 −25 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <gtest/gtest.h> #include <android-base/properties.h> #include <android-base/unique_fd.h> #include <bpf/BpfMap.h> #include <cputimeinstate.h> Loading @@ -40,24 +41,31 @@ static constexpr uint64_t NSEC_PER_YEAR = NSEC_PER_SEC * 60 * 60 * 24 * 365; using std::vector; TEST(TimeInStateTest, IsTrackingSupported) { isTrackingUidTimesSupported(); SUCCEED(); class TimeInStateTest : public testing::Test { protected: TimeInStateTest() {}; void SetUp() { if (!isTrackingUidTimesSupported() || !android::base::GetBoolProperty("sys.init.perf_lsm_hooks", false)) { GTEST_SKIP(); } } }; TEST(TimeInStateTest, TotalTimeInState) { TEST_F(TimeInStateTest, TotalTimeInState) { auto times = getTotalCpuFreqTimes(); ASSERT_TRUE(times.has_value()); EXPECT_FALSE(times->empty()); } TEST(TimeInStateTest, SingleUidTimeInState) { TEST_F(TimeInStateTest, SingleUidTimeInState) { auto times = getUidCpuFreqTimes(0); ASSERT_TRUE(times.has_value()); EXPECT_FALSE(times->empty()); } TEST(TimeInStateTest, SingleUidConcurrentTimes) { TEST_F(TimeInStateTest, SingleUidConcurrentTimes) { auto concurrentTimes = getUidConcurrentTimes(0); ASSERT_TRUE(concurrentTimes.has_value()); ASSERT_FALSE(concurrentTimes->active.empty()); Loading Loading @@ -117,7 +125,7 @@ static void TestUidTimesConsistent(const std::vector<std::vector<uint64_t>> &tim EXPECT_EQ(activeSum, policySum); } TEST(TimeInStateTest, SingleUidTimesConsistent) { TEST_F(TimeInStateTest, SingleUidTimesConsistent) { auto times = getUidCpuFreqTimes(0); ASSERT_TRUE(times.has_value()); Loading @@ -127,7 +135,7 @@ TEST(TimeInStateTest, SingleUidTimesConsistent) { ASSERT_NO_FATAL_FAILURE(TestUidTimesConsistent(*times, *concurrentTimes)); } TEST(TimeInStateTest, AllUidTimeInState) { TEST_F(TimeInStateTest, AllUidTimeInState) { uint64_t zero = 0; auto maps = {getUidsCpuFreqTimes(), getUidsUpdatedCpuFreqTimes(&zero)}; for (const auto &map : maps) { Loading Loading @@ -163,7 +171,7 @@ void TestCheckUpdate(const std::vector<std::vector<uint64_t>> &before, ASSERT_LE(sumAfter - sumBefore, NSEC_PER_SEC); } TEST(TimeInStateTest, AllUidUpdatedTimeInState) { TEST_F(TimeInStateTest, AllUidUpdatedTimeInState) { uint64_t lastUpdate = 0; auto map1 = getUidsUpdatedCpuFreqTimes(&lastUpdate); ASSERT_TRUE(map1.has_value()); Loading Loading @@ -197,7 +205,7 @@ TEST(TimeInStateTest, AllUidUpdatedTimeInState) { } } TEST(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) { TEST_F(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) { auto allUid = getUidsCpuFreqTimes(); auto total = getTotalCpuFreqTimes(); Loading @@ -222,7 +230,7 @@ TEST(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) { } } TEST(TimeInStateTest, SingleAndAllUidTimeInStateConsistent) { TEST_F(TimeInStateTest, SingleAndAllUidTimeInStateConsistent) { uint64_t zero = 0; auto maps = {getUidsCpuFreqTimes(), getUidsUpdatedCpuFreqTimes(&zero)}; for (const auto &map : maps) { Loading @@ -246,7 +254,7 @@ TEST(TimeInStateTest, SingleAndAllUidTimeInStateConsistent) { } } TEST(TimeInStateTest, AllUidConcurrentTimes) { TEST_F(TimeInStateTest, AllUidConcurrentTimes) { uint64_t zero = 0; auto maps = {getUidsConcurrentTimes(), getUidsUpdatedConcurrentTimes(&zero)}; for (const auto &map : maps) { Loading @@ -264,7 +272,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimes) { } } TEST(TimeInStateTest, AllUidUpdatedConcurrentTimes) { TEST_F(TimeInStateTest, AllUidUpdatedConcurrentTimes) { uint64_t lastUpdate = 0; auto map1 = getUidsUpdatedConcurrentTimes(&lastUpdate); ASSERT_TRUE(map1.has_value()); Loading Loading @@ -299,7 +307,7 @@ TEST(TimeInStateTest, AllUidUpdatedConcurrentTimes) { } } TEST(TimeInStateTest, SingleAndAllUidConcurrentTimesConsistent) { TEST_F(TimeInStateTest, SingleAndAllUidConcurrentTimesConsistent) { uint64_t zero = 0; auto maps = {getUidsConcurrentTimes(), getUidsUpdatedConcurrentTimes(&zero)}; for (const auto &map : maps) { Loading Loading @@ -328,7 +336,7 @@ void TestCheckDelta(uint64_t before, uint64_t after) { ASSERT_LE(after - before, NSEC_PER_SEC * 2 * get_nprocs_conf()); } TEST(TimeInStateTest, TotalTimeInStateMonotonic) { TEST_F(TimeInStateTest, TotalTimeInStateMonotonic) { auto before = getTotalCpuFreqTimes(); ASSERT_TRUE(before.has_value()); sleep(1); Loading @@ -344,7 +352,7 @@ TEST(TimeInStateTest, TotalTimeInStateMonotonic) { } } TEST(TimeInStateTest, AllUidTimeInStateMonotonic) { TEST_F(TimeInStateTest, AllUidTimeInStateMonotonic) { auto map1 = getUidsCpuFreqTimes(); ASSERT_TRUE(map1.has_value()); sleep(1); Loading @@ -365,7 +373,7 @@ TEST(TimeInStateTest, AllUidTimeInStateMonotonic) { } } TEST(TimeInStateTest, AllUidConcurrentTimesMonotonic) { TEST_F(TimeInStateTest, AllUidConcurrentTimesMonotonic) { auto map1 = getUidsConcurrentTimes(); ASSERT_TRUE(map1.has_value()); ASSERT_FALSE(map1->empty()); Loading Loading @@ -393,7 +401,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimesMonotonic) { } } TEST(TimeInStateTest, AllUidTimeInStateSanityCheck) { TEST_F(TimeInStateTest, AllUidTimeInStateSanityCheck) { uint64_t zero = 0; auto maps = {getUidsCpuFreqTimes(), getUidsUpdatedCpuFreqTimes(&zero)}; for (const auto &map : maps) { Loading @@ -414,7 +422,7 @@ TEST(TimeInStateTest, AllUidTimeInStateSanityCheck) { } } TEST(TimeInStateTest, AllUidConcurrentTimesSanityCheck) { TEST_F(TimeInStateTest, AllUidConcurrentTimesSanityCheck) { uint64_t zero = 0; auto maps = {getUidsConcurrentTimes(), getUidsUpdatedConcurrentTimes(&zero)}; for (const auto &concurrentMap : maps) { Loading @@ -441,7 +449,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimesSanityCheck) { } } TEST(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) { TEST_F(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) { uint32_t uid = 0; { // Find an unused UID Loading @@ -463,7 +471,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) { ASSERT_FALSE(deleteMapEntry(fd, &key)); } TEST(TimeInStateTest, AllUidTimesConsistent) { TEST_F(TimeInStateTest, AllUidTimesConsistent) { auto tisMap = getUidsCpuFreqTimes(); ASSERT_TRUE(tisMap.has_value()); Loading @@ -481,7 +489,7 @@ TEST(TimeInStateTest, AllUidTimesConsistent) { } } TEST(TimeInStateTest, RemoveUid) { TEST_F(TimeInStateTest, RemoveUid) { uint32_t uid = 0; { // Find an unused UID Loading Loading @@ -547,7 +555,7 @@ TEST(TimeInStateTest, RemoveUid) { ASSERT_EQ(allConcurrentTimes->find(uid), allConcurrentTimes->end()); } TEST(TimeInStateTest, GetCpuFreqs) { TEST_F(TimeInStateTest, GetCpuFreqs) { auto freqs = getCpuFreqs(); ASSERT_TRUE(freqs.has_value()); Loading Loading @@ -583,7 +591,7 @@ void *testThread(void *) { return nullptr; } TEST(TimeInStateTest, GetAggregatedTaskCpuFreqTimes) { TEST_F(TimeInStateTest, GetAggregatedTaskCpuFreqTimes) { uint64_t startTimeNs = timeNanos(); sem_init(&pingsem, 0, 1); Loading libs/renderengine/tests/RenderEngineTest.cpp +190 −135 Original line number Diff line number Diff line Loading @@ -49,6 +49,50 @@ constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false; namespace android { namespace renderengine { namespace { double EOTF_PQ(double channel) { float m1 = (2610.0 / 4096.0) / 4.0; float m2 = (2523.0 / 4096.0) * 128.0; float c1 = (3424.0 / 4096.0); float c2 = (2413.0 / 4096.0) * 32.0; float c3 = (2392.0 / 4096.0) * 32.0; float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2); tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp); return std::pow(tmp, 1.0 / m1); } vec3 EOTF_PQ(vec3 color) { return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b)); } double EOTF_HLG(double channel) { const float a = 0.17883277; const float b = 0.28466892; const float c = 0.55991073; return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0; } vec3 EOTF_HLG(vec3 color) { return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b)); } double OETF_sRGB(double channel) { return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055; } int sign(float in) { return in >= 0.0 ? 1 : -1; } vec3 OETF_sRGB(vec3 linear) { return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g), sign(linear.b) * OETF_sRGB(linear.b)); } } // namespace class RenderEngineFactory { public: virtual ~RenderEngineFactory() = default; Loading Loading @@ -598,6 +642,12 @@ public: const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor); // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU // implementations are identical Also implicitly checks that the injected tonemap shader // compiles void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf, std::function<vec3(vec3, float)> scaleOotf); void initializeRenderEngine(); std::unique_ptr<renderengine::RenderEngine> mRE; Loading Loading @@ -1418,6 +1468,119 @@ void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, invokeDraw(settings, layers); } void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf, std::function<vec3(vec3, float)> scaleOotf) { constexpr int32_t kGreyLevels = 256; const auto rect = Rect(0, 0, kGreyLevels, 1); constexpr float kMaxLuminance = 750.f; constexpr float kCurrentLuminanceNits = 500.f; const renderengine::DisplaySettings display{ .physicalDisplay = rect, .clip = rect, .maxLuminance = kMaxLuminance, .currentLuminanceNits = kCurrentLuminanceNits, .outputDataspace = ui::Dataspace::DISPLAY_P3, }; auto buf = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "input"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, buf->getBuffer()->initCheck()); { uint8_t* pixels; buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&pixels)); uint8_t color = 0; for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) { uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4); for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) { dest[0] = color; dest[1] = color; dest[2] = color; dest[3] = 255; color++; dest += 4; } } buf->getBuffer()->unlock(); } mBuffer = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "output"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, mBuffer->getBuffer()->initCheck()); const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = std::move(buf), .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = sourceDataspace}; std::vector<renderengine::LayerSettings> layers{layer}; invokeDraw(display, layers); ColorSpace displayP3 = ColorSpace::DisplayP3(); ColorSpace bt2020 = ColorSpace::BT2020(); tonemap::Metadata metadata{.displayMaxLuminance = 750.0f}; auto generator = [=](Point location) { const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1); const vec3 rgb = vec3(normColor, normColor, normColor); const vec3 linearRGB = eotf(rgb); const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB; const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits); const double gain = tonemap::getToneMapper() ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common:: Dataspace>(sourceDataspace), static_cast<aidl::android::hardware::graphics::common:: Dataspace>( ui::Dataspace::DISPLAY_P3), scaleOotf(linearRGB, kCurrentLuminanceNits), scaledXYZ, metadata); const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance; const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255; return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g), static_cast<uint8_t>(targetRGB.b), 255); }; expectBufferColor(Rect(kGreyLevels, 1), generator, 2); } INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest, testing::Values(std::make_shared<GLESRenderEngineFactory>(), std::make_shared<GLESCMRenderEngineFactory>(), Loading Loading @@ -2412,155 +2575,47 @@ TEST_P(RenderEngineTest, test_isOpaque) { } } double EOTF_PQ(double channel) { float m1 = (2610.0 / 4096.0) / 4.0; float m2 = (2523.0 / 4096.0) * 128.0; float c1 = (3424.0 / 4096.0); float c2 = (2413.0 / 4096.0) * 32.0; float c3 = (2392.0 / 4096.0) * 32.0; float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2); tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp); return std::pow(tmp, 1.0 / m1); } vec3 EOTF_PQ(vec3 color) { return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b)); TEST_P(RenderEngineTest, test_tonemapPQMatches) { if (!GetParam()->useColorManagement()) { GTEST_SKIP(); } double OETF_sRGB(double channel) { return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055; if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { GTEST_SKIP(); } int sign(float in) { return in >= 0.0 ? 1 : -1; } initializeRenderEngine(); vec3 OETF_sRGB(vec3 linear) { return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g), sign(linear.b) * OETF_sRGB(linear.b)); tonemap( static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL), [](vec3 color) { return EOTF_PQ(color); }, [](vec3 color, float) { static constexpr float kMaxPQLuminance = 10000.f; return color * kMaxPQLuminance; }); } TEST_P(RenderEngineTest, test_tonemapPQMatches) { TEST_P(RenderEngineTest, test_tonemapHLGMatches) { if (!GetParam()->useColorManagement()) { return; GTEST_SKIP(); } if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { return; GTEST_SKIP(); } initializeRenderEngine(); constexpr int32_t kGreyLevels = 256; const auto rect = Rect(0, 0, kGreyLevels, 1); const renderengine::DisplaySettings display{ .physicalDisplay = rect, .clip = rect, .maxLuminance = 750.0f, .outputDataspace = ui::Dataspace::DISPLAY_P3, }; auto buf = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "input"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, buf->getBuffer()->initCheck()); { uint8_t* pixels; buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&pixels)); uint8_t color = 0; for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) { uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4); for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) { dest[0] = color; dest[1] = color; dest[2] = color; dest[3] = 255; color++; dest += 4; } } buf->getBuffer()->unlock(); } mBuffer = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "output"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, mBuffer->getBuffer()->initCheck()); const renderengine::LayerSettings layer{ .geometry.boundaries = rect.toFloatRect(), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = std::move(buf), .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL), }; std::vector<renderengine::LayerSettings> layers{layer}; invokeDraw(display, layers); ColorSpace displayP3 = ColorSpace::DisplayP3(); ColorSpace bt2020 = ColorSpace::BT2020(); tonemap::Metadata metadata{.displayMaxLuminance = 750.0f}; auto generator = [=](Point location) { const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1); const vec3 rgb = vec3(normColor, normColor, normColor); const vec3 linearRGB = EOTF_PQ(rgb); static constexpr float kMaxPQLuminance = 10000.f; const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB * kMaxPQLuminance; const double gain = tonemap::getToneMapper() ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common:: Dataspace>( HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | tonemap( static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG | HAL_DATASPACE_RANGE_FULL), static_cast<aidl::android::hardware::graphics::common:: Dataspace>( ui::Dataspace::DISPLAY_P3), linearRGB * 10000.0, xyz, metadata); const vec3 scaledXYZ = xyz * gain / metadata.displayMaxLuminance; const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * scaledXYZ) * 255; return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g), static_cast<uint8_t>(targetRGB.b), 255); }; expectBufferColor(Rect(kGreyLevels, 1), generator, 2); [](vec3 color) { return EOTF_HLG(color); }, [](vec3 color, float currentLuminaceNits) { static constexpr float kMaxHLGLuminance = 1000.f; static const float kHLGGamma = 1.2 + 0.42 * std::log10(currentLuminaceNits / 1000); return color * kMaxHLGLuminance * std::pow(color.y, kHLGGamma - 1); }); } TEST_P(RenderEngineTest, r8_behaves_as_mask) { Loading Loading
include/input/Input.h +1 −1 Original line number Diff line number Diff line Loading @@ -534,7 +534,7 @@ public: inline int32_t getActionMasked() const { return getActionMasked(mAction); } static int32_t getActionIndex(int32_t action) { static uint8_t getActionIndex(int32_t action) { return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; } Loading
libs/cputimeinstate/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -45,4 +45,5 @@ cc_test { "-Wextra", ], require_root: true, test_suites: ["general-tests"], }
libs/cputimeinstate/TEST_MAPPING 0 → 100644 +7 −0 Original line number Diff line number Diff line { "presubmit": [ { "name": "libtimeinstate_test" } ] }
libs/cputimeinstate/testtimeinstate.cpp +33 −25 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <gtest/gtest.h> #include <android-base/properties.h> #include <android-base/unique_fd.h> #include <bpf/BpfMap.h> #include <cputimeinstate.h> Loading @@ -40,24 +41,31 @@ static constexpr uint64_t NSEC_PER_YEAR = NSEC_PER_SEC * 60 * 60 * 24 * 365; using std::vector; TEST(TimeInStateTest, IsTrackingSupported) { isTrackingUidTimesSupported(); SUCCEED(); class TimeInStateTest : public testing::Test { protected: TimeInStateTest() {}; void SetUp() { if (!isTrackingUidTimesSupported() || !android::base::GetBoolProperty("sys.init.perf_lsm_hooks", false)) { GTEST_SKIP(); } } }; TEST(TimeInStateTest, TotalTimeInState) { TEST_F(TimeInStateTest, TotalTimeInState) { auto times = getTotalCpuFreqTimes(); ASSERT_TRUE(times.has_value()); EXPECT_FALSE(times->empty()); } TEST(TimeInStateTest, SingleUidTimeInState) { TEST_F(TimeInStateTest, SingleUidTimeInState) { auto times = getUidCpuFreqTimes(0); ASSERT_TRUE(times.has_value()); EXPECT_FALSE(times->empty()); } TEST(TimeInStateTest, SingleUidConcurrentTimes) { TEST_F(TimeInStateTest, SingleUidConcurrentTimes) { auto concurrentTimes = getUidConcurrentTimes(0); ASSERT_TRUE(concurrentTimes.has_value()); ASSERT_FALSE(concurrentTimes->active.empty()); Loading Loading @@ -117,7 +125,7 @@ static void TestUidTimesConsistent(const std::vector<std::vector<uint64_t>> &tim EXPECT_EQ(activeSum, policySum); } TEST(TimeInStateTest, SingleUidTimesConsistent) { TEST_F(TimeInStateTest, SingleUidTimesConsistent) { auto times = getUidCpuFreqTimes(0); ASSERT_TRUE(times.has_value()); Loading @@ -127,7 +135,7 @@ TEST(TimeInStateTest, SingleUidTimesConsistent) { ASSERT_NO_FATAL_FAILURE(TestUidTimesConsistent(*times, *concurrentTimes)); } TEST(TimeInStateTest, AllUidTimeInState) { TEST_F(TimeInStateTest, AllUidTimeInState) { uint64_t zero = 0; auto maps = {getUidsCpuFreqTimes(), getUidsUpdatedCpuFreqTimes(&zero)}; for (const auto &map : maps) { Loading Loading @@ -163,7 +171,7 @@ void TestCheckUpdate(const std::vector<std::vector<uint64_t>> &before, ASSERT_LE(sumAfter - sumBefore, NSEC_PER_SEC); } TEST(TimeInStateTest, AllUidUpdatedTimeInState) { TEST_F(TimeInStateTest, AllUidUpdatedTimeInState) { uint64_t lastUpdate = 0; auto map1 = getUidsUpdatedCpuFreqTimes(&lastUpdate); ASSERT_TRUE(map1.has_value()); Loading Loading @@ -197,7 +205,7 @@ TEST(TimeInStateTest, AllUidUpdatedTimeInState) { } } TEST(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) { TEST_F(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) { auto allUid = getUidsCpuFreqTimes(); auto total = getTotalCpuFreqTimes(); Loading @@ -222,7 +230,7 @@ TEST(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) { } } TEST(TimeInStateTest, SingleAndAllUidTimeInStateConsistent) { TEST_F(TimeInStateTest, SingleAndAllUidTimeInStateConsistent) { uint64_t zero = 0; auto maps = {getUidsCpuFreqTimes(), getUidsUpdatedCpuFreqTimes(&zero)}; for (const auto &map : maps) { Loading @@ -246,7 +254,7 @@ TEST(TimeInStateTest, SingleAndAllUidTimeInStateConsistent) { } } TEST(TimeInStateTest, AllUidConcurrentTimes) { TEST_F(TimeInStateTest, AllUidConcurrentTimes) { uint64_t zero = 0; auto maps = {getUidsConcurrentTimes(), getUidsUpdatedConcurrentTimes(&zero)}; for (const auto &map : maps) { Loading @@ -264,7 +272,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimes) { } } TEST(TimeInStateTest, AllUidUpdatedConcurrentTimes) { TEST_F(TimeInStateTest, AllUidUpdatedConcurrentTimes) { uint64_t lastUpdate = 0; auto map1 = getUidsUpdatedConcurrentTimes(&lastUpdate); ASSERT_TRUE(map1.has_value()); Loading Loading @@ -299,7 +307,7 @@ TEST(TimeInStateTest, AllUidUpdatedConcurrentTimes) { } } TEST(TimeInStateTest, SingleAndAllUidConcurrentTimesConsistent) { TEST_F(TimeInStateTest, SingleAndAllUidConcurrentTimesConsistent) { uint64_t zero = 0; auto maps = {getUidsConcurrentTimes(), getUidsUpdatedConcurrentTimes(&zero)}; for (const auto &map : maps) { Loading Loading @@ -328,7 +336,7 @@ void TestCheckDelta(uint64_t before, uint64_t after) { ASSERT_LE(after - before, NSEC_PER_SEC * 2 * get_nprocs_conf()); } TEST(TimeInStateTest, TotalTimeInStateMonotonic) { TEST_F(TimeInStateTest, TotalTimeInStateMonotonic) { auto before = getTotalCpuFreqTimes(); ASSERT_TRUE(before.has_value()); sleep(1); Loading @@ -344,7 +352,7 @@ TEST(TimeInStateTest, TotalTimeInStateMonotonic) { } } TEST(TimeInStateTest, AllUidTimeInStateMonotonic) { TEST_F(TimeInStateTest, AllUidTimeInStateMonotonic) { auto map1 = getUidsCpuFreqTimes(); ASSERT_TRUE(map1.has_value()); sleep(1); Loading @@ -365,7 +373,7 @@ TEST(TimeInStateTest, AllUidTimeInStateMonotonic) { } } TEST(TimeInStateTest, AllUidConcurrentTimesMonotonic) { TEST_F(TimeInStateTest, AllUidConcurrentTimesMonotonic) { auto map1 = getUidsConcurrentTimes(); ASSERT_TRUE(map1.has_value()); ASSERT_FALSE(map1->empty()); Loading Loading @@ -393,7 +401,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimesMonotonic) { } } TEST(TimeInStateTest, AllUidTimeInStateSanityCheck) { TEST_F(TimeInStateTest, AllUidTimeInStateSanityCheck) { uint64_t zero = 0; auto maps = {getUidsCpuFreqTimes(), getUidsUpdatedCpuFreqTimes(&zero)}; for (const auto &map : maps) { Loading @@ -414,7 +422,7 @@ TEST(TimeInStateTest, AllUidTimeInStateSanityCheck) { } } TEST(TimeInStateTest, AllUidConcurrentTimesSanityCheck) { TEST_F(TimeInStateTest, AllUidConcurrentTimesSanityCheck) { uint64_t zero = 0; auto maps = {getUidsConcurrentTimes(), getUidsUpdatedConcurrentTimes(&zero)}; for (const auto &concurrentMap : maps) { Loading @@ -441,7 +449,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimesSanityCheck) { } } TEST(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) { TEST_F(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) { uint32_t uid = 0; { // Find an unused UID Loading @@ -463,7 +471,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) { ASSERT_FALSE(deleteMapEntry(fd, &key)); } TEST(TimeInStateTest, AllUidTimesConsistent) { TEST_F(TimeInStateTest, AllUidTimesConsistent) { auto tisMap = getUidsCpuFreqTimes(); ASSERT_TRUE(tisMap.has_value()); Loading @@ -481,7 +489,7 @@ TEST(TimeInStateTest, AllUidTimesConsistent) { } } TEST(TimeInStateTest, RemoveUid) { TEST_F(TimeInStateTest, RemoveUid) { uint32_t uid = 0; { // Find an unused UID Loading Loading @@ -547,7 +555,7 @@ TEST(TimeInStateTest, RemoveUid) { ASSERT_EQ(allConcurrentTimes->find(uid), allConcurrentTimes->end()); } TEST(TimeInStateTest, GetCpuFreqs) { TEST_F(TimeInStateTest, GetCpuFreqs) { auto freqs = getCpuFreqs(); ASSERT_TRUE(freqs.has_value()); Loading Loading @@ -583,7 +591,7 @@ void *testThread(void *) { return nullptr; } TEST(TimeInStateTest, GetAggregatedTaskCpuFreqTimes) { TEST_F(TimeInStateTest, GetAggregatedTaskCpuFreqTimes) { uint64_t startTimeNs = timeNanos(); sem_init(&pingsem, 0, 1); Loading
libs/renderengine/tests/RenderEngineTest.cpp +190 −135 Original line number Diff line number Diff line Loading @@ -49,6 +49,50 @@ constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false; namespace android { namespace renderengine { namespace { double EOTF_PQ(double channel) { float m1 = (2610.0 / 4096.0) / 4.0; float m2 = (2523.0 / 4096.0) * 128.0; float c1 = (3424.0 / 4096.0); float c2 = (2413.0 / 4096.0) * 32.0; float c3 = (2392.0 / 4096.0) * 32.0; float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2); tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp); return std::pow(tmp, 1.0 / m1); } vec3 EOTF_PQ(vec3 color) { return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b)); } double EOTF_HLG(double channel) { const float a = 0.17883277; const float b = 0.28466892; const float c = 0.55991073; return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0; } vec3 EOTF_HLG(vec3 color) { return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b)); } double OETF_sRGB(double channel) { return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055; } int sign(float in) { return in >= 0.0 ? 1 : -1; } vec3 OETF_sRGB(vec3 linear) { return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g), sign(linear.b) * OETF_sRGB(linear.b)); } } // namespace class RenderEngineFactory { public: virtual ~RenderEngineFactory() = default; Loading Loading @@ -598,6 +642,12 @@ public: const renderengine::ShadowSettings& shadow, const ubyte4& backgroundColor); // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU // implementations are identical Also implicitly checks that the injected tonemap shader // compiles void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf, std::function<vec3(vec3, float)> scaleOotf); void initializeRenderEngine(); std::unique_ptr<renderengine::RenderEngine> mRE; Loading Loading @@ -1418,6 +1468,119 @@ void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds, invokeDraw(settings, layers); } void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf, std::function<vec3(vec3, float)> scaleOotf) { constexpr int32_t kGreyLevels = 256; const auto rect = Rect(0, 0, kGreyLevels, 1); constexpr float kMaxLuminance = 750.f; constexpr float kCurrentLuminanceNits = 500.f; const renderengine::DisplaySettings display{ .physicalDisplay = rect, .clip = rect, .maxLuminance = kMaxLuminance, .currentLuminanceNits = kCurrentLuminanceNits, .outputDataspace = ui::Dataspace::DISPLAY_P3, }; auto buf = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "input"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, buf->getBuffer()->initCheck()); { uint8_t* pixels; buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&pixels)); uint8_t color = 0; for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) { uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4); for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) { dest[0] = color; dest[1] = color; dest[2] = color; dest[3] = 255; color++; dest += 4; } } buf->getBuffer()->unlock(); } mBuffer = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "output"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, mBuffer->getBuffer()->initCheck()); const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = std::move(buf), .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = sourceDataspace}; std::vector<renderengine::LayerSettings> layers{layer}; invokeDraw(display, layers); ColorSpace displayP3 = ColorSpace::DisplayP3(); ColorSpace bt2020 = ColorSpace::BT2020(); tonemap::Metadata metadata{.displayMaxLuminance = 750.0f}; auto generator = [=](Point location) { const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1); const vec3 rgb = vec3(normColor, normColor, normColor); const vec3 linearRGB = eotf(rgb); const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB; const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits); const double gain = tonemap::getToneMapper() ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common:: Dataspace>(sourceDataspace), static_cast<aidl::android::hardware::graphics::common:: Dataspace>( ui::Dataspace::DISPLAY_P3), scaleOotf(linearRGB, kCurrentLuminanceNits), scaledXYZ, metadata); const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance; const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255; return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g), static_cast<uint8_t>(targetRGB.b), 255); }; expectBufferColor(Rect(kGreyLevels, 1), generator, 2); } INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest, testing::Values(std::make_shared<GLESRenderEngineFactory>(), std::make_shared<GLESCMRenderEngineFactory>(), Loading Loading @@ -2412,155 +2575,47 @@ TEST_P(RenderEngineTest, test_isOpaque) { } } double EOTF_PQ(double channel) { float m1 = (2610.0 / 4096.0) / 4.0; float m2 = (2523.0 / 4096.0) * 128.0; float c1 = (3424.0 / 4096.0); float c2 = (2413.0 / 4096.0) * 32.0; float c3 = (2392.0 / 4096.0) * 32.0; float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2); tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp); return std::pow(tmp, 1.0 / m1); } vec3 EOTF_PQ(vec3 color) { return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b)); TEST_P(RenderEngineTest, test_tonemapPQMatches) { if (!GetParam()->useColorManagement()) { GTEST_SKIP(); } double OETF_sRGB(double channel) { return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055; if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { GTEST_SKIP(); } int sign(float in) { return in >= 0.0 ? 1 : -1; } initializeRenderEngine(); vec3 OETF_sRGB(vec3 linear) { return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g), sign(linear.b) * OETF_sRGB(linear.b)); tonemap( static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL), [](vec3 color) { return EOTF_PQ(color); }, [](vec3 color, float) { static constexpr float kMaxPQLuminance = 10000.f; return color * kMaxPQLuminance; }); } TEST_P(RenderEngineTest, test_tonemapPQMatches) { TEST_P(RenderEngineTest, test_tonemapHLGMatches) { if (!GetParam()->useColorManagement()) { return; GTEST_SKIP(); } if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) { return; GTEST_SKIP(); } initializeRenderEngine(); constexpr int32_t kGreyLevels = 256; const auto rect = Rect(0, 0, kGreyLevels, 1); const renderengine::DisplaySettings display{ .physicalDisplay = rect, .clip = rect, .maxLuminance = 750.0f, .outputDataspace = ui::Dataspace::DISPLAY_P3, }; auto buf = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "input"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, buf->getBuffer()->initCheck()); { uint8_t* pixels; buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&pixels)); uint8_t color = 0; for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) { uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4); for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) { dest[0] = color; dest[1] = color; dest[2] = color; dest[3] = 255; color++; dest += 4; } } buf->getBuffer()->unlock(); } mBuffer = std::make_shared< renderengine::impl:: ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, "output"), *mRE, renderengine::impl::ExternalTexture::Usage::READABLE | renderengine::impl::ExternalTexture::Usage::WRITEABLE); ASSERT_EQ(0, mBuffer->getBuffer()->initCheck()); const renderengine::LayerSettings layer{ .geometry.boundaries = rect.toFloatRect(), .source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = std::move(buf), .usePremultipliedAlpha = true, }, }, .alpha = 1.0f, .sourceDataspace = static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL), }; std::vector<renderengine::LayerSettings> layers{layer}; invokeDraw(display, layers); ColorSpace displayP3 = ColorSpace::DisplayP3(); ColorSpace bt2020 = ColorSpace::BT2020(); tonemap::Metadata metadata{.displayMaxLuminance = 750.0f}; auto generator = [=](Point location) { const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1); const vec3 rgb = vec3(normColor, normColor, normColor); const vec3 linearRGB = EOTF_PQ(rgb); static constexpr float kMaxPQLuminance = 10000.f; const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB * kMaxPQLuminance; const double gain = tonemap::getToneMapper() ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common:: Dataspace>( HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | tonemap( static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG | HAL_DATASPACE_RANGE_FULL), static_cast<aidl::android::hardware::graphics::common:: Dataspace>( ui::Dataspace::DISPLAY_P3), linearRGB * 10000.0, xyz, metadata); const vec3 scaledXYZ = xyz * gain / metadata.displayMaxLuminance; const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * scaledXYZ) * 255; return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g), static_cast<uint8_t>(targetRGB.b), 255); }; expectBufferColor(Rect(kGreyLevels, 1), generator, 2); [](vec3 color) { return EOTF_HLG(color); }, [](vec3 color, float currentLuminaceNits) { static constexpr float kMaxHLGLuminance = 1000.f; static const float kHLGGamma = 1.2 + 0.42 * std::log10(currentLuminaceNits / 1000); return color * kMaxHLGLuminance * std::pow(color.y, kHLGGamma - 1); }); } TEST_P(RenderEngineTest, r8_behaves_as_mask) { Loading