Validate Render Engine output in composer VTS 2.2
Bug: 133411821
Test: build, boot, VtsHalGraphicsComposerV2_2TargetTest
Change-Id: Ie95c197d702977738a75e29954c541fe1b7baa38
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 56b12f5..b813688 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -20,8 +20,16 @@
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",
diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
index 515dda3..91efc6f 100644
--- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
@@ -60,6 +60,27 @@
}
}
+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 @@
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* 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 @@
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 @@
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 @@
close(mFillFence);
}
}
+
void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
if (mBufferHandle != nullptr) {
mGralloc->freeBuffer(mBufferHandle);
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
new file mode 100644
index 0000000..d910169
--- /dev/null
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
index d7c8c03..5304cd4 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
@@ -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::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 @@
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 @@
void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+ LayerSettings toRenderEngineLayerSettings() override;
+
void setColor(IComposerClient::Color color) { mColor = color; }
private:
@@ -110,6 +117,8 @@
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 @@
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 {
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
new file mode 100644
index 0000000..0ac5a22
--- /dev/null
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
@@ -0,0 +1,68 @@
+/*
+ * 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
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 9f7e1cd..cc24774 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -20,6 +20,7 @@
srcs: [
"VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
"VtsHalGraphicsComposerV2_2TargetTest.cpp",
+ "VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp",
],
// TODO(b/64437680): Assume these libs are always available on the device.
@@ -27,9 +28,19 @@
"libfmq",
"libhidlbase",
"libhidltransport",
+ "libhwbinder",
"libsync",
+ "libui",
+ "libgui",
+ "libEGL",
+ "libGLESv1_CM",
+ "libGLESv2",
],
static_libs: [
+ "librenderengine",
+ "libmath",
+ "libarect",
+ "libnativewindow",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.1",
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp
new file mode 100644
index 0000000..d694a5b
--- /dev/null
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2CompositionComparisonTest.cpp
@@ -0,0 +1,262 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "graphics_composer_hidl_hal_readback_tests@2.2"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <composer-vts/2.1/GraphicsComposerCallback.h>
+#include <composer-vts/2.1/TestCommandReader.h>
+#include <composer-vts/2.2/ComposerVts.h>
+#include <composer-vts/2.2/ReadbackVts.h>
+#include <composer-vts/2.2/RenderEngineVts.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_2 {
+namespace vts {
+namespace {
+
+using android::GraphicBuffer;
+using android::Rect;
+using android::hardware::hidl_handle;
+using common::V1_1::BufferUsage;
+using common::V1_1::Dataspace;
+using common::V1_1::PixelFormat;
+using mapper::V2_1::IMapper;
+using V2_1::Config;
+using V2_1::Display;
+using V2_1::vts::TestCommandReader;
+using vts::Gralloc;
+
+// Test environment for graphics.composer
+class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static GraphicsComposerHidlEnvironment* Instance() {
+ static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
+ return instance;
+ }
+ virtual void registerTestServices() override { registerTestService<IComposer>(); }
+
+ private:
+ GraphicsComposerHidlEnvironment() {}
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
+};
+
+class GraphicsCompositionComparisonTest : public ::testing::VtsHalHidlTargetTestBase {
+ protected:
+ using PowerMode = V2_1::IComposerClient::PowerMode;
+ void SetUp() override {
+ VtsHalHidlTargetTestBase::SetUp();
+ ASSERT_NO_FATAL_FAILURE(
+ mComposer = std::make_unique<Composer>(
+ GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
+ mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
+ mComposerClient->registerCallback(mComposerCallback);
+
+ // assume the first display is primary and is never removed
+ mPrimaryDisplay = waitForFirstDisplay();
+ Config activeConfig;
+ ASSERT_NO_FATAL_FAILURE(activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay));
+ ASSERT_NO_FATAL_FAILURE(
+ mDisplayWidth = mComposerClient->getDisplayAttribute(
+ mPrimaryDisplay, activeConfig, IComposerClient::Attribute::WIDTH));
+ ASSERT_NO_FATAL_FAILURE(
+ mDisplayHeight = mComposerClient->getDisplayAttribute(
+ mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT));
+
+ setTestColorModes();
+
+ // explicitly disable vsync
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false));
+ mComposerCallback->setVsyncAllowed(false);
+
+ // set up command writer/reader and gralloc
+ mWriter = std::make_shared<CommandWriterBase>(1024);
+ mReader = std::make_unique<TestCommandReader>();
+ mGralloc = std::make_shared<Gralloc>();
+
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
+
+ ASSERT_NO_FATAL_FAILURE(
+ mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
+ PixelFormat::RGBA_8888,
+ renderengine::RenderEngine::USE_COLOR_MANAGEMENT |
+ renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT)));
+
+ renderengine::DisplaySettings clientCompositionDisplay;
+ clientCompositionDisplay.physicalDisplay = Rect(mDisplayWidth, mDisplayHeight);
+ clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
+ clientCompositionDisplay.clearRegion = Region(clientCompositionDisplay.physicalDisplay);
+
+ mTestRenderEngine->initGraphicBuffer(
+ static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight), 1,
+ static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN));
+ mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
+ }
+
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
+ EXPECT_EQ(0, mReader->mErrors.size());
+ EXPECT_EQ(0, mReader->mCompositionChanges.size());
+ if (mComposerCallback != nullptr) {
+ EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+ EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+ EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+ }
+ VtsHalHidlTargetTestBase::TearDown();
+ }
+
+ void clearCommandReaderState() {
+ mReader->mCompositionChanges.clear();
+ mReader->mErrors.clear();
+ }
+
+ void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+ for (auto layer : layers) {
+ layer->write(mWriter);
+ }
+ execute();
+ }
+
+ void execute() {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->execute(mReader.get(), mWriter.get()));
+ }
+
+ std::unique_ptr<Composer> mComposer;
+ std::shared_ptr<ComposerClient> mComposerClient;
+
+ sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
+ // the first display and is assumed never to be removed
+ Display mPrimaryDisplay;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
+ std::vector<ColorMode> mTestColorModes;
+ std::shared_ptr<CommandWriterBase> mWriter;
+ std::unique_ptr<TestCommandReader> mReader;
+ std::shared_ptr<Gralloc> mGralloc;
+ std::unique_ptr<TestRenderEngine> mTestRenderEngine;
+
+ bool mHasReadbackBuffer;
+ PixelFormat mPixelFormat;
+ Dataspace mDataspace;
+
+ private:
+ Display waitForFirstDisplay() {
+ while (true) {
+ std::vector<Display> displays = mComposerCallback->getDisplays();
+ if (displays.empty()) {
+ usleep(5 * 1000);
+ continue;
+ }
+ return displays[0];
+ }
+ }
+
+ void setTestColorModes() {
+ mTestColorModes.clear();
+ mComposerClient->getRaw()->getColorModes_2_2(mPrimaryDisplay, [&](const auto& tmpError,
+ const auto& tmpModes) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ for (ColorMode mode : tmpModes) {
+ if (std::find(ReadbackHelper::colorModes.begin(), ReadbackHelper::colorModes.end(),
+ mode) != ReadbackHelper::colorModes.end()) {
+ mTestColorModes.push_back(mode);
+ }
+ }
+ });
+ }
+};
+
+TEST_F(GraphicsCompositionComparisonTest, SingleSolidColorLayer) {
+ for (ColorMode mode : mTestColorModes) {
+ std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
+ << std::endl;
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat,
+ tmpDataspace, tmpError);
+ mPixelFormat = tmpPixelFormat;
+ mDataspace = tmpDataspace;
+ });
+
+ if (!mHasReadbackBuffer) {
+ std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl;
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setColor(BLUE);
+ layer->setDisplayFrame(coloredSquare);
+ layer->setZOrder(10);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ // expected color for each pixel
+ std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ // if hwc cannot handle and asks for composition change,
+ // just succeed the test
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+} // namespace
+} // namespace vts
+} // namespace V2_2
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 6b30df7..72c9496 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * 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.