From be92bb9fae96cdfad53c1c34de516e82938951de Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Thu, 11 Jan 2018 08:50:03 -0800 Subject: [PATCH] Add new HWC HAL methods for Android P. Add new methods to support HDR, video readback mechanism and additional power mode. Test: adb shell /data/nativetest/VtsHalGraphicsComposerV2_2TargetTest/VtsHalGraphicsComposerV2_2TargetTest Bug: 71513501 Change-Id: I45596df6c5a2a726e12f524e82681aef4bcbe180 --- .../VtsHalGraphicsComposerTestUtils.h | 4 +- graphics/composer/2.2/Android.bp | 20 ++ graphics/composer/2.2/IComposer.hal | 25 ++ graphics/composer/2.2/IComposerClient.hal | 243 ++++++++++++++++++ graphics/composer/2.2/utils/OWNERS | 8 + .../2.2/utils/command-buffer/Android.bp | 13 + .../2.2/ComposerCommandBuffer.h | 94 +++++++ .../composer/2.2/vts/functional/Android.bp | 74 ++++++ graphics/composer/2.2/vts/functional/OWNERS | 8 + .../VtsHalGraphicsComposerTestUtils.cpp | 127 +++++++++ .../VtsHalGraphicsComposerV2_2TargetTest.cpp | 242 +++++++++++++++++ .../2.2/VtsHalGraphicsComposerTestUtils.h | 84 ++++++ 12 files changed, 941 insertions(+), 1 deletion(-) create mode 100644 graphics/composer/2.2/Android.bp create mode 100644 graphics/composer/2.2/IComposer.hal create mode 100644 graphics/composer/2.2/IComposerClient.hal create mode 100644 graphics/composer/2.2/utils/OWNERS create mode 100644 graphics/composer/2.2/utils/command-buffer/Android.bp create mode 100644 graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h create mode 100644 graphics/composer/2.2/vts/functional/Android.bp create mode 100644 graphics/composer/2.2/vts/functional/OWNERS create mode 100644 graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerTestUtils.cpp create mode 100644 graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp create mode 100644 graphics/composer/2.2/vts/functional/include/2.2/VtsHalGraphicsComposerTestUtils.h diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h index 29b9de35a7..00d9d8c94c 100644 --- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h +++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h @@ -58,10 +58,12 @@ class Composer { std::string dumpDebugInfo(); std::unique_ptr createClient(); + protected: + sp mComposer; + private: void init(); - sp mComposer; std::unordered_set mCapabilities; }; diff --git a/graphics/composer/2.2/Android.bp b/graphics/composer/2.2/Android.bp new file mode 100644 index 0000000000..633a208cf1 --- /dev/null +++ b/graphics/composer/2.2/Android.bp @@ -0,0 +1,20 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.graphics.composer@2.2", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "IComposer.hal", + "IComposerClient.hal", + ], + interfaces: [ + "android.hardware.graphics.common@1.0", + "android.hardware.graphics.composer@2.1", + "android.hidl.base@1.0", + ], + gen_java: false, +} + diff --git a/graphics/composer/2.2/IComposer.hal b/graphics/composer/2.2/IComposer.hal new file mode 100644 index 0000000000..05052c8903 --- /dev/null +++ b/graphics/composer/2.2/IComposer.hal @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2018 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. + */ + +package android.hardware.graphics.composer@2.2; + +import @2.1::IComposer; + +interface IComposer extends @2.1::IComposer { + + /* createClient from @2.1::IComposer must return an instance of @2.2::IComposerClient */ + +}; diff --git a/graphics/composer/2.2/IComposerClient.hal b/graphics/composer/2.2/IComposerClient.hal new file mode 100644 index 0000000000..4a884bc9e2 --- /dev/null +++ b/graphics/composer/2.2/IComposerClient.hal @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2018 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. + */ + +package android.hardware.graphics.composer@2.2; + +import android.hardware.graphics.common@1.0::PixelFormat; +import android.hardware.graphics.common@1.0::Dataspace; +import @2.1::IComposerClient; +import @2.1::Display; +import @2.1::Error; + +interface IComposerClient extends @2.1::IComposerClient { + + enum PowerMode : @2.1::IComposerClient.PowerMode { + /** + * The display is configured as in ON but may stop applying display + * updates from the client. This is effectively a hint to the device + * that drawing to the display has been suspended and that the the + * device must remain on and continue displaying its current contents + * indefinitely until the power mode changes. + * + * This mode may also be used as a signal to enable hardware-based + * functionality to take over the display and manage it autonomously + * to implement a low power always-on display. + */ + ON_SUSPEND = 4 + }; + + /** + * Following enums define keys for metadata defined by SMPTE ST 2086:2014 + * and CTA 861.3. + */ + enum PerFrameMetadataKey : int32_t { + /** SMPTE ST 2084:2014. + * Coordinates defined in CIE 1931 xy chromaticity space + */ + /** SMPTE ST 2084:2014 */ + DISPLAY_RED_PRIMARY_X, + /** SMPTE ST 2084:2014 */ + DISPLAY_RED_PRIMARY_Y, + /** SMPTE ST 2084:2014 */ + DISPLAY_GREEN_PRIMARY_X, + /** SMPTE ST 2084:2014 */ + DISPLAY_GREEN_PRIMARY_Y, + /** SMPTE ST 2084:2014 */ + DISPLAY_BLUE_PRIMARY_X, + /** SMPTE ST 2084:2014 */ + DISPLAY_BLUE_PRIMARY_Y, + /** SMPTE ST 2084:2014 */ + WHITE_POINT_X, + /** SMPTE ST 2084:2014 */ + WHITE_POINT_Y, + /** SMPTE ST 2084:2014. + * Units: nits + * max as defined by ST 2048: 10,000 nits + */ + MAX_LUMINANCE, + /** SMPTE ST 2084:2014 */ + MIN_LUMINANCE, + /** CTA 861.3 */ + MAX_CONTENT_LIGHT_LEVEL, + /** CTA 861.3 */ + MAX_FRAME_AVERAGE_LIGHT_LEVEL, + }; + + struct PerFrameMetadata { + PerFrameMetadataKey key; + float value; + }; + + /** + * setPerFrameMetadata(Display display, vec data) + * Sets the PerFrameMetadata for the display. This metadata must be used + * by the implementation to better tone map content to that display. + * + * This is a method that may be called every frame. Thus it's + * implemented using buffered transport. + * SET_PER_FRAME_METADATA is the command used by the buffered transport + * mechanism. + */ + enum Command : @2.1::IComposerClient.Command { + SET_PER_FRAME_METADATA = 0x207 << @2.1::IComposerClient.Command:OPCODE_SHIFT, + }; + + /** + * Returns the PerFrameMetadataKeys that are supported by this device. + * + * @param display is the display on which to create the layer. + * @return keys is the vector of PerFrameMetadataKey keys that are + * supported by this device. + * @return error is NONE upon success. Otherwise, + * UNSUPPORTED if not supported on underlying HAL + */ + getPerFrameMetadataKeys(Display display) + generates (Error error, + vec keys); + + /** + * getReadbackBufferAttributes + * Returns the format which should be used when allocating a buffer for use by + * device readback as well as the dataspace in which its contents should be + * interpreted. + * + * The width and height of this buffer must be those of the currently-active + * display configuration, and the usage flags must consist of the following: + * BufferUsage::CPU_READ | BufferUsage::GPU_TEXTURE | + * BufferUsage::COMPOSER_OUTPUT + * + * The format and dataspace provided must be sufficient such that if a + * correctly-configured buffer is passed into setReadbackBuffer, filled by + * the device, and then displayed by the client as a full-screen buffer, the + * output of the display remains the same (subject to the note about protected + * content in the description of setReadbackBuffer). + * + * Parameters: + * @param display - the display on which to create the layer. + * + * @return format - the format the client should use when allocating a device + * readback buffer + * @return dataspace - the dataspace to use when interpreting the + * contents of a device readback buffer + * @return error is NONE upon success. Otherwise, + * BAD_DISPLAY when an invalid display handle was passed in. + * UNSUPPORTED if not supported on underlying HAL + * + * See also: + * setReadbackBuffer + * getReadbackBufferFence + */ + getReadbackBufferAttributes(Display display) + generates (Error error, + PixelFormat format, + Dataspace dataspace); + + /** + * getReadbackBufferFence + * Returns an acquire sync fence file descriptor which must signal when the + * buffer provided to setReadbackBuffer has been filled by the device and is + * safe for the client to read. + * + * If it is already safe to read from this buffer, -1 may be returned instead. + * The client takes ownership of this file descriptor and is responsible for + * closing it when it is no longer needed. + * + * This function must be called immediately after the composition cycle being + * captured into the readback buffer. The complete ordering of a readback buffer + * capture is as follows: + * + * getReadbackBufferAttributes + * // Readback buffer is allocated + * // Many frames may pass + * + * setReadbackBuffer + * validateDisplay + * presentDisplay + * getReadbackBufferFence + * // Implicitly wait on the acquire fence before accessing the buffer + * + * Parameters: + * @param display - the display on which to create the layer. + * + * @return acquireFence - a sync fence file descriptor as described above; pointer + * must be non-NULL + * @return error - is HWC2_ERROR_NONE or one of the following errors: + * BAD_DISPLAY - an invalid display handle was passed in + * UNSUPPORTED if not supported on underlying HAL + * + * See also: + * getReadbackBufferAttributes + * setReadbackBuffer + */ + getReadbackBufferFence(Display display) + generates (Error error, + handle acquireFence); + + /** + * setReadbackBuffer + * Sets the readback buffer to be filled with the contents of the next + * composition performed for this display (i.e., the contents present at the + * time of the next validateDisplay/presentDisplay cycle). + * + * This buffer must have been allocated as described in + * getReadbackBufferAttributes and is in the dataspace provided by the same. + * + * If there is hardware protected content on the display at the time of the next + * composition, the area of the readback buffer covered by such content must be + * completely black. Any areas of the buffer not covered by such content may + * optionally be black as well. + * + * The release fence file descriptor provided works identically to the one + * described for setOutputBuffer. + * + * This function must not be called between any call to validateDisplay and a + * subsequent call to presentDisplay. + * + * Parameters: + * @param display - the display on which to create the layer. + * @param buffer - the new readback buffer + * @param releaseFence - a sync fence file descriptor as described in setOutputBuffer + * + * @return error - is HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + * HWC2_ERROR_BAD_PARAMETER - the new readback buffer handle was invalid + * + * See also: + * getReadbackBufferAttributes + * getReadbackBufferFence + */ + setReadbackBuffer(Display display, handle buffer, handle releaseFence) generates (Error error); + + /** + * setPowerMode_2_2 + * Sets the power mode of the given display. The transition must be + * complete when this function returns. It is valid to call this function + * multiple times with the same power mode. + * + * All displays must support PowerMode::ON and PowerMode::OFF. Whether a + * display supports PowerMode::DOZE or PowerMode::DOZE_SUSPEND may be + * queried using getDozeSupport. + * + * @param display is the display to which the power mode is set. + * @param mode is the new power mode. + * @return error is NONE upon success. Otherwise, + * BAD_DISPLAY when an invalid display handle was passed in. + * BAD_PARAMETER when mode was not a valid power mode. + * UNSUPPORTED when mode is not supported on this display. + */ + setPowerMode_2_2(Display display, PowerMode mode) generates (Error error); + +}; diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS new file mode 100644 index 0000000000..1beb074fe1 --- /dev/null +++ b/graphics/composer/2.2/utils/OWNERS @@ -0,0 +1,8 @@ +# Graphics team +courtneygo@google.com +olv@google.com +stoza@google.com + +# VTS team +yim@google.com +zhuoyao@google.com diff --git a/graphics/composer/2.2/utils/command-buffer/Android.bp b/graphics/composer/2.2/utils/command-buffer/Android.bp new file mode 100644 index 0000000000..efaabd46f4 --- /dev/null +++ b/graphics/composer/2.2/utils/command-buffer/Android.bp @@ -0,0 +1,13 @@ +cc_library_headers { + name: "android.hardware.graphics.composer@2.2-command-buffer", + defaults: ["hidl_defaults"], + vendor_available: true, + shared_libs: [ + "android.hardware.graphics.composer@2.1", + "android.hardware.graphics.composer@2.2", + ], + header_libs: [ + "android.hardware.graphics.composer@2.1-command-buffer", + ], + export_include_dirs: ["include"], +} diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h new file mode 100644 index 0000000000..f953b96c74 --- /dev/null +++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h @@ -0,0 +1,94 @@ +/* + * Copyright 2018 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. + */ + +#pragma once + +#ifndef LOG_TAG +#warn "ComposerCommandBuffer.h included without LOG_TAG" +#endif + +#undef LOG_NDEBUG +#define LOG_NDEBUG 0 + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace composer { +namespace V2_2 { + +using android::hardware::MessageQueue; +using android::hardware::graphics::common::V1_0::ColorTransform; +using android::hardware::graphics::common::V1_0::Dataspace; +using android::hardware::graphics::common::V1_0::Transform; +using android::hardware::graphics::composer::V2_1::Config; +using android::hardware::graphics::composer::V2_1::Display; +using android::hardware::graphics::composer::V2_1::Error; +using android::hardware::graphics::composer::V2_1::IComposerCallback; +using android::hardware::graphics::composer::V2_1::Layer; +using android::hardware::graphics::composer::V2_2::IComposerClient; + +using CommandQueueType = MessageQueue; + +// This class helps build a command queue. Note that all sizes/lengths are in +// units of uint32_t's. +class CommandWriterBase : public V2_1::CommandWriterBase { + public: + CommandWriterBase(uint32_t initialMaxSize) : V2_1::CommandWriterBase(initialMaxSize) {} + + void setPerFrameMetadata(const hidl_vec& metadataVec) { + beginCommand2_2(IComposerClient::Command::SET_PER_FRAME_METADATA, metadataVec.size() * 2); + for (const auto& metadata : metadataVec) { + writeSigned(static_cast(metadata.key)); + writeFloat(metadata.value); + } + endCommand(); + } + + protected: + void beginCommand2_2(IComposerClient::Command command, uint16_t length) { + V2_1::CommandWriterBase::beginCommand( + static_cast(static_cast(command)), length); + } +}; + +// This class helps parse a command queue. Note that all sizes/lengths are in +// units of uint32_t's. +class CommandReaderBase : public V2_1::CommandReaderBase { + public: + CommandReaderBase() : V2_1::CommandReaderBase(){}; +}; + +} // 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 new file mode 100644 index 0000000000..0325a6c57c --- /dev/null +++ b/graphics/composer/2.2/vts/functional/Android.bp @@ -0,0 +1,74 @@ +// +// Copyright (C) 2018 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. +// + +cc_library_static { + name: "libVtsHalGraphicsComposerTestUtils@2.2", + defaults: ["hidl_defaults"], + srcs: [ + "VtsHalGraphicsComposerTestUtils.cpp", + ], + shared_libs: [ + "android.hardware.graphics.composer@2.1", + "android.hardware.graphics.composer@2.2", + "libfmq", + "libsync", + ], + static_libs: [ + "libVtsHalGraphicsComposerTestUtils", + "VtsHalHidlTargetTestBase", + ], + header_libs: [ + "android.hardware.graphics.composer@2.1-command-buffer", + "android.hardware.graphics.composer@2.2-command-buffer", + ], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + "-O0", + "-g", + "-DLOG_TAG=\"GraphicsComposerTestUtils@2.2\"", + ], + export_include_dirs: ["include"], +} + +cc_test { + name: "VtsHalGraphicsComposerV2_2TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalGraphicsComposerV2_2TargetTest.cpp"], + + // TODO(b/64437680): Assume these libs are always available on the device. + shared_libs: [ + "libfmq", + "libhidltransport", + "libsync", + ], + static_libs: [ + "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.composer@2.2", + "android.hardware.graphics.composer@2.1", + "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@2.1", + "libVtsHalGraphicsComposerTestUtils", + "libVtsHalGraphicsComposerTestUtils@2.2", + "libVtsHalGraphicsMapperTestUtils", + "libnativehelper", + ], + header_libs: [ + "android.hardware.graphics.composer@2.1-command-buffer", + "android.hardware.graphics.composer@2.2-command-buffer", + ], +} diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS new file mode 100644 index 0000000000..1beb074fe1 --- /dev/null +++ b/graphics/composer/2.2/vts/functional/OWNERS @@ -0,0 +1,8 @@ +# Graphics team +courtneygo@google.com +olv@google.com +stoza@google.com + +# VTS team +yim@google.com +zhuoyao@google.com diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerTestUtils.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerTestUtils.cpp new file mode 100644 index 0000000000..00946cef61 --- /dev/null +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerTestUtils.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2018 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 +#include + +#include +#include "2.2/VtsHalGraphicsComposerTestUtils.h" + +namespace android { +namespace hardware { +namespace graphics { +namespace composer { +namespace V2_2 { +namespace tests { + +using android::hardware::graphics::composer::V2_2::IComposerClient; +using android::hardware::details::getDescriptor; +using android::hardware::details::canCastInterface; + +std::unique_ptr Composer_v2_2::createClient_v2_2() { + std::unique_ptr client; + mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) { + ASSERT_EQ(Error::NONE, tmpError) << "failed to create client"; + ALOGV("tmpClient is a %s", getDescriptor(&(*tmpClient)).c_str()); + ASSERT_TRUE(canCastInterface( + &(*tmpClient), "android.hardware.graphics.composer@2.2::IComposerClient", false)) + << "Cannot create 2.2 IComposerClient"; + client = std::make_unique(IComposerClient::castFrom(tmpClient, true)); + }); + + return client; +} + +std::vector ComposerClient_v2_2::getPerFrameMetadataKeys( + Display display) { + std::vector keys; + mClient_v2_2->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) { + ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR metadata keys"; + keys = tmpKeys; + }); + + return keys; +} + +void ComposerClient_v2_2::execute_v2_2(V2_1::tests::TestCommandReader* reader, + V2_2::CommandWriterBase* writer) { + bool queueChanged = false; + uint32_t commandLength = 0; + hidl_vec commandHandles; + ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles)); + + if (queueChanged) { + auto ret = mClient_v2_2->setInputCommandQueue(*writer->getMQDescriptor()); + ASSERT_EQ(Error::NONE, static_cast(ret)); + return; + } + + mClient_v2_2->executeCommands(commandLength, commandHandles, + [&](const auto& tmpError, const auto& tmpOutQueueChanged, + const auto& tmpOutLength, const auto& tmpOutHandles) { + ASSERT_EQ(Error::NONE, tmpError); + + if (tmpOutQueueChanged) { + mClient_v2_2->getOutputCommandQueue( + [&](const auto& tmpError, const auto& tmpDescriptor) { + ASSERT_EQ(Error::NONE, tmpError); + reader->setMQDescriptor(tmpDescriptor); + }); + } + + ASSERT_TRUE(reader->readQueue(tmpOutLength, tmpOutHandles)); + reader->parse(); + }); +} + +void ComposerClient_v2_2::setPowerMode_2_2(Display display, V2_2::IComposerClient::PowerMode mode) { + Error error = mClient_v2_2->setPowerMode_2_2(display, mode); + ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set power mode"; +} + +void ComposerClient_v2_2::setReadbackBuffer(Display display, const native_handle_t* buffer, + int32_t /* releaseFence */) { + // Ignoring fence, HIDL doesn't care + Error error = mClient_v2_2->setReadbackBuffer(display, buffer, nullptr); + ASSERT_EQ(Error::NONE, error) << "failed to setReadbackBuffer"; +} + +void ComposerClient_v2_2::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat, + Dataspace* outDataspace) { + mClient_v2_2->getReadbackBufferAttributes( + display, + [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) { + ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes"; + *outPixelFormat = tmpOutPixelFormat; + *outDataspace = tmpOutDataspace; + }); +} + +void ComposerClient_v2_2::getReadbackBufferFence(Display display, int32_t* outFence) { + hidl_handle handle; + mClient_v2_2->getReadbackBufferFence(display, [&](const auto& tmpError, const auto& tmpHandle) { + ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback fence"; + handle = tmpHandle; + }); + *outFence = 0; +} + +} // namespace tests +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp new file mode 100644 index 0000000000..d7826bf3f6 --- /dev/null +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2018 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_test@2.2" + +#include +#include +#include +#include "2.2/VtsHalGraphicsComposerTestUtils.h" +#include "GraphicsComposerCallback.h" +#include "TestCommandReader.h" +#include "VtsHalGraphicsComposerTestUtils.h" +#include "VtsHalGraphicsMapperTestUtils.h" + +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace composer { +namespace V2_2 { +namespace tests { +namespace { + +using android::hardware::graphics::common::V1_0::BufferUsage; +using android::hardware::graphics::common::V1_0::ColorMode; +using android::hardware::graphics::common::V1_0::ColorTransform; +using android::hardware::graphics::common::V1_0::Dataspace; +using android::hardware::graphics::common::V1_0::PixelFormat; +using android::hardware::graphics::common::V1_0::Transform; +using android::hardware::graphics::composer::V2_2::IComposerClient; +using android::hardware::graphics::mapper::V2_0::IMapper; +using android::hardware::graphics::mapper::V2_0::tests::Gralloc; +using GrallocError = android::hardware::graphics::mapper::V2_0::Error; + +// 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(); } + + private: + GraphicsComposerHidlEnvironment() {} + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment); +}; + +class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase { + protected: + void SetUp() override { + ASSERT_NO_FATAL_FAILURE( + mComposer = std::make_unique( + GraphicsComposerHidlEnvironment::Instance()->getServiceName())); + ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient_v2_2()); + + mComposerCallback = new V2_1::tests::GraphicsComposerCallback; + mComposerClient->registerCallback(mComposerCallback); + + // assume the first display is primary and is never removed + mPrimaryDisplay = waitForFirstDisplay(); + + // explicitly disable vsync + mComposerClient->setVsyncEnabled(mPrimaryDisplay, false); + mComposerCallback->setVsyncAllowed(false); + } + + void TearDown() override { + if (mComposerCallback != nullptr) { + EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount()); + EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount()); + EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount()); + } + } + + // use the slot count usually set by SF + static constexpr uint32_t kBufferSlotCount = 64; + + std::unique_ptr mComposer; + std::unique_ptr mComposerClient; + sp mComposerCallback; + // the first display and is assumed never to be removed + Display mPrimaryDisplay; + + private: + Display waitForFirstDisplay() { + while (true) { + std::vector displays = mComposerCallback->getDisplays(); + if (displays.empty()) { + usleep(5 * 1000); + continue; + } + + return displays[0]; + } + } +}; + +// Tests for IComposerClient::Command. +class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { + protected: + void SetUp() override { + ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp()); + + ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique()); + + mWriter = std::make_unique(1024); + mReader = std::make_unique(); + } + + void TearDown() override { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); } + + const native_handle_t* allocate() { + IMapper::BufferDescriptorInfo info{}; + info.width = 64; + info.height = 64; + info.layerCount = 1; + info.format = PixelFormat::RGBA_8888; + info.usage = + static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN); + + return mGralloc->allocate(info); + } + + void execute() { mComposerClient->execute_v2_2(mReader.get(), mWriter.get()); } + + std::unique_ptr mWriter; + std::unique_ptr mReader; + + private: + std::unique_ptr mGralloc; +}; + +/** + * Test IComposerClient::Command::SET_PER_FRAME_METADATA. + */ +TEST_F(GraphicsComposerHidlCommandTest, SET_PER_FRAME_METADATA) { + Layer layer; + ASSERT_NO_FATAL_FAILURE(layer = + mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); + + mWriter->selectDisplay(mPrimaryDisplay); + mWriter->selectLayer(layer); + + /** + * DISPLAY_P3 is a color space that uses the DCI_P3 primaries, + * the D65 white point and the SRGB transfer functions. + * Rendering Intent: Colorimetric + * Primaries: + * x y + * green 0.265 0.690 + * blue 0.150 0.060 + * red 0.680 0.320 + * white (D65) 0.3127 0.3290 + */ + + std::vector hidlMetadata; + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_X, 0.3127}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_Y, 0.3290}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_LUMINANCE, 100.0}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MIN_LUMINANCE, 0.1}); + hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0}); + hidlMetadata.push_back( + {IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0}); + mWriter->setPerFrameMetadata(hidlMetadata); + execute(); +} + +/** + * Test IComposerClient::getPerFrameMetadataKeys. + */ +TEST_F(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) { + mComposerClient->getPerFrameMetadataKeys(mPrimaryDisplay); +} +/** + * Test IComposerClient::setPowerMode_2_2. + */ +TEST_F(GraphicsComposerHidlTest, setPowerMode_2_2) { + std::vector modes; + modes.push_back(IComposerClient::PowerMode::OFF); + modes.push_back(IComposerClient::PowerMode::ON_SUSPEND); + modes.push_back(IComposerClient::PowerMode::ON); + + for (auto mode : modes) { + mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode); + } +} + +TEST_F(GraphicsComposerHidlTest, setReadbackBuffer) { + mComposerClient->setReadbackBuffer(mPrimaryDisplay, nullptr, -1); +} + +TEST_F(GraphicsComposerHidlTest, getReadbackBufferFence) { + int32_t fence; + mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fence); +} + +TEST_F(GraphicsComposerHidlTest, getReadbackBufferAttributes) { + PixelFormat pixelFormat; + Dataspace dataspace; + mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace); +} + +} // namespace +} // namespace tests +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android + +int main(int argc, char** argv) { + using android::hardware::graphics::composer::V2_2::tests::GraphicsComposerHidlEnvironment; + ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance()); + ::testing::InitGoogleTest(&argc, argv); + GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv); + int status = RUN_ALL_TESTS(); + return status; +} diff --git a/graphics/composer/2.2/vts/functional/include/2.2/VtsHalGraphicsComposerTestUtils.h b/graphics/composer/2.2/vts/functional/include/2.2/VtsHalGraphicsComposerTestUtils.h new file mode 100644 index 0000000000..c5756ed870 --- /dev/null +++ b/graphics/composer/2.2/vts/functional/include/2.2/VtsHalGraphicsComposerTestUtils.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 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. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace composer { +namespace V2_2 { +namespace tests { + +using android::hardware::graphics::common::V1_0::ColorMode; +using android::hardware::graphics::common::V1_0::Dataspace; +using android::hardware::graphics::common::V1_0::Hdr; +using android::hardware::graphics::common::V1_0::PixelFormat; +using android::hardware::graphics::composer::V2_2::IComposer; +using android::hardware::graphics::composer::V2_2::IComposerClient; + +class ComposerClient_v2_2; + +// Only thing I need for Composer_v2_2 is to create a v2_2 ComposerClient +// Everything else is the same +class Composer_v2_2 : public V2_1::tests::Composer { + public: + Composer_v2_2() : V2_1::tests::Composer(){}; + explicit Composer_v2_2(const std::string& name) : V2_1::tests::Composer(name){}; + + std::unique_ptr createClient_v2_2(); +}; + +// A wrapper to IComposerClient. +class ComposerClient_v2_2 + : public android::hardware::graphics::composer::V2_1::tests::ComposerClient { + public: + ComposerClient_v2_2(const sp& client) + : V2_1::tests::ComposerClient(client), mClient_v2_2(client){}; + + void execute_v2_2(V2_1::tests::TestCommandReader* reader, V2_2::CommandWriterBase* writer); + + std::vector getPerFrameMetadataKeys(Display display); + + void setPowerMode_2_2(Display display, V2_2::IComposerClient::PowerMode mode); + void setReadbackBuffer(Display display, const native_handle_t* buffer, int32_t releaseFence); + void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat, + Dataspace* outDataspace); + void getReadbackBufferFence(Display display, int32_t* outFence); + + private: + sp mClient_v2_2; +}; + +} // namespace tests +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android