Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5dc8fb88 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8139020 from c4b5a89b to tm-d1-release

Change-Id: Ifd35bd1570e73574f454456d58e8aee404648678
parents c93cf9e8 c4b5a89b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
    }
+1 −0
Original line number Diff line number Diff line
@@ -45,4 +45,5 @@ cc_test {
        "-Wextra",
    ],
    require_root: true,
    test_suites: ["general-tests"],
}
+7 −0
Original line number Diff line number Diff line
{
  "presubmit": [
    {
      "name": "libtimeinstate_test"
    }
  ]
}
+33 −25
Original line number Diff line number Diff line
@@ -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>
@@ -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());
@@ -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());

@@ -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) {
@@ -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());
@@ -197,7 +205,7 @@ TEST(TimeInStateTest, AllUidUpdatedTimeInState) {
    }
}

TEST(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) {
TEST_F(TimeInStateTest, TotalAndAllUidTimeInStateConsistent) {
    auto allUid = getUidsCpuFreqTimes();
    auto total = getTotalCpuFreqTimes();

@@ -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) {
@@ -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) {
@@ -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());
@@ -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) {
@@ -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);
@@ -344,7 +352,7 @@ TEST(TimeInStateTest, TotalTimeInStateMonotonic) {
    }
}

TEST(TimeInStateTest, AllUidTimeInStateMonotonic) {
TEST_F(TimeInStateTest, AllUidTimeInStateMonotonic) {
    auto map1 = getUidsCpuFreqTimes();
    ASSERT_TRUE(map1.has_value());
    sleep(1);
@@ -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());
@@ -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) {
@@ -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) {
@@ -441,7 +449,7 @@ TEST(TimeInStateTest, AllUidConcurrentTimesSanityCheck) {
    }
}

TEST(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) {
TEST_F(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) {
    uint32_t uid = 0;
    {
        // Find an unused UID
@@ -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());

@@ -481,7 +489,7 @@ TEST(TimeInStateTest, AllUidTimesConsistent) {
    }
}

TEST(TimeInStateTest, RemoveUid) {
TEST_F(TimeInStateTest, RemoveUid) {
    uint32_t uid = 0;
    {
        // Find an unused UID
@@ -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());

@@ -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);
+190 −135
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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>(),
@@ -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