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

Commit 78211cf7 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

graphics: add ComposerCommandEngine

Add ComposerCommandEngine to the HAL support library to replace
ComposerClient::CommandReader and ComposerClient::mWriter.

Test: boots and VTS
Change-Id: I2d1281d37180497cbd5c623ef005cee44bce377e
parent 2d894af0
Loading
Loading
Loading
Loading
+13 −584
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ namespace V2_1 {
namespace implementation {

ComposerClient::ComposerClient(ComposerHal& hal)
    : mHal(hal), mWriter(kWriterInitialSize)
    : mHal(hal)
{
}

@@ -106,7 +106,7 @@ void ComposerClient::initialize()
        LOG_ALWAYS_FATAL("failed to create resources");
    }

    mReader = createCommandReader();
    mCommandEngine = createCommandEngine();
}

void ComposerClient::onHotplug(Display display,
@@ -333,8 +333,8 @@ Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
Return<Error> ComposerClient::setInputCommandQueue(
        const MQDescriptorSync<uint32_t>& descriptor)
{
    std::lock_guard<std::mutex> lock(mCommandMutex);
    return mReader->setMQDescriptor(descriptor) ?
    std::lock_guard<std::mutex> lock(mCommandEngineMutex);
    return mCommandEngine->setInputMQDescriptor(descriptor) ?
        Error::NONE : Error::NO_RESOURCES;
}

@@ -344,7 +344,7 @@ Return<void> ComposerClient::getOutputCommandQueue(
    // no locking as we require this function to be called inside
    // executeCommands_cb

    auto outDescriptor = mWriter.getMQDescriptor();
    auto outDescriptor = mCommandEngine->getOutputMQDescriptor();
    if (outDescriptor) {
        hidl_cb(Error::NONE, *outDescriptor);
    } else {
@@ -358,27 +358,17 @@ Return<void> ComposerClient::executeCommands(uint32_t inLength,
        const hidl_vec<hidl_handle>& inHandles,
        executeCommands_cb hidl_cb)
{
    std::lock_guard<std::mutex> lock(mCommandMutex);
    std::lock_guard<std::mutex> lock(mCommandEngineMutex);

    bool outChanged = false;
    uint32_t outLength = 0;
    hidl_vec<hidl_handle> outHandles;
    Error error = mCommandEngine->execute(inLength, inHandles,
            &outChanged, &outLength, &outHandles);

    if (!mReader->readQueue(inLength, inHandles)) {
        hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
        return Void();
    }

    Error err = mReader->parse();
    if (err == Error::NONE &&
            !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
        err = Error::NO_RESOURCES;
    }

    hidl_cb(err, outChanged, outLength, outHandles);
    hidl_cb(error, outChanged, outLength, outHandles);

    mReader->reset();
    mWriter.reset();
    mCommandEngine->reset();

    return Void();
}
@@ -388,571 +378,10 @@ std::unique_ptr<ComposerResources> ComposerClient::createResources()
    return ComposerResources::create();
}

std::unique_ptr<ComposerClient::CommandReader>
ComposerClient::createCommandReader()
{
    return std::unique_ptr<ComposerClient::CommandReader>(
        new CommandReader(*this));
}

ComposerClient::CommandReader::CommandReader(ComposerClient& client)
    : mHal(client.mHal), mResources(client.mResources.get()), mWriter(client.mWriter)
{
}

ComposerClient::CommandReader::~CommandReader()
{
}

Error ComposerClient::CommandReader::parse()
{
    IComposerClient::Command command;
    uint16_t length = 0;

    while (!isEmpty()) {
        if (!beginCommand(&command, &length)) {
            break;
        }

        bool parsed = parseCommand(command, length);
        endCommand();

        if (!parsed) {
            ALOGE("failed to parse command 0x%x, length %" PRIu16,
                    command, length);
            break;
        }
    }

    return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
}

bool ComposerClient::CommandReader::parseCommand(
        IComposerClient::Command command, uint16_t length) {
    switch (command) {
    case IComposerClient::Command::SELECT_DISPLAY:
        return parseSelectDisplay(length);
    case IComposerClient::Command::SELECT_LAYER:
        return parseSelectLayer(length);
    case IComposerClient::Command::SET_COLOR_TRANSFORM:
        return parseSetColorTransform(length);
    case IComposerClient::Command::SET_CLIENT_TARGET:
        return parseSetClientTarget(length);
    case IComposerClient::Command::SET_OUTPUT_BUFFER:
        return parseSetOutputBuffer(length);
    case IComposerClient::Command::VALIDATE_DISPLAY:
        return parseValidateDisplay(length);
    case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
        return parsePresentOrValidateDisplay(length);
    case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
        return parseAcceptDisplayChanges(length);
    case IComposerClient::Command::PRESENT_DISPLAY:
        return parsePresentDisplay(length);
    case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
        return parseSetLayerCursorPosition(length);
    case IComposerClient::Command::SET_LAYER_BUFFER:
        return parseSetLayerBuffer(length);
    case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
        return parseSetLayerSurfaceDamage(length);
    case IComposerClient::Command::SET_LAYER_BLEND_MODE:
        return parseSetLayerBlendMode(length);
    case IComposerClient::Command::SET_LAYER_COLOR:
        return parseSetLayerColor(length);
    case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
        return parseSetLayerCompositionType(length);
    case IComposerClient::Command::SET_LAYER_DATASPACE:
        return parseSetLayerDataspace(length);
    case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
        return parseSetLayerDisplayFrame(length);
    case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
        return parseSetLayerPlaneAlpha(length);
    case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
        return parseSetLayerSidebandStream(length);
    case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
        return parseSetLayerSourceCrop(length);
    case IComposerClient::Command::SET_LAYER_TRANSFORM:
        return parseSetLayerTransform(length);
    case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
        return parseSetLayerVisibleRegion(length);
    case IComposerClient::Command::SET_LAYER_Z_ORDER:
        return parseSetLayerZOrder(length);
    default:
        return false;
    }
}

bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
{
    if (length != CommandWriterBase::kSelectDisplayLength) {
        return false;
    }

    mDisplay = read64();
    mWriter.selectDisplay(mDisplay);

    return true;
}

bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
{
    if (length != CommandWriterBase::kSelectLayerLength) {
        return false;
    }

    mLayer = read64();

    return true;
}

bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
{
    if (length != CommandWriterBase::kSetColorTransformLength) {
        return false;
    }

    float matrix[16];
    for (int i = 0; i < 16; i++) {
        matrix[i] = readFloat();
    }
    auto transform = readSigned();

    auto err = mHal.setColorTransform(mDisplay, matrix, transform);
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
{
    // 4 parameters followed by N rectangles
    if ((length - 4) % 4 != 0) {
        return false;
    }

    bool useCache = false;
    auto slot = read();
    auto rawHandle = readHandle(&useCache);
    auto fence = readFence();
    auto dataspace = readSigned();
    auto damage = readRegion((length - 4) / 4);
    bool closeFence = true;

    const native_handle_t* clientTarget;
    ComposerResources::ReplacedBufferHandle replacedClientTarget;
    auto err = mResources->getDisplayClientTarget(mDisplay,
            slot, useCache, rawHandle, &clientTarget, &replacedClientTarget);
    if (err == Error::NONE) {
        err = mHal.setClientTarget(mDisplay, clientTarget, fence,
                dataspace, damage);
        if (err == Error::NONE) {
            closeFence = false;
        }
    }
    if (closeFence) {
        close(fence);
    }
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
{
    if (length != CommandWriterBase::kSetOutputBufferLength) {
        return false;
    }

    bool useCache = false;
    auto slot = read();
    auto rawhandle = readHandle(&useCache);
    auto fence = readFence();
    bool closeFence = true;

    const native_handle_t* outputBuffer;
    ComposerResources::ReplacedBufferHandle replacedOutputBuffer;
    auto err = mResources->getDisplayOutputBuffer(mDisplay,
            slot, useCache, rawhandle, &outputBuffer, &replacedOutputBuffer);
    if (err == Error::NONE) {
        err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
        if (err == Error::NONE) {
            closeFence = false;
        }
    }
    if (closeFence) {
        close(fence);
    }
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
{
    if (length != CommandWriterBase::kValidateDisplayLength) {
        return false;
    }

    std::vector<Layer> changedLayers;
    std::vector<IComposerClient::Composition> compositionTypes;
    uint32_t displayRequestMask = 0x0;
    std::vector<Layer> requestedLayers;
    std::vector<uint32_t> requestMasks;

    auto err = mHal.validateDisplay(mDisplay, &changedLayers,
            &compositionTypes, &displayRequestMask,
            &requestedLayers, &requestMasks);
    if (err == Error::NONE) {
        mWriter.setChangedCompositionTypes(changedLayers,
                compositionTypes);
        mWriter.setDisplayRequests(displayRequestMask,
                requestedLayers, requestMasks);
    } else {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length)
{
    if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
        return false;
    }

    // First try to Present as is.
    if (mHal.hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
        int presentFence = -1;
        std::vector<Layer> layers;
        std::vector<int> fences;
        auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
        if (err == Error::NONE) {
            mWriter.setPresentOrValidateResult(1);
            mWriter.setPresentFence(presentFence);
            mWriter.setReleaseFences(layers, fences);
            return true;
        }
    }

    // Present has failed. We need to fallback to validate
    std::vector<Layer> changedLayers;
    std::vector<IComposerClient::Composition> compositionTypes;
    uint32_t displayRequestMask = 0x0;
    std::vector<Layer> requestedLayers;
    std::vector<uint32_t> requestMasks;

    auto err = mHal.validateDisplay(mDisplay, &changedLayers, &compositionTypes,
                                    &displayRequestMask, &requestedLayers, &requestMasks);
    if (err == Error::NONE) {
        mWriter.setPresentOrValidateResult(0);
        mWriter.setChangedCompositionTypes(changedLayers,
                                           compositionTypes);
        mWriter.setDisplayRequests(displayRequestMask,
                                   requestedLayers, requestMasks);
    } else {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
{
    if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
        return false;
    }

    auto err = mHal.acceptDisplayChanges(mDisplay);
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
{
    if (length != CommandWriterBase::kPresentDisplayLength) {
        return false;
    }

    int presentFence = -1;
    std::vector<Layer> layers;
    std::vector<int> fences;
    auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
    if (err == Error::NONE) {
        mWriter.setPresentFence(presentFence);
        mWriter.setReleaseFences(layers, fences);
    } else {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
        return false;
    }

    auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
            readSigned(), readSigned());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerBufferLength) {
        return false;
    }

    bool useCache = false;
    auto slot = read();
    auto rawHandle = readHandle(&useCache);
    auto fence = readFence();
    bool closeFence = true;

    const native_handle_t* buffer;
    ComposerResources::ReplacedBufferHandle replacedBuffer;
    auto err = mResources->getLayerBuffer(mDisplay, mLayer,
            slot, useCache, rawHandle, &buffer, &replacedBuffer);
    if (err == Error::NONE) {
        err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
        if (err == Error::NONE) {
            closeFence = false;
        }
    }
    if (closeFence) {
        close(fence);
    }
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
{
    // N rectangles
    if (length % 4 != 0) {
        return false;
    }

    auto damage = readRegion(length / 4);
    auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerBlendModeLength) {
        return false;
    }

    auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerColorLength) {
        return false;
    }

    auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerCompositionType(
        uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
        return false;
    }

    auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerDataspaceLength) {
        return false;
    }

    auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
        return false;
    }

    auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
        return false;
    }

    auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
        return false;
    }

    auto rawHandle = readHandle();

    const native_handle_t* stream;
    ComposerResources::ReplacedStreamHandle replacedStream;
    auto err = mResources->getLayerSidebandStream(mDisplay, mLayer,
            rawHandle, &stream, &replacedStream);
    if (err == Error::NONE) {
        err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
    }
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerSourceCropLength) {
        return false;
    }

    auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerTransformLength) {
        return false;
    }

    auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
{
    // N rectangles
    if (length % 4 != 0) {
        return false;
    }

    auto region = readRegion(length / 4);
    auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
{
    if (length != CommandWriterBase::kSetLayerZOrderLength) {
        return false;
    }

    auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
    if (err != Error::NONE) {
        mWriter.setError(getCommandLoc(), err);
    }

    return true;
}

hwc_rect_t ComposerClient::CommandReader::readRect()
{
    return hwc_rect_t{
        readSigned(),
        readSigned(),
        readSigned(),
        readSigned(),
    };
}

std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
{
    std::vector<hwc_rect_t> region;
    region.reserve(count);
    while (count > 0) {
        region.emplace_back(readRect());
        count--;
    }

    return region;
}

hwc_frect_t ComposerClient::CommandReader::readFRect()
std::unique_ptr<ComposerCommandEngine>
ComposerClient::createCommandEngine()
{
    return hwc_frect_t{
        readFloat(),
        readFloat(),
        readFloat(),
        readFloat(),
    };
    return std::make_unique<ComposerCommandEngine>(&mHal, mResources.get());
}

} // namespace implementation
+5 −55
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <vector>

#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
#include <composer-hal/2.1/ComposerCommandEngine.h>
#include <composer-hal/2.1/ComposerHal.h>
#include <composer-hal/2.1/ComposerResources.h>
#include <hardware/hwcomposer2.h>
@@ -92,68 +93,17 @@ public:
            executeCommands_cb hidl_cb) override;

protected:
    class CommandReader : public CommandReaderBase {
    public:
        CommandReader(ComposerClient& client);
        virtual ~CommandReader();

        Error parse();

    protected:
        virtual bool parseCommand(IComposerClient::Command command,
                uint16_t length);

        bool parseSelectDisplay(uint16_t length);
        bool parseSelectLayer(uint16_t length);
        bool parseSetColorTransform(uint16_t length);
        bool parseSetClientTarget(uint16_t length);
        bool parseSetOutputBuffer(uint16_t length);
        bool parseValidateDisplay(uint16_t length);
        bool parsePresentOrValidateDisplay(uint16_t length);
        bool parseAcceptDisplayChanges(uint16_t length);
        bool parsePresentDisplay(uint16_t length);
        bool parseSetLayerCursorPosition(uint16_t length);
        bool parseSetLayerBuffer(uint16_t length);
        bool parseSetLayerSurfaceDamage(uint16_t length);
        bool parseSetLayerBlendMode(uint16_t length);
        bool parseSetLayerColor(uint16_t length);
        bool parseSetLayerCompositionType(uint16_t length);
        bool parseSetLayerDataspace(uint16_t length);
        bool parseSetLayerDisplayFrame(uint16_t length);
        bool parseSetLayerPlaneAlpha(uint16_t length);
        bool parseSetLayerSidebandStream(uint16_t length);
        bool parseSetLayerSourceCrop(uint16_t length);
        bool parseSetLayerTransform(uint16_t length);
        bool parseSetLayerVisibleRegion(uint16_t length);
        bool parseSetLayerZOrder(uint16_t length);

        hwc_rect_t readRect();
        std::vector<hwc_rect_t> readRegion(size_t count);
        hwc_frect_t readFRect();

        ComposerHal& mHal;
        ComposerResources* mResources;
        CommandWriterBase& mWriter;

        Display mDisplay;
        Layer mLayer;
    };
    virtual std::unique_ptr<ComposerResources> createResources();
    virtual std::unique_ptr<ComposerCommandEngine> createCommandEngine();

    void destroyResources();

    virtual std::unique_ptr<ComposerResources> createResources();
    virtual std::unique_ptr<CommandReader> createCommandReader();

    ComposerHal& mHal;

    std::unique_ptr<ComposerResources> mResources;

    // 64KiB minus a small space for metadata such as read/write pointers
    static constexpr size_t kWriterInitialSize =
        64 * 1024 / sizeof(uint32_t) - 16;
    std::mutex mCommandMutex;
    std::unique_ptr<CommandReader> mReader;
    CommandWriterBase mWriter;
    std::mutex mCommandEngineMutex;
    std::unique_ptr<ComposerCommandEngine> mCommandEngine;

    sp<IComposerCallback> mCallback;
};
+6 −0
Original line number Diff line number Diff line
@@ -27,5 +27,11 @@ cc_library_headers {
        "android.hardware.graphics.mapper@2.0",
        "libhardware",
    ],
    header_libs: [
        "android.hardware.graphics.composer@2.1-command-buffer",
    ],
    export_header_lib_headers: [
        "android.hardware.graphics.composer@2.1-command-buffer",
    ],
    export_include_dirs: ["include"],
}
+594 −0

File added.

Preview size limit exceeded, changes collapsed.