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

Commit d42be6dc authored by Adam Bodnar's avatar Adam Bodnar Committed by Android (Google) Code Review
Browse files

Merge "Validate Render Engine output in composer VTS 2.2"

parents e4168f1e 5bf9dc69
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