diff options
Diffstat (limited to 'graphics')
20 files changed, 619 insertions, 89 deletions
diff --git a/graphics/allocator/aidl/Android.bp b/graphics/allocator/aidl/Android.bp new file mode 100644 index 0000000000..ea8a599578 --- /dev/null +++ b/graphics/allocator/aidl/Android.bp @@ -0,0 +1,40 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +aidl_interface { + name: "android.hardware.graphics.allocator", + vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, + srcs: ["android/hardware/graphics/allocator/*.aidl"], + imports: [ + "android.hardware.common-V2", + ], + stability: "vintf", + backend: { + cpp: { + enabled: false, + }, + java: { + enabled: false, + }, + ndk: { + apex_available: [ + "//apex_available:platform", + "com.android.media.swcodec", + ], + vndk: { + enabled: true, + }, + min_sdk_version: "29", + }, + }, +} diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl new file mode 100644 index 0000000000..6e7b739ed5 --- /dev/null +++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.graphics.allocator; +@Backing(type="int") @VintfStability +enum AllocationError { + BAD_DESCRIPTOR = 0, + NO_RESOURCES = 1, + UNSUPPORTED = 2, +} diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationResult.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationResult.aidl new file mode 100644 index 0000000000..73cfeb5422 --- /dev/null +++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationResult.aidl @@ -0,0 +1,39 @@ +/* + * Copyright 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.graphics.allocator; +@VintfStability +parcelable AllocationResult { + int stride; + android.hardware.common.NativeHandle[] buffers; +} diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl new file mode 100644 index 0000000000..fe0b0a214b --- /dev/null +++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl @@ -0,0 +1,38 @@ +/* + * Copyright 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.graphics.allocator; +@VintfStability +interface IAllocator { + android.hardware.graphics.allocator.AllocationResult allocate(in byte[] descriptor, in int count); +} diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationError.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationError.aidl new file mode 100644 index 0000000000..c6b77b9f7f --- /dev/null +++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationError.aidl @@ -0,0 +1,36 @@ +/* + * Copyright 2022 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.allocator; + +@VintfStability +@Backing(type="int") +enum AllocationError { + /** + * Invalid BufferDescriptor. + */ + BAD_DESCRIPTOR, + + /** + * Resource unavailable. + */ + NO_RESOURCES, + + /** + * Permanent failure. + */ + UNSUPPORTED +}
\ No newline at end of file diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationResult.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationResult.aidl new file mode 100644 index 0000000000..0774e2554c --- /dev/null +++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationResult.aidl @@ -0,0 +1,30 @@ +/* + * Copyright 2022 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.allocator; + +import android.hardware.common.NativeHandle; + + /** + * Result of an IAllocator::allocate call. + * + * @sa +ndk libnativewindow#AHardwareBuffer_Desc + */ +@VintfStability +parcelable AllocationResult { + int stride; + NativeHandle[] buffers; +}
\ No newline at end of file diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl new file mode 100644 index 0000000000..8c3ca9601e --- /dev/null +++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl @@ -0,0 +1,36 @@ +/* + * Copyright 2022 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.allocator; + +import android.hardware.graphics.allocator.AllocationResult; + +@VintfStability +interface IAllocator { + /** + * Allocates buffers with the properties specified by the descriptor. + * + * Allocations should be optimized for usage bits provided in the + * descriptor. + * + * @param descriptor Properties of the buffers to allocate. This must be + * obtained from IMapper::createDescriptor(). + * @param count The number of buffers to allocate. + * @return An AllocationResult containing the result of an error, or + * an AllocationError status + */ + AllocationResult allocate(in byte[] descriptor, in int count); +} diff --git a/graphics/common/OWNERS b/graphics/common/OWNERS new file mode 100644 index 0000000000..94999ea409 --- /dev/null +++ b/graphics/common/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 1075130 +adyabr@google.com +alecmouri@google.com +jreck@google.com +scroggo@google.com diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl index b4ef4515c7..e1edb17793 100644 --- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/BufferUsage.aidl @@ -54,10 +54,11 @@ enum BufferUsage { RENDERSCRIPT = 1048576, VIDEO_DECODER = 4194304, SENSOR_DIRECT_DATA = 8388608, + GPU_DATA_BUFFER = 16777216, GPU_CUBE_MAP = 33554432, GPU_MIPMAP_COMPLETE = 67108864, HW_IMAGE_ENCODER = 134217728, - GPU_DATA_BUFFER = 16777216, + FRONT_BUFFER = 4294967296, VENDOR_MASK = -268435456, VENDOR_MASK_HI = -281474976710656, } diff --git a/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl index d978f46345..4b5a306881 100644 --- a/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl +++ b/graphics/common/aidl/android/hardware/graphics/common/BufferUsage.aidl @@ -87,6 +87,12 @@ enum BufferUsage { /** buffer is used as a sensor direct report output */ SENSOR_DIRECT_DATA = 1 << 23, + /** + * buffer is used as as an OpenGL shader storage or uniform + * buffer object + */ + GPU_DATA_BUFFER = 1 << 24, + /** buffer is used as a cube map texture */ GPU_CUBE_MAP = 1 << 25, @@ -98,17 +104,17 @@ enum BufferUsage { */ HW_IMAGE_ENCODER = 1 << 27, + /* Bits 28-31 are reserved for vendor usage */ + /** - * buffer is used as as an OpenGL shader storage or uniform - * buffer object - */ - GPU_DATA_BUFFER = 1 << 24, + * Buffer is used for front-buffer rendering + */ + FRONT_BUFFER = 1L << 32, - /** bits 25-27 must be zero and are reserved for future versions */ /** bits 28-31 are reserved for vendor extensions */ VENDOR_MASK = 0xf << 28, - /** bits 32-47 must be zero and are reserved for future versions */ + /** bits 33-47 must be zero and are reserved for future versions */ /** bits 48-63 are reserved for vendor extensions */ VENDOR_MASK_HI = (1L * 0xffff) << 48, } diff --git a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl index 7719d6e61d..74a9ce309b 100644 --- a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl +++ b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl @@ -22,8 +22,9 @@ package android.hardware.graphics.common; * This is an enum that defines the common types of gralloc 4 buffer metadata. The comments for * each enum include a description of the metadata that is associated with the type. * - * IMapper@4.x must support getting the following standard buffer metadata types. IMapper@4.x may - * support setting these standard buffer metadata types as well. + * IMapper@4.x must support getting the following standard buffer metadata types, with the exception + * of SMPTE 2094-10 metadata. IMapper@4.x may support setting these standard buffer metadata types + * as well. * * When encoding these StandardMetadataTypes into a byte stream, the associated MetadataType is * is first encoded followed by the StandardMetadataType value. The MetadataType is encoded by diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp index b071f71e85..fa294ff259 100644 --- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp +++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp @@ -161,7 +161,8 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> { return mGralloc->allocate( width, height, /*layerCount*/ 1, static_cast<common::V1_1::PixelFormat>(PixelFormat::RGBA_8888), - static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN)); + static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN | + BufferUsage::COMPOSER_OVERLAY)); } struct TestParameters { diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp index 741572db57..bd2c3b1248 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp @@ -50,6 +50,7 @@ cc_test { "libgui", "libhidlbase", "libprocessgroup", + "libtinyxml2", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.graphics.mapper@3.0", diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp index e519221159..3f1e703031 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp @@ -24,10 +24,18 @@ #include <composer-vts/include/ReadbackVts.h> #include <composer-vts/include/RenderEngineVts.h> #include <gtest/gtest.h> +#include <ui/DisplayId.h> +#include <ui/DisplayIdentification.h> #include <ui/GraphicBuffer.h> #include <ui/GraphicBufferAllocator.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> + +// tinyxml2 does implicit conversions >:( +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wconversion" +#include <tinyxml2.h> +#pragma clang diagnostic pop #include "composer-vts/include/GraphicsComposerCallback.h" namespace aidl::android::hardware::graphics::composer3::vts { @@ -124,6 +132,76 @@ class GraphicsCompositionTestBase : public ::testing::Test { /*layerCount*/ 1u, usage, "VtsHalGraphicsComposer3_ReadbackTest"); } + uint64_t getStableDisplayId(int64_t display) { + DisplayIdentification identification; + const auto error = mComposerClient->getDisplayIdentificationData(display, &identification); + EXPECT_TRUE(error.isOk()); + + if (const auto info = ::android::parseDisplayIdentificationData( + static_cast<uint8_t>(identification.port), identification.data)) { + return info->id.value; + } + + return ::android::PhysicalDisplayId::fromPort(static_cast<uint8_t>(identification.port)) + .value; + } + + // Gets the per-display XML config + std::unique_ptr<tinyxml2::XMLDocument> getDisplayConfigXml(int64_t display) { + std::stringstream pathBuilder; + pathBuilder << "/vendor/etc/displayconfig/display_id_" << getStableDisplayId(display) + << ".xml"; + const std::string path = pathBuilder.str(); + auto document = std::make_unique<tinyxml2::XMLDocument>(); + const tinyxml2::XMLError error = document->LoadFile(path.c_str()); + if (error == tinyxml2::XML_SUCCESS) { + return document; + } else { + return nullptr; + } + } + + // Gets the max display brightness for this display. + // If the display config xml does not exist, then assume that the display is not well-configured + // enough to provide a display brightness, so return nullopt. + std::optional<float> getMaxDisplayBrightnessNits(int64_t display) { + const auto document = getDisplayConfigXml(display); + if (!document) { + // Assume the device doesn't support display brightness + return std::nullopt; + } + + const auto root = document->RootElement(); + if (!root) { + // If there's somehow no root element, then this isn't a valid config + return std::nullopt; + } + + const auto screenBrightnessMap = root->FirstChildElement("screenBrightnessMap"); + if (!screenBrightnessMap) { + // A valid display config must have a screen brightness map + return std::nullopt; + } + + auto point = screenBrightnessMap->FirstChildElement("point"); + float maxNits = -1.f; + while (point != nullptr) { + const auto nits = point->FirstChildElement("nits"); + if (nits) { + maxNits = std::max(maxNits, nits->FloatText(-1.f)); + } + point = point->NextSiblingElement("point"); + } + + if (maxNits < 0.f) { + // If we got here, then there were no point elements containing a nit value, so this + // config isn't valid + return std::nullopt; + } + + return maxNits; + } + void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) { for (auto layer : layers) { layer->write(mWriter); @@ -250,8 +328,8 @@ TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) { std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight)); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(layers); @@ -286,8 +364,8 @@ TEST_P(GraphicsCompositionTest, SetLayerBuffer) { return; } - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight)); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, @@ -363,8 +441,8 @@ TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) { std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight)); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp); @@ -389,8 +467,8 @@ TEST_P(GraphicsCompositionTest, SetReadbackBuffer) { return; } - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, mDisplayWidth, - mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, mDisplayHeight, + mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); } @@ -419,8 +497,13 @@ TEST_P(GraphicsCompositionTest, SetReadbackBufferBadParameter) { return; } - aidl::android::hardware::common::NativeHandle bufferHandle = - ::android::dupToAidl(mGraphicBuffer->handle); + aidl::android::hardware::common::NativeHandle bufferHandle; + { + ::android::sp<::android::GraphicBuffer> buffer = allocate(); + ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck()); + ::android::makeToAidl(mGraphicBuffer->handle); + } + ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1); const auto error = mComposerClient->setReadbackBuffer(mPrimaryDisplay, bufferHandle, releaseFence); @@ -438,8 +521,9 @@ TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) { ndk::ScopedFileDescriptor releaseFence; const auto error = mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &releaseFence); - EXPECT_TRUE(error.isOk()); + ASSERT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError()); + EXPECT_EQ(-1, releaseFence.get()); } TEST_P(GraphicsCompositionTest, ClientComposition) { @@ -474,8 +558,8 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { std::vector<std::shared_ptr<TestLayer>> layers = {layer}; - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(layers); ASSERT_TRUE(mReader.takeErrors().empty()); @@ -553,8 +637,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); auto deviceLayer = std::make_shared<TestBufferLayer>( @@ -657,8 +741,8 @@ TEST_P(GraphicsCompositionTest, SetLayerDamage) { std::vector<std::shared_ptr<TestLayer>> layers = {layer}; - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(layers); @@ -720,8 +804,8 @@ TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) { std::vector<std::shared_ptr<TestLayer>> layers = {layer}; - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); @@ -781,8 +865,8 @@ TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) { // update expected colors to match crop ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight}, BLUE); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(layers); ASSERT_TRUE(mReader.takeErrors().empty()); @@ -834,8 +918,8 @@ TEST_P(GraphicsCompositionTest, SetLayerZOrder) { ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(layers); @@ -876,6 +960,90 @@ TEST_P(GraphicsCompositionTest, SetLayerZOrder) { } } +TEST_P(GraphicsCompositionTest, SetLayerWhitePointDims) { + std::vector<DisplayCapability> capabilities; + const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities); + ASSERT_TRUE(error.isOk()); + + const bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(), + DisplayCapability::BRIGHTNESS) != capabilities.end(); + + if (!brightnessSupport) { + GTEST_SUCCEED() << "Cannot verify dimming behavior without brightness support"; + return; + } + + const std::optional<float> maxBrightnessNitsOptional = + getMaxDisplayBrightnessNits(mPrimaryDisplay); + + ASSERT_TRUE(maxBrightnessNitsOptional.has_value()); + + const float maxBrightnessNits = *maxBrightnessNitsOptional; + + // Preconditions to successfully run are knowing the max brightness and successfully applying + // the max brightness + ASSERT_GT(maxBrightnessNits, 0.f); + mWriter.setDisplayBrightness(mPrimaryDisplay, 1.f); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + for (ColorMode mode : mTestColorModes) { + ASSERT_NO_FATAL_FAILURE( + mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); + + if (!getHasReadbackBuffer()) { + GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace for " + "color mode: " + << toString(mode); + continue; + } + const common::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2}; + const common::Rect dimmerRedRect = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}; + const auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); + redLayer->setColor(RED); + redLayer->setDisplayFrame(redRect); + redLayer->setWhitePointNits(maxBrightnessNits); + + const auto dimmerRedLayer = + std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); + dimmerRedLayer->setColor(RED); + dimmerRedLayer->setDisplayFrame(dimmerRedRect); + // Intentionally use a small dimming ratio as some implementations may be more likely to + // kick into GPU composition to apply dithering when the dimming ratio is high. + static constexpr float kDimmingRatio = 0.9f; + dimmerRedLayer->setWhitePointNits(maxBrightnessNits * kDimmingRatio); + + const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer}; + std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight)); + + ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); + ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, dimmerRedRect, DIM_RED); + + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); + ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); + + writeLayers(layers); + ASSERT_TRUE(mReader.takeErrors().empty()); + mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp); + execute(); + if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) { + GTEST_SUCCEED() + << "Readback verification not supported for GPU composition for color mode: " + << toString(mode); + continue; + } + mWriter.presentDisplay(mPrimaryDisplay); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); + mTestRenderEngine->setRenderLayers(layers); + ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers()); + ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors)); + } +} + class GraphicsBlendModeCompositionTest : public GraphicsCompositionTestBase, public testing::WithParamInterface<std::tuple<std::string, std::string>> { @@ -973,8 +1141,8 @@ TEST_P(GraphicsBlendModeCompositionTest, None) { setUpLayers(BlendMode::NONE); setExpectedColors(expectedColors); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(mLayers); ASSERT_TRUE(mReader.takeErrors().empty()); @@ -1014,8 +1182,8 @@ TEST_P(GraphicsBlendModeCompositionTest, Coverage) { setUpLayers(BlendMode::COVERAGE); setExpectedColors(expectedColors); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(mLayers); ASSERT_TRUE(mReader.takeErrors().empty()); @@ -1050,8 +1218,8 @@ TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) { setUpLayers(BlendMode::PREMULTIPLIED); setExpectedColors(expectedColors); - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); writeLayers(mLayers); ASSERT_TRUE(mReader.takeErrors().empty()); @@ -1120,8 +1288,8 @@ TEST_P(GraphicsTransformCompositionTest, FLIP_H) { GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; return; } - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); mLayer->setTransform(Transform::FLIP_H); mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -1161,8 +1329,8 @@ TEST_P(GraphicsTransformCompositionTest, FLIP_V) { GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; return; } - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); mLayer->setTransform(Transform::FLIP_V); @@ -1202,8 +1370,8 @@ TEST_P(GraphicsTransformCompositionTest, ROT_180) { GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; return; } - ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, - mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace); + ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, + mDisplayHeight, mPixelFormat, mDataspace); ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); mLayer->setTransform(Transform::ROT_180); diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index 1cfd3f95bb..0a12f1a592 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -76,7 +76,10 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { ASSERT_NE(binder, nullptr); ASSERT_NO_FATAL_FAILURE(mComposer = IComposer::fromBinder(binder)); ASSERT_NE(mComposer, nullptr); - ASSERT_NO_FATAL_FAILURE(mComposer->createClient(&mComposerClient)); + + ndk::ScopedAStatus status; + ASSERT_NO_FATAL_FAILURE(status = mComposer->createClient(&mComposerClient)); + ASSERT_TRUE(status.isOk()); mComposerCallback = ::ndk::SharedRefBase::make<GraphicsComposerCallback>(); EXPECT_TRUE(mComposerClient->registerCallback(mComposerCallback).isOk()); @@ -188,6 +191,14 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { resourceIt->second.layers.erase(layer); } + bool hasCapability(Capability capability) { + std::vector<Capability> capabilities; + EXPECT_TRUE(mComposer->getCapabilities(&capabilities).isOk()); + return std::any_of( + capabilities.begin(), capabilities.end(), + [&](const Capability& activeCapability) { return activeCapability == capability; }); + } + // returns an invalid display id (one that has not been registered to a // display. Currently assuming that a device will never have close to // std::numeric_limit<uint64_t>::max() displays registered while running tests @@ -1474,6 +1485,11 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { } void Test_expectedPresentTime(std::optional<int> framesDelay) { + if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) { + GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping"; + return; + } + ASSERT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON).isOk()); const auto vsyncPeriod = getVsyncPeriod(); @@ -1538,7 +1554,7 @@ TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) { execute(); const auto errors = mReader.takeErrors(); - if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) { + if (errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_UNSUPPORTED) { GTEST_SUCCEED() << "setLayerColorTransform is not supported"; return; } @@ -1555,7 +1571,7 @@ TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) { execute(); const auto errors = mReader.takeErrors(); EXPECT_EQ(1, errors.size()); - EXPECT_EQ(EX_UNSUPPORTED_OPERATION, errors[0].errorCode); + EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode); GTEST_SUCCEED() << "SetDisplayBrightness is not supported"; return; } @@ -1650,10 +1666,7 @@ TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY) { */ // TODO(b/208441745) fix the test failure TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) { - std::vector<Capability> capabilities; - EXPECT_TRUE(mComposer->getCapabilities(&capabilities).isOk()); - if (none_of(capabilities.begin(), capabilities.end(), - [&](auto item) { return item == Capability::SKIP_VALIDATE; })) { + if (!hasCapability(Capability::SKIP_VALIDATE)) { GTEST_SUCCEED() << "Device does not have skip validate capability, skipping"; return; } @@ -1881,10 +1894,7 @@ TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PLANE_ALPHA) { } TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SIDEBAND_STREAM) { - std::vector<Capability> capabilities; - EXPECT_TRUE(mComposer->getCapabilities(&capabilities).isOk()); - if (none_of(capabilities.begin(), capabilities.end(), - [&](auto& item) { return item == Capability::SIDEBAND_STREAM; })) { + if (!hasCapability(Capability::SIDEBAND_STREAM)) { GTEST_SUCCEED() << "no sideband stream support"; return; } @@ -2024,6 +2034,27 @@ TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PER_FRAME_METADATA) { EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk()); } +TEST_P(GraphicsComposerAidlCommandTest, setLayerWhitePointNits) { + int64_t layer; + EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk()); + + mWriter.setLayerWhitePointNits(mPrimaryDisplay, layer, 200.f); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + mWriter.setLayerWhitePointNits(mPrimaryDisplay, layer, 1000.f); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + mWriter.setLayerWhitePointNits(mPrimaryDisplay, layer, 0.f); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + mWriter.setLayerWhitePointNits(mPrimaryDisplay, layer, -1.f); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); +} + TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints) { Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false}); } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp index ee597a1b1c..587c523d19 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp @@ -41,6 +41,7 @@ void TestLayer::write(ComposerClientWriter& writer) { writer.setLayerTransform(mDisplay, mLayer, mTransform); writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha); writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode); + writer.setLayerWhitePointNits(mDisplay, mLayer, mWhitePointNits); } std::string ReadbackHelper::getColorModeString(ColorMode mode) { @@ -103,6 +104,7 @@ LayerSettings TestLayer::toRenderEngineLayerSettings() { 1.0f, 1.0f)); layerSettings.geometry.positionTransform = scale * translation; + layerSettings.whitePointNits = mWhitePointNits; return layerSettings; } @@ -175,18 +177,17 @@ bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat, return true; } -void ReadbackHelper::compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData, - const int32_t stride, const uint32_t width, +void ReadbackHelper::compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData, + const uint32_t stride, const uint32_t width, const uint32_t height, common::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++) { auto pixel = row * static_cast<int32_t>(width) + col; - int offset = (row * stride + col) * bytesPerPixel; + int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel; uint8_t* pixelColor = (uint8_t*)bufferData + offset; const Color expectedColor = expectedColors[static_cast<size_t>(pixel)]; - ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]); ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]); ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]); @@ -195,13 +196,11 @@ void ReadbackHelper::compareColorBuffers(std::vector<Color>& expectedColors, voi } ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client, - const ::android::sp<::android::GraphicBuffer>& graphicBuffer, int32_t width, int32_t height, common::PixelFormat pixelFormat, common::Dataspace dataspace) { mDisplay = display; mComposerClient = client; - mGraphicBuffer = graphicBuffer; mPixelFormat = pixelFormat; mDataspace = dataspace; @@ -235,19 +234,24 @@ void ReadbackBuffer::setReadbackBuffer() { } void ReadbackBuffer::checkReadbackBuffer(std::vector<Color> expectedColors) { + ASSERT_NE(nullptr, mGraphicBuffer); // lock buffer for reading ndk::ScopedFileDescriptor fenceHandle; EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle).isOk()); - int outBytesPerPixel; - int outBytesPerStride; + int bytesPerPixel = -1; + int bytesPerStride = -1; void* bufData = nullptr; - auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, fenceHandle.get(), - &outBytesPerPixel, &outBytesPerStride); + + auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, dup(fenceHandle.get()), + &bytesPerPixel, &bytesPerStride); EXPECT_EQ(::android::OK, status); ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888); - ReadbackHelper::compareColorBuffers(expectedColors, bufData, static_cast<int32_t>(mStride), - mWidth, mHeight, mPixelFormat); + const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0) + ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel) + : mGraphicBuffer->getStride(); + ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight, + mPixelFormat); status = mGraphicBuffer->unlock(); EXPECT_EQ(::android::OK, status); } @@ -303,10 +307,7 @@ LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); layerSettings.source.buffer.buffer = std::make_shared<::android::renderengine::impl::ExternalTexture>( - ::android::sp<::android::GraphicBuffer>::make( - mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, - mHeight, static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride), - mRenderEngine.getInternalRenderEngine(), + mGraphicBuffer, mRenderEngine.getInternalRenderEngine(), ::android::renderengine::impl::ExternalTexture::Usage::READABLE); layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED; @@ -317,7 +318,7 @@ LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { const float translateY = mSourceCrop.top / (static_cast<float>(mHeight)); layerSettings.source.buffer.textureTransform = - ::android::mat4::translate(::android::vec4(translateX, translateY, 0, 1)) * + ::android::mat4::translate(::android::vec4(translateX, translateY, 0, 1.0)) * ::android::mat4::scale(::android::vec4(scaleX, scaleY, 1.0, 1.0)); return layerSettings; @@ -325,9 +326,14 @@ LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { void TestBufferLayer::fillBuffer(std::vector<Color>& expectedColors) { void* bufData; - auto status = mGraphicBuffer->lock(mUsage, &bufData); + int32_t bytesPerPixel = -1; + int32_t bytesPerStride = -1; + auto status = mGraphicBuffer->lock(mUsage, &bufData, &bytesPerPixel, &bytesPerStride); + const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0) + ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel) + : mGraphicBuffer->getStride(); EXPECT_EQ(::android::OK, status); - ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData, + ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData, mPixelFormat, expectedColors)); EXPECT_EQ(::android::OK, mGraphicBuffer->unlock()); } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp index 6ff064f93c..0a55484c78 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp @@ -77,13 +77,18 @@ void TestRenderEngine::drawLayers() { } } -void TestRenderEngine::checkColorBuffer(std::vector<Color>& expectedColors) { +void TestRenderEngine::checkColorBuffer(const std::vector<Color>& expectedColors) { void* bufferData; - ASSERT_EQ(0, - mGraphicBuffer->lock(static_cast<uint32_t>(mGraphicBuffer->getUsage()), &bufferData)); - ReadbackHelper::compareColorBuffers( - expectedColors, bufferData, static_cast<int32_t>(mGraphicBuffer->getStride()), - mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(), mFormat); + int32_t bytesPerPixel = -1; + int32_t bytesPerStride = -1; + ASSERT_EQ(0, mGraphicBuffer->lock(static_cast<uint32_t>(mGraphicBuffer->getUsage()), + &bufferData, &bytesPerPixel, &bytesPerStride)); + const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0) + ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel) + : mGraphicBuffer->getStride(); + ReadbackHelper::compareColorBuffers(expectedColors, bufferData, stride, + mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(), + mFormat); ASSERT_EQ(::android::OK, mGraphicBuffer->unlock()); } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h index 0fac2b3bfe..a3ce795db1 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h @@ -43,6 +43,10 @@ using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper; static const Color BLACK = {0.0f, 0.0f, 0.0f, 1.0f}; static const Color RED = {1.0f, 0.0f, 0.0f, 1.0f}; +// DIM_RED is 90% dimmed from RED in linear space +// hard-code as value 243 in 8-bit space here, as calculating it requires +// oetf(eotf(value) * .9), which is a complex non-linear transformation +static const Color DIM_RED = {243.f / 255.f, 0.0f, 0.0f, 1.0f}; static const Color TRANSLUCENT_RED = {1.0f, 0.0f, 0.0f, 0.3f}; static const Color GREEN = {0.0f, 1.0f, 0.0f, 1.0f}; static const Color BLUE = {0.0f, 0.0f, 1.0f, 1.0f}; @@ -67,6 +71,7 @@ class TestLayer { void setDisplayFrame(Rect frame) { mDisplayFrame = frame; } void setSourceCrop(FRect crop) { mSourceCrop = crop; } void setZOrder(uint32_t z) { mZOrder = z; } + void setWhitePointNits(float whitePointNits) { mWhitePointNits = whitePointNits; } void setSurfaceDamage(std::vector<Rect> surfaceDamage) { mSurfaceDamage = std::move(surfaceDamage); @@ -84,10 +89,13 @@ class TestLayer { int64_t getLayer() const { return mLayer; } + float getWhitePointNits() const { return mWhitePointNits; } + protected: int64_t mDisplay; int64_t mLayer; Rect mDisplayFrame = {0, 0, 0, 0}; + float mWhitePointNits = -1.f; std::vector<Rect> mSurfaceDamage; Transform mTransform = static_cast<Transform>(0); FRect mSourceCrop = {0, 0, 0, 0}; @@ -153,7 +161,6 @@ class TestBufferLayer : public TestLayer { uint32_t mLayerCount; PixelFormat mPixelFormat; uint32_t mUsage; - uint32_t mStride; ::android::Rect mAccessRegion; }; @@ -181,15 +188,14 @@ class ReadbackHelper { static const std::vector<ColorMode> colorModes; static const std::vector<Dataspace> dataspaces; - static void compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData, - const int32_t stride, const uint32_t width, + static void compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData, + const uint32_t stride, const uint32_t width, const uint32_t height, PixelFormat pixelFormat); }; class ReadbackBuffer { public: - ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client, - const ::android::sp<::android::GraphicBuffer>& graphicBuffer, int32_t width, + ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client, int32_t width, int32_t height, common::PixelFormat pixelFormat, common::Dataspace dataspace); void setReadbackBuffer(); @@ -203,7 +209,6 @@ class ReadbackBuffer { uint32_t mHeight; uint32_t mLayerCount; uint32_t mUsage; - uint32_t mStride; PixelFormat mPixelFormat; Dataspace mDataspace; int64_t mDisplay; diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h index 2798e092a0..a776a279c4 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h @@ -54,7 +54,7 @@ class TestRenderEngine { mDisplaySettings = displaySettings; }; void drawLayers(); - void checkColorBuffer(std::vector<Color>& expectedColors); + void checkColorBuffer(const std::vector<Color>& expectedColors); ::android::renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; } diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp index 2ab9c01c5d..5e012f6ef7 100644 --- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp +++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp @@ -21,6 +21,7 @@ #include <thread> #include <vector> +#include <aidl/android/hardware/graphics/common/PixelFormat.h> #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h> #include <android-base/logging.h> @@ -92,7 +93,13 @@ class GraphicsMapperHidlTest ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(descriptorInfo, true)); hidl_vec<uint8_t> vec; - ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, metadataType, &vec)); + const auto result = mGralloc->get(bufferHandle, metadataType, &vec); + + if (metadataType == gralloc4::MetadataType_Smpte2094_10 && result == Error::UNSUPPORTED) { + GTEST_SKIP() << "getting metadata for Smpte2094-10 is unsupported"; + } + + ASSERT_EQ(Error::NONE, result); ASSERT_NO_FATAL_FAILURE(decode(descriptorInfo, vec)); } @@ -1205,6 +1212,40 @@ TEST_P(GraphicsMapperHidlTest, IsSupportedY16) { } /** + * Test IMapper::isSupported with optional format R_8 + */ +TEST_P(GraphicsMapperHidlTest, IsSupportedR8) { + auto info = mDummyDescriptorInfo; + info.format = static_cast<android::hardware::graphics::common::V1_2::PixelFormat>( + aidl::android::hardware::graphics::common::PixelFormat::R_8); + bool supported = false; + + ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info)); + + if (!supported) { + GTEST_SUCCEED() << "R_8 is optional; unsupported so skipping allocation test"; + return; + } + + BufferDescriptor descriptor; + ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(info)); + + constexpr uint32_t count = 1; + std::vector<const native_handle_t*> bufferHandles; + uint32_t stride; + ASSERT_NO_FATAL_FAILURE(bufferHandles = + mGralloc->allocate(descriptor, count, false, + Tolerance::kToleranceStrict, &stride)); + + EXPECT_LE(info.width, stride) << "invalid buffer stride"; + EXPECT_EQ(1u, bufferHandles.size()); + + for (auto bufferHandle : bufferHandles) { + mGralloc->freeBuffer(bufferHandle); + } +} + +/** * Test IMapper::get(BufferId) */ TEST_P(GraphicsMapperHidlTest, GetBufferId) { |