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

Commit 5bf9dc69 authored by Adam Bodnar's avatar Adam Bodnar
Browse files

Validate Render Engine output in composer VTS 2.2

Bug: 133411821
Test: build, boot, VtsHalGraphicsComposerV2_2TargetTest
Change-Id: Ie95c197d702977738a75e29954c541fe1b7baa38
parent 123cfda6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -20,8 +20,16 @@ cc_library_static {
    srcs: [
        "ComposerVts.cpp",
        "ReadbackVts.cpp",
        "RenderEngineVts.cpp",
    ],
    shared_libs: [
        "libui",
    ],
    static_libs: [
        "librenderengine",
        "libmath",
        "libarect",
        "libnativewindow",
        "VtsHalHidlTargetTestBase",
        "android.hardware.graphics.composer@2.1",
        "android.hardware.graphics.composer@2.1-vts",
+74 −13
Original line number Diff line number Diff line
@@ -60,6 +60,27 @@ std::string ReadbackHelper::getDataspaceString(Dataspace dataspace) {
    }
}

LayerSettings TestLayer::toRenderEngineLayerSettings() {
    LayerSettings layerSettings;

    layerSettings.alpha = half(mAlpha);
    layerSettings.disableBlending = mBlendMode == IComposerClient::BlendMode::NONE;
    layerSettings.geometry.boundaries = FloatRect(
            static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
            static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));

    const mat4 translation = mat4::translate(vec4(
            (mTransform & Transform::FLIP_H ? -1.0f : 0.0f) * mDisplayFrame.right,
            (mTransform & Transform::FLIP_V ? -1.0f : 0.0f) * mDisplayFrame.bottom, 0.0f, 1.0f));

    const mat4 scale = mat4::scale(vec4(mTransform & Transform::FLIP_H ? -1.0f : 1.0f,
                                        mTransform & Transform::FLIP_V ? -1.0f : 1.0f, 1.0f, 1.0f));

    layerSettings.geometry.positionTransform = translation * scale;

    return layerSettings;
}

int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
    switch (pixelFormat) {
        case PixelFormat::RGBA_8888:
@@ -131,6 +152,25 @@ bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dat
    return true;
}

void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
                                         void* bufferData, const uint32_t stride,
                                         const uint32_t width, const uint32_t height,
                                         const PixelFormat pixelFormat) {
    const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
    ASSERT_NE(-1, bytesPerPixel);
    for (int row = 0; row < height; row++) {
        for (int col = 0; col < width; col++) {
            int pixel = row * width + col;
            int offset = (row * stride + col) * bytesPerPixel;
            uint8_t* pixelColor = (uint8_t*)bufferData + offset;

            ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
            ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
            ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
        }
    }
}

ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
                               const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
                               uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
@@ -179,19 +219,8 @@ void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> exp

    void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle);
    ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
    int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(mPixelFormat);
    ASSERT_NE(-1, bytesPerPixel);
    for (int row = 0; row < mHeight; row++) {
        for (int col = 0; col < mWidth; col++) {
            int pixel = row * mWidth + col;
            int offset = (row * mStride + col) * bytesPerPixel;
            uint8_t* pixelColor = (uint8_t*)bufData + offset;

            ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
            ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
            ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
        }
    }
    ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
                                        mPixelFormat);
    int32_t unlockFence = mGralloc->unlock(mBufferHandle);
    if (unlockFence != -1) {
        sync_wait(unlockFence, -1);
@@ -205,6 +234,16 @@ void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
    writer->setLayerColor(mColor);
}

LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
    LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();

    layerSettings.source.solidColor =
            half3(static_cast<half>(mColor.r) / 255.0, static_cast<half>(mColor.g) / 255.0,
                  static_cast<half>(mColor.b) / 255.0);
    layerSettings.alpha = mAlpha * (static_cast<half>(mColor.a) / 255.0);
    return layerSettings;
}

TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
                                 const std::shared_ptr<Gralloc>& gralloc, Display display,
                                 int32_t width, int32_t height, PixelFormat format,
@@ -241,6 +280,27 @@ void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
    if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
}

LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
    LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
    layerSettings.source.buffer.buffer =
            new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
                              static_cast<int32_t>(mFormat), 1, mUsage, mStride);
    // TODO(b/136483187): Why does this break the premultiply test
    // layerSettings.source.buffer.usePremultipliedAlpha =
    //      mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;

    const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (mWidth);
    const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (mHeight);
    const float translateX = mSourceCrop.left / (mWidth);
    const float translateY = mSourceCrop.top / (mHeight);

    layerSettings.source.buffer.textureTransform =
            mat4::translate(vec4(translateX, translateY, 0, 1)) *
            mat4::scale(vec4(scaleX, scaleY, 1.0, 1.0));

    return layerSettings;
}

void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
    void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1);
    ASSERT_NO_FATAL_FAILURE(
@@ -251,6 +311,7 @@ void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedCol
        close(mFillFence);
    }
}

void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
    if (mBufferHandle != nullptr) {
        mGralloc->freeBuffer(mBufferHandle);
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <composer-vts/2.2/RenderEngineVts.h>

namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace vts {

using mapper::V2_1::IMapper;
using renderengine::DisplaySettings;
using renderengine::LayerSettings;

TestRenderEngine::TestRenderEngine(common::V1_1::PixelFormat hwcFormat,
                                   uint32_t renderEngineFeatures) {
    mFormat = hwcFormat;
    mRenderEngine = renderengine::RenderEngine::create(
            static_cast<int32_t>(mFormat), renderEngineFeatures, mMaxFrameBufferAcquireBuffers);
}

void TestRenderEngine::setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers) {
    sort(layers.begin(), layers.end(),
         [](const std::shared_ptr<TestLayer>& lhs, const std::shared_ptr<TestLayer>& rhs) -> bool {
             return lhs->mZOrder < rhs->mZOrder;
         });

    if (!mCompositionLayers.empty()) {
        mCompositionLayers.clear();
    }
    for (auto& layer : layers) {
        LayerSettings settings = layer->toRenderEngineLayerSettings();
        mCompositionLayers.push_back(settings);
    }
}

void TestRenderEngine::initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
                                         uint64_t usage) {
    mGraphicBuffer =
            new GraphicBuffer(width, height, static_cast<int32_t>(mFormat), layerCount, usage);
}

void TestRenderEngine::drawLayers() {
    base::unique_fd bufferFence;
    base::unique_fd readyFence;
    mRenderEngine->drawLayers(mDisplaySettings, mCompositionLayers,
                              mGraphicBuffer->getNativeBuffer(), true, std::move(bufferFence),
                              &readyFence);
    int fd = readyFence.release();
    if (fd != -1) {
        ASSERT_EQ(0, sync_wait(fd, -1));
        ASSERT_EQ(0, close(fd));
    }
}

void TestRenderEngine::checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors) {
    void* bufferData;
    ASSERT_EQ(0, mGraphicBuffer->lock(mGraphicBuffer->getUsage(), &bufferData));
    ReadbackHelper::compareColorBuffers(expectedColors, bufferData, mGraphicBuffer->getStride(),
                                        mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
                                        mFormat);
    ASSERT_EQ(0, mGraphicBuffer->unlock());
}

}  // namespace vts
}  // namespace V2_2
}  // namespace composer
}  // namespace graphics
}  // namespace hardware
}  // namespace android
+13 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
 * limitations under the License.
 */

#pragma once

#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
@@ -21,6 +23,7 @@
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.2/ComposerVts.h>
#include <mapper-vts/2.1/MapperVts.h>
#include <renderengine/RenderEngine.h>

namespace android {
namespace hardware {
@@ -35,6 +38,7 @@ using common::V1_1::Dataspace;
using common::V1_1::PixelFormat;
using IMapper2_1 = mapper::V2_1::IMapper;
using Gralloc2_1 = mapper::V2_1::vts::Gralloc;
using renderengine::LayerSettings;
using V2_1::Display;
using V2_1::Layer;
using V2_1::vts::AccessRegion;
@@ -56,6 +60,7 @@ class TestLayer {
    virtual ~TestLayer(){};

    virtual void write(const std::shared_ptr<CommandWriterBase>& writer);
    virtual LayerSettings toRenderEngineLayerSettings();

    void setDisplayFrame(IComposerClient::Rect frame) { mDisplayFrame = frame; }
    void setSourceCrop(IComposerClient::FRect crop) { mSourceCrop = crop; }
@@ -93,6 +98,8 @@ class TestColorLayer : public TestLayer {

    void write(const std::shared_ptr<CommandWriterBase>& writer) override;

    LayerSettings toRenderEngineLayerSettings() override;

    void setColor(IComposerClient::Color color) { mColor = color; }

  private:
@@ -110,6 +117,8 @@ class TestBufferLayer : public TestLayer {

    void write(const std::shared_ptr<CommandWriterBase>& writer) override;

    LayerSettings toRenderEngineLayerSettings() override;

    void fillBuffer(std::vector<IComposerClient::Color> expectedColors);

    void setBuffer(std::vector<IComposerClient::Color> colors);
@@ -154,6 +163,10 @@ class ReadbackHelper : public ::testing::VtsHalHidlTargetTestBase {

    static const std::vector<ColorMode> colorModes;
    static const std::vector<Dataspace> dataspaces;

    static void compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
                                    void* bufferData, const uint32_t stride, const uint32_t width,
                                    const uint32_t height, const PixelFormat pixelFormat);
};

class ReadbackBuffer {
+68 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <composer-vts/2.2/ReadbackVts.h>
#include <math/half.h>
#include <math/vec3.h>
#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <ui/Region.h>

#include <VtsHalHidlTargetTestBase.h>

namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace vts {

using mapper::V2_1::IMapper;
using renderengine::DisplaySettings;
using vts::Gralloc;

class TestRenderEngine {
  public:
    TestRenderEngine(common::V1_1::PixelFormat hwcFormat, uint32_t renderEngineFeatures);
    ~TestRenderEngine() = default;

    void setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers);
    void initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint64_t usage);
    void setDisplaySettings(DisplaySettings& displaySettings) {
        mDisplaySettings = displaySettings;
    };
    void drawLayers();
    void checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors);

  private:
    static constexpr uint32_t mMaxFrameBufferAcquireBuffers = 2;
    common::V1_1::PixelFormat mFormat;
    std::vector<renderengine::LayerSettings> mCompositionLayers;
    std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
    std::vector<renderengine::LayerSettings> mRenderLayers;
    sp<GraphicBuffer> mGraphicBuffer;
    DisplaySettings mDisplaySettings;
};

}  // namespace vts
}  // namespace V2_2
}  // namespace composer
}  // namespace graphics
}  // namespace hardware
}  // namespace android
Loading