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

Commit c25748d2 authored by Valerie Hau's avatar Valerie Hau
Browse files

Adding HDR10+ Dynamic Metadata Support

Bug: 118343714
Test: build, flash, boot
Test: VtsGraphicsComposerV2_3TargetTest should pass
Change-Id: Iee78818bc2704f4045b62251ea2cc75af72a0609
parent 2d4d55c9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -16,11 +16,20 @@

package android.hardware.graphics.common@1.2;

import @1.0::Hdr;
import @1.1::BufferUsage;
import @1.1::ColorMode;
import @1.1::Dataspace;
import @1.1::PixelFormat;

/**
 * Hdr
 */
@export(name="android_hdr_v1_2_t", value_prefix="HAL_HDR_")
enum Hdr : @1.0::Hdr {
    HDR10_PLUS = 4,
};

@export(name="android_dataspace_v1_2_t", value_prefix="HAL_DATASPACE_",
        export_parent="false")
enum Dataspace : @1.1::Dataspace {
+6 −5
Original line number Diff line number Diff line
@@ -534,6 +534,9 @@ class CommandWriterBase {

    static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();

    std::unique_ptr<uint32_t[]> mData;
    uint32_t mDataWritten;

   private:
    void growData(uint32_t grow) {
        uint32_t newWritten = mDataWritten + grow;
@@ -558,9 +561,6 @@ class CommandWriterBase {
    }

    uint32_t mDataMaxSize;
    std::unique_ptr<uint32_t[]> mData;

    uint32_t mDataWritten;
    // end offset of the current command
    uint32_t mCommandEnd;

@@ -746,13 +746,14 @@ class CommandReaderBase {
        return fd;
    }

    std::unique_ptr<uint32_t[]> mData;
    uint32_t mDataRead;

   private:
    std::unique_ptr<CommandQueueType> mQueue;
    uint32_t mDataMaxSize;
    std::unique_ptr<uint32_t[]> mData;

    uint32_t mDataSize;
    uint32_t mDataRead;

    // begin/end offsets of the current command
    uint32_t mCommandBegin;
+99 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.hardware.graphics.common@1.1::RenderIntent;
import android.hardware.graphics.common@1.1::PixelFormat;
import android.hardware.graphics.common@1.2::ColorMode;
import android.hardware.graphics.common@1.2::Dataspace;
import android.hardware.graphics.common@1.2::Hdr;
import android.hardware.graphics.composer@2.1::IComposerClient.Command;
import @2.2::IComposerClient;
import @2.1::Display;
@@ -27,7 +28,7 @@ import @2.1::Error;

interface IComposerClient extends @2.2::IComposerClient {

    // TODO: Move this enum to LLNDK after we decide where to put graphic types.
    // Bug: Move this enum to LLNDK after we decide where to put graphic types.
    /**
     * Required capabilities which are supported by the display. The
     * particular set of supported capabilities for a given display may be
@@ -63,6 +64,48 @@ interface IComposerClient extends @2.2::IComposerClient {
        DOZE = 2,
    };

    //Bug: Move this enum to LLNDK after we decide where to put graphic types.
    /**
     * PerFrameMetadataKey
     *
     * A set of PerFrameMetadataKey pertains specifically to blob-formatted
     * metadata (as opposed to float-valued metadata).
     * The list of keys that represent blobs are:
     * 1. HDR10_PLUS_SEI
     */
    enum PerFrameMetadataKey : @2.2::IComposerClient.PerFrameMetadataKey {
        /**HDR10+ metadata
         * Specifies a metadata blob adhering to
         * the ST2094-40 SEI message spec, Version 1.0
         */
        HDR10_PLUS_SEI,
    };

    /**
     * PerFrameMetadata
     * This struct encapsulates float-valued
     * metadata - key must not be in the list
     * of keys representing blob-formatted metadata
     * (see PerFrameMetadataKey)
     */
    struct PerFrameMetadata {
        PerFrameMetadataKey key;
        float value;
    };

    /**
     * PerFrameMetadataBlob
     * This struct encapsulates blob
     * metadata - key must be one of the list of keys
     * associated with blob-type metadata key
     * and the blob must adhere to the format specified by
     * that key (See PerFrameMetadataKey).
     */
    struct PerFrameMetadataBlob {
        PerFrameMetadataKey key;
        vec<uint8_t> blob;
    };

    enum Command : @2.2::IComposerClient.Command {
        /**
         * SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
@@ -106,6 +149,22 @@ interface IComposerClient extends @2.2::IComposerClient {
         * @param matrix is a 4x4 transform matrix (16 floats) as described above.
         */
        SET_LAYER_COLOR_TRANSFORM = 0x40d << @2.1::IComposerClient.Command:OPCODE_SHIFT,

        /* SET_LAYER_PER_FRAME_METADATA_BLOBS has this pseudo prototype
         *
         *   setLayerPerFrameMetadataBlobs(Display display, Layer layer,
         *                                   vec<PerFrameMetadataBlob> metadata);
         *
         *   This command sends metadata that may be used for tone-mapping the
         *   associated layer.  The metadata structure follows a {key, blob}
         *   format (see the PerFrameMetadataBlob struct).  All keys must be
         *   returned by a prior call to getPerFrameMetadataKeys and must
         *   be part of the list of keys associated with blob-type metadata
         *   (see PerFrameMetadataKey).
         *
         *   This method may be called every frame.
         */
        SET_LAYER_PER_FRAME_METADATA_BLOBS = 0x304 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
    };

    /**
@@ -399,4 +458,43 @@ interface IComposerClient extends @2.2::IComposerClient {
    getDisplayCapabilities(Display display)
              generates (Error error,
                         vec<DisplayCapability> capabilities);

    /**
     * Returns the PerFrameMetadataKeys that are supported by this device.
     *
     * @param display is the display on which to create the layer.
     * @return keys is the vector of PerFrameMetadataKey keys that are
     *        supported by this device.
     * @return error is NONE upon success. Otherwise,
     *         UNSUPPORTED if not supported on underlying HAL
     */
    getPerFrameMetadataKeys_2_3(Display display)
          generates (Error error,
                     vec<PerFrameMetadataKey> keys);

    /**
     * Returns the high dynamic range (HDR) capabilities of the given display,
     * which are invariant with regard to the active configuration.
     *
     * Displays which are not HDR-capable must return no types.
     *
     * @param display is the display to query.
     * @return error is NONE upon success. Otherwise,
     *         BAD_DISPLAY when an invalid display handle was passed in.
     * @return types is an array of HDR types, may have 0 elements if the
     *         display is not HDR-capable.
     * @return maxLuminance is the desired content maximum luminance for this
     *         display in cd/m^2.
     * @return maxAverageLuminance - the desired content maximum frame-average
     *         luminance for this display in cd/m^2.
     * @return minLuminance is the desired content minimum luminance for this
     *         display in cd/m^2.
     */
    @callflow(next="*")
    getHdrCapabilities_2_3(Display display)
            generates (Error error,
                       vec<Hdr> types,
                       float maxLuminance,
                       float maxAverageLuminance,
                       float minLuminance);
};
+59 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <android/hardware/graphics/composer/2.3/IComposer.h>
#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
#include <limits>

namespace android {
namespace hardware {
@@ -44,6 +45,16 @@ using android::hardware::graphics::composer::V2_3::IComposerClient;
// units of uint32_t's.
class CommandWriterBase : public V2_2::CommandWriterBase {
   public:
    void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
        beginCommand_2_3(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
                         metadataVec.size() * 2);
        for (const auto& metadata : metadataVec) {
            writeSigned(static_cast<int32_t>(metadata.key));
            writeFloat(metadata.value);
        }
        endCommand();
    }

    void setLayerDataspace(Dataspace dataspace) {
        setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
    }
@@ -66,11 +77,59 @@ class CommandWriterBase : public V2_2::CommandWriterBase {
        endCommand();
    }

    void setLayerPerFrameMetadataBlobs(
        const hidl_vec<IComposerClient::PerFrameMetadataBlob>& metadata) {
        size_t commandLength = 0;

        if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
            LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
            return;
        }

        // number of blobs
        commandLength += metadata.size();

        for (auto metadataBlob : metadata) {
            commandLength += sizeof(int32_t);  // key of metadata blob
            commandLength += 1;                // size information of metadata blob

            // metadata content size
            size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
            commandLength += metadataSize;
            commandLength +=
                (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
        }

        if (commandLength > std::numeric_limits<uint16_t>::max()) {
            LOG_FATAL("dynamic metadata size is too large");
            return;
        }

        // Blobs are written as:
        // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
        uint16_t length = static_cast<uint16_t>(commandLength);
        beginCommand_2_3(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
        write(static_cast<uint32_t>(metadata.size()));
        for (auto metadataBlob : metadata) {
            writeSigned(static_cast<int32_t>(metadataBlob.key));
            write(static_cast<uint32_t>(metadataBlob.blob.size()));
            writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
        }
        endCommand();
    }

   protected:
    void beginCommand_2_3(IComposerClient::Command command, uint16_t length) {
        V2_2::CommandWriterBase::beginCommand_2_2(
            static_cast<V2_2::IComposerClient::Command>(static_cast<int32_t>(command)), length);
    }

    void writeBlob(uint32_t length, const unsigned char* blob) {
        memcpy(&mData[mDataWritten], blob, length);
        uint32_t numElements = length / 4;
        mDataWritten += numElements;
        mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
    }
};

// This class helps parse a command queue.  Note that all sizes/lengths are in
+28 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#endif

#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
#include <composer-hal/2.2/ComposerResources.h>
#include <composer-hal/2.3/ComposerClient.h>
#include <composer-hal/2.3/ComposerCommandEngine.h>
#include <composer-hal/2.3/ComposerHal.h>
@@ -38,6 +39,14 @@ namespace detail {
template <typename Interface, typename Hal>
class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interface, Hal> {
   public:
    Return<void> getPerFrameMetadataKeys_2_3(
        Display display, IComposerClient::getPerFrameMetadataKeys_2_3_cb hidl_cb) override {
        std::vector<IComposerClient::PerFrameMetadataKey> keys;
        Error error = mHal->getPerFrameMetadataKeys_2_3(display, &keys);
        hidl_cb(error, keys);
        return Void();
    }

    Return<Error> setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
        return mHal->setColorMode_2_3(display, mode, intent);
    }
@@ -67,6 +76,18 @@ class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interfac
        return Void();
    }

    Return<void> getHdrCapabilities_2_3(
        Display display, IComposerClient::getHdrCapabilities_2_3_cb hidl_cb) override {
        hidl_vec<Hdr> types;
        float max_lumi = 0.0f;
        float max_avg_lumi = 0.0f;
        float min_lumi = 0.0f;
        Error err =
            mHal->getHdrCapabilities_2_3(display, &types, &max_lumi, &max_avg_lumi, &min_lumi);
        hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
        return Void();
    }

    Return<Error> getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
                                             PixelFormat format, Dataspace dataspace) override {
        Error err = mHal->getClientTargetSupport_2_3(display, width, height, format, dataspace);
@@ -151,12 +172,19 @@ class ComposerClientImpl : public V2_2::hal::detail::ComposerClientImpl<Interfac
        return Void();
    }

   protected:
    std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
        return std::make_unique<ComposerCommandEngine>(
            mHal, static_cast<V2_2::hal::ComposerResources*>(mResources.get()));
    }

   private:
    using BaseType2_2 = V2_2::hal::detail::ComposerClientImpl<Interface, Hal>;
    using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
    using BaseType2_1::mCommandEngine;
    using BaseType2_1::mCommandEngineMutex;
    using BaseType2_1::mHal;
    using BaseType2_1::mResources;
};

}  // namespace detail
Loading