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

Commit 3c51bc50 authored by Alec Mouri's avatar Alec Mouri
Browse files

Improve tonemapping utilities

* Add util for getting buffer dataspace from metadata, since some
  ANativeWindow queries are unreliable when Surface endpoints are passed
  between processes, e.g., camera
* Let libshaders generate SkSL for SkColorFilters

Bug: 238395777
Test: Switching HDR cameras don't color shift
Change-Id: I7c3b917eeafcf8d028f8f52f38aa1389025bc607
parent 89ea6a91
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -702,6 +702,14 @@ uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t ahardwarebuffer_format) {
    return ahardwarebuffer_format;
}

int32_t AHardwareBuffer_getDataSpace(AHardwareBuffer* buffer) {
    GraphicBuffer* gb = AHardwareBuffer_to_GraphicBuffer(buffer);
    auto& mapper = GraphicBufferMapper::get();
    ui::Dataspace dataspace = ui::Dataspace::UNKNOWN;
    mapper.getDataspace(gb->handle, &dataspace);
    return static_cast<int32_t>(dataspace);
}

uint64_t AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage) {
    using android::hardware::graphics::common::V1_1::BufferUsage;
    static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_NEVER == (uint64_t)BufferUsage::CPU_READ_NEVER,
+5 −0
Original line number Diff line number Diff line
@@ -52,6 +52,11 @@ uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format);
// convert HAL format to AHardwareBuffer format (note: this is a no-op)
uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format);

// retrieves a dataspace from the AHardwareBuffer metadata, if the device
// support gralloc metadata. Returns UNKNOWN if gralloc metadata is not
// supported.
int32_t AHardwareBuffer_getDataSpace(AHardwareBuffer* buffer);

// convert AHardwareBuffer usage bits to HAL usage bits (note: this is a no-op)
uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage);

+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ LIBNATIVEWINDOW_PLATFORM {
      android::AHardwareBuffer_convertToPixelFormat*;
      android::AHardwareBuffer_convertFromGrallocUsageBits*;
      android::AHardwareBuffer_convertToGrallocUsageBits*;
      android::AHardwareBuffer_getDataSpace*;
      android::AHardwareBuffer_to_GraphicBuffer*;
      android::AHardwareBuffer_to_ANativeWindowBuffer*;
      android::AHardwareBuffer_from_GraphicBuffer*;
+7 −0
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ struct LinearEffect {
    // fakeInputDataspace is used to essentially masquerade the input dataspace to be the output
    // dataspace for correct conversion to linear colors.
    ui::Dataspace fakeInputDataspace = ui::Dataspace::UNKNOWN;

    enum SkSLType { Shader, ColorFilter };
    SkSLType type = Shader;
};

static inline bool operator==(const LinearEffect& lhs, const LinearEffect& rhs) {
@@ -96,6 +99,10 @@ struct LinearEffectHasher {
// 2. Apply color transform matrices in linear space
std::string buildLinearEffectSkSL(const LinearEffect& linearEffect);

// Generates a shader string that applies color transforms in linear space.
// This is intended to be plugged into an SkColorFilter
std::string buildLinearEffectSkSLForColorFilter(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,
+18 −7
Original line number Diff line number Diff line
@@ -386,12 +386,23 @@ void generateOETF(ui::Dataspace dataspace, std::string& shader) {
    }
}

void generateEffectiveOOTF(bool undoPremultipliedAlpha, std::string& shader) {
void generateEffectiveOOTF(bool undoPremultipliedAlpha, LinearEffect::SkSLType type,
                           std::string& shader) {
    switch (type) {
        case LinearEffect::SkSLType::ColorFilter:
            shader.append(R"(
                half4 main(half4 inputColor) {
                    float4 c = float4(inputColor);
            )");
            break;
        case LinearEffect::SkSLType::Shader:
            shader.append(R"(
                uniform shader child;
                half4 main(float2 xy) {
                    float4 c = float4(child.eval(xy));
            )");
            break;
    }
    if (undoPremultipliedAlpha) {
        shader.append(R"(
            c.rgb = c.rgb / (c.a + 0.0019);
@@ -459,7 +470,7 @@ std::string buildLinearEffectSkSL(const LinearEffect& linearEffect) {
    generateXYZTransforms(shaderString);
    generateOOTF(linearEffect.inputDataspace, linearEffect.outputDataspace, shaderString);
    generateOETF(linearEffect.outputDataspace, shaderString);
    generateEffectiveOOTF(linearEffect.undoPremultipliedAlpha, shaderString);
    generateEffectiveOOTF(linearEffect.undoPremultipliedAlpha, linearEffect.type, shaderString);
    return shaderString;
}