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

Commit 91c9d1a8 authored by Ady Abraham's avatar Ady Abraham
Browse files

composer: cleanup CommandWriterBase and CommandReaderBase

These classes are used by both the client and the service, which
makes them confusing. This CL splits the logic for the client
and the service.

Bug: 208856704
Test: VTS
Change-Id: I6fa89858afeee9113ea8c810261d734163a95ec9
parent d394ed45
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -167,8 +167,8 @@ class GraphicsCompositionTestBase : public ::testing::Test {
    int32_t mDisplayWidth;
    int32_t mDisplayHeight;
    std::vector<ColorMode> mTestColorModes;
    CommandWriterBase mWriter;
    CommandReaderBase mReader;
    ComposerClientWriter mWriter;
    ComposerClientReader mReader;
    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
    std::unique_ptr<TestRenderEngine> mTestRenderEngine;

+4 −3
Original line number Diff line number Diff line
@@ -13,7 +13,8 @@
#include <android-base/properties.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android/hardware/graphics/composer3/command-buffer.h>
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
#include <binder/ProcessState.h>
#include <gtest/gtest.h>
#include <ui/GraphicBuffer.h>
@@ -1408,8 +1409,8 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
    }};
    // clang-format on

    CommandWriterBase mWriter;
    CommandReaderBase mReader;
    ComposerClientWriter mWriter;
    ComposerClientReader mReader;
};

TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) {
+5 −5
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, Colo
const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
                                                           common::Dataspace::DISPLAY_P3};

void TestLayer::write(CommandWriterBase& writer) {
void TestLayer::write(ComposerClientWriter& writer) {
    writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
    writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
    writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
@@ -253,7 +253,7 @@ void ReadbackBuffer::checkReadbackBuffer(std::vector<Color> expectedColors) {
    EXPECT_EQ(::android::OK, status);
}

void TestColorLayer::write(CommandWriterBase& writer) {
void TestColorLayer::write(ComposerClientWriter& writer) {
    TestLayer::write(writer);
    writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
    writer.setLayerColor(mDisplay, mLayer, mColor);
@@ -296,7 +296,7 @@ TestBufferLayer::TestBufferLayer(const std::shared_ptr<IComposerClient>& client,
    setSourceCrop({0, 0, (float)width, (float)height});
}

void TestBufferLayer::write(CommandWriterBase& writer) {
void TestBufferLayer::write(ComposerClientWriter& writer) {
    TestLayer::write(writer);
    writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
    writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
@@ -345,11 +345,11 @@ void TestBufferLayer::setBuffer(std::vector<Color> colors) {
    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
}

void TestBufferLayer::setDataspace(common::Dataspace dataspace, CommandWriterBase& writer) {
void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) {
    writer.setLayerDataspace(mDisplay, mLayer, dataspace);
}

void TestBufferLayer::setToClientComposition(CommandWriterBase& writer) {
void TestBufferLayer::setToClientComposition(ComposerClientWriter& writer) {
    writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
}

+7 −6
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@
#include <GraphicsComposerCallback.h>
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer3/command-buffer.h>
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
#include <mapper-vts/2.1/MapperVts.h>
#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>
@@ -61,7 +62,7 @@ class TestLayer {
    // call destroyLayers here
    virtual ~TestLayer(){};

    virtual void write(CommandWriterBase& writer);
    virtual void write(ComposerClientWriter& writer);
    virtual LayerSettings toRenderEngineLayerSettings();

    void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
@@ -105,7 +106,7 @@ class TestColorLayer : public TestLayer {
    TestColorLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
        : TestLayer{client, display} {}

    void write(CommandWriterBase& writer) override;
    void write(ComposerClientWriter& writer) override;

    LayerSettings toRenderEngineLayerSettings() override;

@@ -123,7 +124,7 @@ class TestBufferLayer : public TestLayer {
                    uint32_t height, common::PixelFormat format,
                    Composition composition = Composition::DEVICE);

    void write(CommandWriterBase& writer) override;
    void write(ComposerClientWriter& writer) override;

    LayerSettings toRenderEngineLayerSettings() override;

@@ -131,9 +132,9 @@ class TestBufferLayer : public TestLayer {

    void setBuffer(std::vector<Color> colors);

    void setDataspace(Dataspace dataspace, CommandWriterBase& writer);
    void setDataspace(Dataspace dataspace, ComposerClientWriter& writer);

    void setToClientComposition(CommandWriterBase& writer);
    void setToClientComposition(ComposerClientWriter& writer);

    uint32_t getWidth() const { return mWidth; }

+319 −0
Original line number Diff line number Diff line
@@ -63,304 +63,9 @@ using aidl::android::hardware::common::NativeHandle;

namespace aidl::android::hardware::graphics::composer3 {

// This class helps build a command queue.  Note that all sizes/lengths are in
// units of uint32_t's.
class CommandWriterBase {
class ComposerClientReader {
  public:
    CommandWriterBase() { reset(); }

    virtual ~CommandWriterBase() { reset(); }

    void reset() {
        mDisplayCommand.reset();
        mLayerCommand.reset();
        mCommands.clear();
        mCommandsResults.clear();
    }

    void setError(int32_t index, int32_t errorCode) {
        CommandError error;
        error.commandIndex = index;
        error.errorCode = errorCode;
        mCommandsResults.emplace_back(std::move(error));
    }

    void setPresentOrValidateResult(int64_t display, PresentOrValidate::Result result) {
        PresentOrValidate presentOrValidate;
        presentOrValidate.display = display;
        presentOrValidate.result = result;
        mCommandsResults.emplace_back(std::move(presentOrValidate));
    }

    void setChangedCompositionTypes(int64_t display, const std::vector<int64_t>& layers,
                                    const std::vector<Composition>& types) {
        ChangedCompositionTypes changedCompositionTypes;
        changedCompositionTypes.display = display;
        changedCompositionTypes.layers.reserve(layers.size());
        for (int i = 0; i < layers.size(); i++) {
            auto layer = ChangedCompositionLayer{.layer = layers[i], .composition = types[i]};
            changedCompositionTypes.layers.emplace_back(std::move(layer));
        }
        mCommandsResults.emplace_back(std::move(changedCompositionTypes));
    }

    void setDisplayRequests(int64_t display, int32_t displayRequestMask,
                            const std::vector<int64_t>& layers,
                            const std::vector<int32_t>& layerRequestMasks) {
        DisplayRequest displayRequest;
        displayRequest.display = display;
        displayRequest.mask = displayRequestMask;
        displayRequest.layerRequests.reserve(layers.size());
        for (int i = 0; i < layers.size(); i++) {
            auto layerRequest =
                    DisplayRequest::LayerRequest{.layer = layers[i], .mask = layerRequestMasks[i]};
            displayRequest.layerRequests.emplace_back(std::move(layerRequest));
        }
        mCommandsResults.emplace_back(std::move(displayRequest));
    }

    void setPresentFence(int64_t display, ::ndk::ScopedFileDescriptor presentFence) {
        if (presentFence.get() >= 0) {
            PresentFence presentFenceCommand;
            presentFenceCommand.fence = std::move(presentFence);
            presentFenceCommand.display = display;
            mCommandsResults.emplace_back(std::move(presentFenceCommand));
        } else {
            ALOGW("%s: invalid present fence %d", __func__, presentFence.get());
        }
    }

    void setReleaseFences(int64_t display, const std::vector<int64_t>& layers,
                          std::vector<::ndk::ScopedFileDescriptor> releaseFences) {
        ReleaseFences releaseFencesCommand;
        releaseFencesCommand.display = display;
        for (int i = 0; i < layers.size(); i++) {
            if (releaseFences[i].get() >= 0) {
                ReleaseFences::Layer layer;
                layer.layer = layers[i];
                layer.fence = std::move(releaseFences[i]);
                releaseFencesCommand.layers.emplace_back(std::move(layer));
            } else {
                ALOGW("%s: invalid release fence %d", __func__, releaseFences[i].get());
            }
        }
        mCommandsResults.emplace_back(std::move(releaseFencesCommand));
    }

    void setClientTargetProperty(int64_t display, const ClientTargetProperty& clientTargetProperty,
                                 float whitePointNits) {
        ClientTargetPropertyWithNits clientTargetPropertyWithNits;
        clientTargetPropertyWithNits.display = display;
        clientTargetPropertyWithNits.clientTargetProperty = clientTargetProperty;
        clientTargetPropertyWithNits.whitePointNits = whitePointNits;
        mCommandsResults.emplace_back(std::move(clientTargetPropertyWithNits));
    }

    void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) {
        ColorTransformPayload colorTransformPayload;
        colorTransformPayload.matrix.assign(matrix, matrix + 16);
        colorTransformPayload.hint = hint;
        getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload));
    }

    void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
                         int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
        ClientTarget clientTargetCommand;
        clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
        clientTargetCommand.dataspace = dataspace;
        clientTargetCommand.damage.assign(damage.begin(), damage.end());
        getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
    }

    void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
                         int releaseFence) {
        getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
                getBuffer(slot, buffer, releaseFence));
    }

    void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; }

    void presentOrvalidateDisplay(int64_t display) {
        getDisplayCommand(display).presentOrValidateDisplay = true;
    }

    void acceptDisplayChanges(int64_t display) {
        getDisplayCommand(display).acceptDisplayChanges = true;
    }

    void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; }

    void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
        common::Point cursorPosition;
        cursorPosition.x = x;
        cursorPosition.y = y;
        getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition));
    }

    void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
                        const native_handle_t* buffer, int acquireFence) {
        getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
    }

    void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
        getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end());
    }

    void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) {
        ParcelableBlendMode parcelableBlendMode;
        parcelableBlendMode.blendMode = mode;
        getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode));
    }

    void setLayerColor(int64_t display, int64_t layer, Color color) {
        getLayerCommand(display, layer).color.emplace(std::move(color));
    }

    void setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
        ParcelableComposition compositionPayload;
        compositionPayload.composition = type;
        getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload));
    }

    void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) {
        ParcelableDataspace dataspacePayload;
        dataspacePayload.dataspace = dataspace;
        getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload));
    }

    void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) {
        getLayerCommand(display, layer).displayFrame.emplace(frame);
    }

    void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
        PlaneAlpha planeAlpha;
        planeAlpha.alpha = alpha;
        getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha));
    }

    void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) {
        NativeHandle handle;
        if (stream) handle = ::android::dupToAidl(stream);
        getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle));
    }

    void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) {
        getLayerCommand(display, layer).sourceCrop.emplace(crop);
    }

    void setLayerTransform(int64_t display, int64_t layer, Transform transform) {
        ParcelableTransform transformPayload;
        transformPayload.transform = transform;
        getLayerCommand(display, layer).transform.emplace(std::move(transformPayload));
    }

    void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
        getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
    }

    void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
        ZOrder zorder;
        zorder.z = z;
        getLayerCommand(display, layer).z.emplace(std::move(zorder));
    }

    void setLayerPerFrameMetadata(int64_t display, int64_t layer,
                                  const std::vector<PerFrameMetadata>& metadataVec) {
        getLayerCommand(display, layer)
                .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end());
    }

    void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) {
        getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16);
    }

    void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
                                       const std::vector<PerFrameMetadataBlob>& metadata) {
        getLayerCommand(display, layer)
                .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
    }

    void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) {
        getLayerCommand(display, layer).floatColor.emplace(color);
    }

    void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key,
                                 const bool mandatory, const std::vector<uint8_t>& value) {
        GenericMetadata metadata;
        metadata.key.name = key;
        metadata.key.mandatory = mandatory;
        metadata.value.assign(value.begin(), value.end());
        getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata));
    }

    void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) {
        getLayerCommand(display, layer)
                .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits});
    }

    const std::vector<DisplayCommand>& getPendingCommands() {
        flushLayerCommand();
        flushDisplayCommand();
        return mCommands;
    }

    std::vector<CommandResultPayload> getPendingCommandResults() {
        return std::move(mCommandsResults);
    }

  protected:
    Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) {
        Buffer bufferCommand;
        bufferCommand.slot = slot;
        if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
        if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
        return bufferCommand;
    }

    std::optional<DisplayCommand> mDisplayCommand;
    std::optional<LayerCommand> mLayerCommand;
    std::vector<DisplayCommand> mCommands;
    std::vector<CommandResultPayload> mCommandsResults;

  private:
    void flushLayerCommand() {
        if (mLayerCommand.has_value()) {
            mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand));
            mLayerCommand.reset();
        }
    }

    void flushDisplayCommand() {
        if (mDisplayCommand.has_value()) {
            mCommands.emplace_back(std::move(*mDisplayCommand));
            mDisplayCommand.reset();
        }
    }

    DisplayCommand& getDisplayCommand(int64_t display) {
        if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
            flushLayerCommand();
            flushDisplayCommand();
            mDisplayCommand.emplace();
            mDisplayCommand->display = display;
        }
        return *mDisplayCommand;
    }

    LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
        getDisplayCommand(display);
        if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) {
            flushLayerCommand();
            mLayerCommand.emplace();
            mLayerCommand->layer = layer;
        }
        return *mLayerCommand;
    }
};

class CommandReaderBase {
  public:
    ~CommandReaderBase() { resetData(); }
    ~ComposerClientReader() { resetData(); }

    // Parse and execute commands from the command queue.  The commands are
    // actually return values from the server and will be saved in ReturnData.
Loading