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

Commit a4bea0ea authored by Dan Stoza's avatar Dan Stoza
Browse files

Add generic layer metadata to Composer 2.4

Bug: 139747351
Test: VtsHalGraphicsComposerV2_4TargetTest
Test: Manual verification with a modified Composer implementation
Change-Id: I800841ab1348a93c73c25c5f8bcf2254d9dc22e8
parent fdb6b518
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -71,6 +71,51 @@ interface IComposerClient extends @2.3::IComposerClient {
         *   setClientTargetProperty(ClientTargetProperty clientTargetProperty);
         */
         SET_CLIENT_TARGET_PROPERTY = 0x105 << @2.1::IComposerClient.Command:OPCODE_SHIFT,

        /**
         * SET_LAYER_GENERIC_METADATA has this pseudo prototype
         *
         *   setLayerGenericMetadata(string key, bool mandatory, vec<uint8_t> value);
         *
         * Sets a piece of generic metadata for the given layer. If this
         * function is called twice with the same key but different values, the
         * newer value must override the older one. Calling this function with a
         * 0-length value must reset that key's metadata as if it had not been
         * set.
         *
         * A given piece of metadata may either be mandatory or a hint
         * (non-mandatory) as indicated by the second parameter. Mandatory
         * metadata may affect the composition result, which is to say that it
         * may cause a visible change in the final image. By contrast, hints may
         * only affect the composition strategy, such as which layers are
         * composited by the client, but must not cause a visible change in the
         * final image. The value of the mandatory flag shall match the value
         * returned from getLayerGenericMetadataKeys for the given key.
         *
         * Only keys which have been returned from getLayerGenericMetadataKeys()
         * shall be accepted. Any other keys must result in an UNSUPPORTED error.
         *
         * The value passed into this function shall be the binary
         * representation of a HIDL type corresponding to the given key. For
         * example, a key of 'com.example.V1_3.Foo' shall be paired with a
         * value of type com.example@1.3::Foo, which would be defined in a
         * vendor HAL extension.
         *
         * This function will be encoded in the command buffer in this order:
         *   1) The key length, stored as a uint32_t
         *   2) The key itself, padded to a uint32_t boundary if necessary
         *   3) The mandatory flag, stored as a uint32_t
         *   4) The value length in bytes, stored as a uint32_t
         *   5) The value itself, padded to a uint32_t boundary if necessary
         *
         * @param key indicates which metadata value should be set on this layer
         * @param mandatory indicates whether this particular key represents
         *        mandatory metadata or a hint (non-mandatory metadata), as
         *        described above
         * @param value is a binary representation of a HIDL struct
         *        corresponding to the key as described above
         */
        SET_LAYER_GENERIC_METADATA = 0x40e << @2.1::IComposerClient.Command:OPCODE_SHIFT,
    };

    /**
@@ -271,4 +316,33 @@ interface IComposerClient extends @2.3::IComposerClient {
     */
    setContentType(Display display, ContentType type)
        generates (Error error);

    struct LayerGenericMetadataKey {
        /**
         * Key names must comply with the requirements specified for
         * getLayerGenericMetadataKeys below
         */
        string name;

        /**
         * The mandatory flag is defined in the description of
         * setLayerGenericMetadata above
         */
        bool mandatory;
    };

    /**
     * Retrieves the set of keys that may be passed into setLayerGenericMetadata
     *
     * Key names must meet the following requirements:
     * - Must be specified in reverse domain name notation
     * - Must not start with 'com.android' or 'android'
     * - Must be unique within the returned vector
     * - Must correspond to a matching HIDL struct type, which defines the
     *   structure of its values. For example, the key 'com.example.V1-3.Foo'
     *   should correspond to a value of type com.example@1.3::Foo, which is
     *   defined in a vendor HAL extension
     */
    getLayerGenericMetadataKeys()
        generates(Error error, vec<LayerGenericMetadataKey> keys);
};
+21 −0
Original line number Diff line number Diff line
@@ -53,6 +53,27 @@ class CommandWriterBase : public V2_3::CommandWriterBase {
        writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace));
        endCommand();
    }

    void setLayerGenericMetadata(const hidl_string& key, const bool mandatory,
                                 const hidl_vec<uint8_t>& value) {
        const size_t commandSize = 3 + sizeToElements(key.size()) + sizeToElements(value.size());
        if (commandSize > std::numeric_limits<uint16_t>::max()) {
            LOG_FATAL("Too much generic metadata (%zu elements)", commandSize);
            return;
        }

        beginCommand(IComposerClient::Command::SET_LAYER_GENERIC_METADATA,
                     static_cast<uint16_t>(commandSize));
        write(key.size());
        writeBlob(key.size(), reinterpret_cast<const unsigned char*>(key.c_str()));
        write(mandatory);
        write(value.size());
        writeBlob(value.size(), value.data());
        endCommand();
    }

  protected:
    uint32_t sizeToElements(uint32_t size) { return (size + 3) / 4; }
};

// This class helps parse a command queue.  Note that all sizes/lengths are in
+8 −0
Original line number Diff line number Diff line
@@ -164,6 +164,14 @@ class ComposerClientImpl : public V2_3::hal::detail::ComposerClientImpl<Interfac
        return mHal->setContentType(display, contentType);
    }

    Return<void> getLayerGenericMetadataKeys(
            IComposerClient::getLayerGenericMetadataKeys_cb hidl_cb) override {
        std::vector<IComposerClient::LayerGenericMetadataKey> keys;
        Error error = mHal->getLayerGenericMetadataKeys(&keys);
        hidl_cb(error, keys);
        return Void();
    }

    static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
        auto client = std::make_unique<ComposerClientImpl>(hal);
        return client->init() ? std::move(client) : nullptr;
+37 −0
Original line number Diff line number Diff line
@@ -74,6 +74,43 @@ class ComposerCommandEngine : public V2_3::hal::ComposerCommandEngine {

    CommandWriterBase* getWriter() { return static_cast<CommandWriterBase*>(mWriter.get()); }

    bool executeCommand(V2_1::IComposerClient::Command command, uint16_t length) override {
        switch (static_cast<IComposerClient::Command>(command)) {
            case IComposerClient::Command::SET_LAYER_GENERIC_METADATA:
                return executeSetLayerGenericMetadata(length);
            default:
                return BaseType2_3::executeCommand(command, length);
        }
    }

    bool executeSetLayerGenericMetadata(uint16_t length) {
        // We expect at least two buffer lengths and a mandatory flag
        if (length < 3) {
            return false;
        }

        const uint32_t keySize = read();
        std::string key;
        key.resize(keySize);
        readBlob(keySize, key.data());

        const bool mandatory = read();

        const uint32_t valueSize = read();
        std::vector<uint8_t> value(valueSize);
        readBlob(valueSize, value.data());

        auto error = mHal->setLayerGenericMetadata(mCurrentDisplay, mCurrentLayer, key, mandatory,
                                                   value);
        if (error != Error::NONE) {
            // The error cast is safe because setLayerGenericMetadata doesn't
            // return any of the new values added in V2_4::Error
            mWriter->setError(getCommandLoc(), static_cast<V2_1::Error>(error));
        }

        return true;
    }

    ComposerHal* mHal;
};

+4 −0
Original line number Diff line number Diff line
@@ -79,6 +79,10 @@ class ComposerHal : public V2_3::hal::ComposerHal {
            uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
            std::vector<uint32_t>* outRequestMasks,
            IComposerClient::ClientTargetProperty* outClientTargetProperty) = 0;
    virtual Error setLayerGenericMetadata(Display display, Layer layer, const std::string& key,
                                          bool mandatory, const std::vector<uint8_t>& value) = 0;
    virtual Error getLayerGenericMetadataKeys(
            std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) = 0;
};

}  // namespace hal
Loading