Merge "IComposerClient wrapper for VTS tests"

This commit is contained in:
Ram Indani 2022-01-29 01:52:29 +00:00 committed by Android (Google) Code Review
commit d1cbbea53f
8 changed files with 716 additions and 106 deletions

View file

@ -35,6 +35,9 @@ cc_test {
"VtsHalGraphicsComposer3_TargetTest.cpp",
"VtsHalGraphicsComposer3_ReadbackTest.cpp",
"composer-vts/GraphicsComposerCallback.cpp",
"composer-vts/ReadbackVts.cpp",
"composer-vts/RenderEngineVts.cpp",
"composer-vts/VtsComposerClient.cpp",
],
shared_libs: [
@ -72,15 +75,19 @@ cc_test {
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.composer@3-vts",
"android.hardware.graphics.mapper@2.0-vts",
"android.hardware.graphics.mapper@2.1-vts",
"android.hardware.graphics.mapper@3.0-vts",
"android.hardware.graphics.mapper@4.0-vts",
"libaidlcommonsupport",
"libarect",
"libbase",
"libfmq",
"libgtest",
"libmath",
"librenderengine",
"libshaders",
"libsync",
"libtonemap",
],
cflags: [

View file

@ -1,78 +0,0 @@
/**
* Copyright (c) 2021, 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 {
// 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"],
}
cc_library_static {
name: "android.hardware.graphics.composer@3-vts",
defaults: ["hidl_defaults"],
srcs: [
"GraphicsComposerCallback.cpp",
"ReadbackVts.cpp",
"RenderEngineVts.cpp",
],
header_libs: [
"android.hardware.graphics.composer3-command-buffer",
],
static_libs: [
"android.hardware.graphics.composer3-V1-ndk",
"android.hardware.graphics.common-V3-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
"libarect",
"libgtest",
"libbase",
"libfmq",
"libsync",
"libmath",
"libaidlcommonsupport",
"libnativewindow",
"librenderengine",
"libshaders",
"libtonemap",
"android.hardware.graphics.mapper@2.0-vts",
"android.hardware.graphics.mapper@2.1-vts",
"android.hardware.graphics.mapper@3.0-vts",
"android.hardware.graphics.mapper@4.0-vts",
],
shared_libs: [
"libbinder_ndk",
"libhidlbase",
"libui",
"android.hardware.graphics.composer3-V1-ndk",
],
export_static_lib_headers: [
"android.hardware.graphics.mapper@2.1-vts",
"librenderengine",
],
cflags: [
"-O0",
"-g",
"-DLOG_TAG=\"ComposerVts\"",
"-Wconversion",
],
export_header_lib_headers: [
"android.hardware.graphics.composer3-command-buffer",
],
export_include_dirs: ["include"],
}

View file

@ -0,0 +1,471 @@
/**
* Copyright (c) 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.
*/
#include "include/VtsComposerClient.h"
#include <aidlcommonsupport/NativeHandle.h>
#include <android-base/logging.h>
#include <log/log_main.h>
#undef LOG_TAG
#define LOG_TAG "VtsComposerClient"
using namespace std::chrono_literals;
namespace aidl::android::hardware::graphics::composer3::vts {
VtsComposerClient::VtsComposerClient(const std::string& name) {
SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
ALOGE_IF(binder == nullptr, "Could not initialize the service binder");
if (binder != nullptr) {
mComposer = IComposer::fromBinder(binder);
ALOGE_IF(mComposer == nullptr, "Failed to acquire the composer from the binder");
}
}
bool VtsComposerClient::createClient() {
if (mComposer == nullptr) {
ALOGE("IComposer not initialized");
return false;
}
auto error = mComposer->createClient(&mComposerClient);
if (!error.isOk() || mComposerClient == nullptr) {
ALOGE("Failed to create client for IComposerClient with %s",
error.getDescription().c_str());
return false;
}
mComposerCallback = SharedRefBase::make<GraphicsComposerCallback>();
if (mComposerCallback == nullptr) {
ALOGE("Unable to create ComposerCallback");
return false;
}
error = mComposerClient->registerCallback(mComposerCallback);
if (!error.isOk()) {
ALOGE("Unable to register the callback with IComposerClient, failed with %s",
error.getDescription().c_str());
return false;
}
return true;
}
bool VtsComposerClient::tearDown() {
return verifyComposerCallbackParams() && destroyAllLayers();
}
std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
VirtualDisplay outVirtualDisplay;
auto error = mComposerClient->createVirtualDisplay(width, height, pixelFormat, bufferSlotCount,
&outVirtualDisplay);
if (!error.isOk()) {
return {std::move(error), outVirtualDisplay};
}
return {addDisplayToDisplayResources(outVirtualDisplay.display, /*isVirtual*/ true),
outVirtualDisplay};
}
ScopedAStatus VtsComposerClient::destroyVirtualDisplay(int64_t display) {
auto error = mComposerClient->destroyVirtualDisplay(display);
if (!error.isOk()) {
return error;
}
mDisplayResources.erase(display);
return error;
}
std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
int32_t bufferSlotCount) {
int64_t outLayer;
auto error = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
if (!error.isOk()) {
return {std::move(error), outLayer};
}
return {addLayerToDisplayResources(display, outLayer), outLayer};
}
ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer) {
auto error = mComposerClient->destroyLayer(display, layer);
if (!error.isOk()) {
return error;
}
removeLayerFromDisplayResources(display, layer);
return error;
}
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
int32_t outConfig;
return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
}
ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay& vtsDisplay, int32_t config) {
auto error = mComposerClient->setActiveConfig(vtsDisplay.get(), config);
if (!error.isOk()) {
return error;
}
return updateDisplayProperties(vtsDisplay, config);
}
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
int64_t display, int32_t config, DisplayAttribute displayAttribute) {
int32_t outDisplayAttribute;
return {mComposerClient->getDisplayAttribute(display, config, displayAttribute,
&outDisplayAttribute),
outDisplayAttribute};
}
ScopedAStatus VtsComposerClient::setPowerMode(int64_t display, PowerMode powerMode) {
return mComposerClient->setPowerMode(display, powerMode);
}
ScopedAStatus VtsComposerClient::setVsync(int64_t display, bool enable) {
return mComposerClient->setVsyncEnabled(display, enable);
}
void VtsComposerClient::setVsyncAllowed(bool isAllowed) {
mComposerCallback->setVsyncAllowed(isAllowed);
}
std::pair<ScopedAStatus, std::vector<float>> VtsComposerClient::getDataspaceSaturationMatrix(
Dataspace dataspace) {
std::vector<float> outMatrix;
return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
}
std::pair<ScopedAStatus, std::vector<CommandResultPayload>> VtsComposerClient::executeCommands(
const std::vector<DisplayCommand>& commands) {
std::vector<CommandResultPayload> outResultPayload;
return {mComposerClient->executeCommands(commands, &outResultPayload),
std::move(outResultPayload)};
}
std::optional<VsyncPeriodChangeTimeline> VtsComposerClient::takeLastVsyncPeriodChangeTimeline() {
return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
}
ScopedAStatus VtsComposerClient::setContentType(int64_t display, ContentType contentType) {
return mComposerClient->setContentType(display, contentType);
}
std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
VtsComposerClient::setActiveConfigWithConstraints(VtsDisplay& vtsDisplay, int32_t config,
const VsyncPeriodChangeConstraints& constraints) {
VsyncPeriodChangeTimeline outTimeline;
auto error = mComposerClient->setActiveConfigWithConstraints(vtsDisplay.get(), config,
constraints, &outTimeline);
if (!error.isOk()) {
return {std::move(error), outTimeline};
}
return {updateDisplayProperties(vtsDisplay, config), outTimeline};
}
std::pair<ScopedAStatus, std::vector<DisplayCapability>> VtsComposerClient::getDisplayCapabilities(
int64_t display) {
std::vector<DisplayCapability> outCapabilities;
return {mComposerClient->getDisplayCapabilities(display, &outCapabilities), outCapabilities};
}
ScopedAStatus VtsComposerClient::dumpDebugInfo() {
std::string debugInfo;
return mComposer->dumpDebugInfo(&debugInfo);
}
std::pair<ScopedAStatus, DisplayIdentification> VtsComposerClient::getDisplayIdentificationData(
int64_t display) {
DisplayIdentification outDisplayIdentification;
return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
outDisplayIdentification};
}
std::pair<ScopedAStatus, HdrCapabilities> VtsComposerClient::getHdrCapabilities(int64_t display) {
HdrCapabilities outHdrCapabilities;
return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
}
std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
VtsComposerClient::getPerFrameMetadataKeys(int64_t display) {
std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
outPerFrameMetadataKeys};
}
std::pair<ScopedAStatus, ReadbackBufferAttributes> VtsComposerClient::getReadbackBufferAttributes(
int64_t display) {
ReadbackBufferAttributes outReadbackBufferAttributes;
return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
outReadbackBufferAttributes};
}
ScopedAStatus VtsComposerClient::setReadbackBuffer(int64_t display, const native_handle* buffer,
const ScopedFileDescriptor& releaseFence) {
return mComposerClient->setReadbackBuffer(display, ::android::dupToAidl(buffer), releaseFence);
}
std::pair<ScopedAStatus, ScopedFileDescriptor> VtsComposerClient::getReadbackBufferFence(
int64_t display) {
ScopedFileDescriptor outReleaseFence;
return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
std::move(outReleaseFence)};
}
std::pair<ScopedAStatus, std::vector<ColorMode>> VtsComposerClient::getColorModes(int64_t display) {
std::vector<ColorMode> outColorModes;
return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
}
std::pair<ScopedAStatus, std::vector<RenderIntent>> VtsComposerClient::getRenderIntents(
int64_t display, ColorMode colorMode) {
std::vector<RenderIntent> outRenderIntents;
return {mComposerClient->getRenderIntents(display, colorMode, &outRenderIntents),
outRenderIntents};
}
ScopedAStatus VtsComposerClient::setColorMode(int64_t display, ColorMode colorMode,
RenderIntent renderIntent) {
return mComposerClient->setColorMode(display, colorMode, renderIntent);
}
std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
VtsComposerClient::getDisplayedContentSamplingAttributes(int64_t display) {
DisplayContentSamplingAttributes outAttributes;
return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
outAttributes};
}
ScopedAStatus VtsComposerClient::setDisplayedContentSamplingEnabled(
int64_t display, bool isEnabled, FormatColorComponent formatColorComponent,
int64_t maxFrames) {
return mComposerClient->setDisplayedContentSamplingEnabled(display, isEnabled,
formatColorComponent, maxFrames);
}
std::pair<ScopedAStatus, DisplayContentSample> VtsComposerClient::getDisplayedContentSample(
int64_t display, int64_t maxFrames, int64_t timestamp) {
DisplayContentSample outDisplayContentSample;
return {mComposerClient->getDisplayedContentSample(display, maxFrames, timestamp,
&outDisplayContentSample),
outDisplayContentSample};
}
std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayConnectionType(
int64_t display) {
DisplayConnectionType outDisplayConnectionType;
return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
outDisplayConnectionType};
}
std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
int64_t display) {
std::vector<int32_t> outConfigs;
return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
}
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
int32_t outVsyncPeriodNanos;
return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
outVsyncPeriodNanos};
}
ScopedAStatus VtsComposerClient::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
}
std::pair<ScopedAStatus, std::vector<ContentType>> VtsComposerClient::getSupportedContentTypes(
int64_t display) {
std::vector<ContentType> outContentTypes;
return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
}
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxVirtualDisplayCount() {
int32_t outMaxVirtualDisplayCount;
return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
outMaxVirtualDisplayCount};
}
std::pair<ScopedAStatus, std::string> VtsComposerClient::getDisplayName(int64_t display) {
std::string outDisplayName;
return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
}
ScopedAStatus VtsComposerClient::setClientTargetSlotCount(int64_t display,
int32_t bufferSlotCount) {
return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
}
std::pair<ScopedAStatus, std::vector<Capability>> VtsComposerClient::getCapabilities() {
std::vector<Capability> outCapabilities;
return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
}
ScopedAStatus VtsComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
return mComposerClient->setBootDisplayConfig(display, config);
}
ScopedAStatus VtsComposerClient::clearBootDisplayConfig(int64_t display) {
return mComposerClient->clearBootDisplayConfig(display);
}
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getPreferredBootDisplayConfig(
int64_t display) {
int32_t outConfig;
return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
}
std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
int64_t display) {
common::Transform outDisplayOrientation;
return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
outDisplayOrientation};
}
std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays() {
while (true) {
// Sleep for a small period of time to allow all built-in displays
// to post hotplug events
std::this_thread::sleep_for(5ms);
std::vector<int64_t> displays = mComposerCallback->getDisplays();
if (displays.empty()) {
continue;
}
std::vector<VtsDisplay> vtsDisplays;
vtsDisplays.reserve(displays.size());
for (int64_t display : displays) {
auto activeConfig = getActiveConfig(display);
if (!activeConfig.first.isOk()) {
ALOGE("Unable to get the displays for test, failed to get the active config "
"for display %" PRId64,
display);
return {std::move(activeConfig.first), vtsDisplays};
}
auto vtsDisplay = VtsDisplay{display};
auto error = updateDisplayProperties(vtsDisplay, activeConfig.second);
if (!error.isOk()) {
ALOGE("Unable to get the displays for test, failed to update the properties "
"for display %" PRId64,
display);
return {std::move(error), vtsDisplays};
}
vtsDisplays.emplace_back(vtsDisplay);
addDisplayToDisplayResources(display, /*isVirtual*/ false);
}
return {ScopedAStatus::ok(), vtsDisplays};
}
}
ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay& vtsDisplay, int32_t config) {
const auto width = getDisplayAttribute(vtsDisplay.get(), config, DisplayAttribute::WIDTH);
const auto height = getDisplayAttribute(vtsDisplay.get(), config, DisplayAttribute::HEIGHT);
const auto vsyncPeriod =
getDisplayAttribute(vtsDisplay.get(), config, DisplayAttribute::VSYNC_PERIOD);
const auto configGroup =
getDisplayAttribute(vtsDisplay.get(), config, DisplayAttribute::CONFIG_GROUP);
if (width.first.isOk() && height.first.isOk() && vsyncPeriod.first.isOk() &&
configGroup.first.isOk()) {
vtsDisplay.setDimensions(width.second, height.second);
vtsDisplay.addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
return ScopedAStatus::ok();
}
LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
<< ", height: " << height.first.isOk() << ", vsync: " << vsyncPeriod.first.isOk()
<< ", config: " << configGroup.first.isOk();
return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
}
ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
return ScopedAStatus::ok();
}
ALOGE("Duplicate display id %" PRId64, display);
return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
}
ScopedAStatus VtsComposerClient::addLayerToDisplayResources(int64_t display, int64_t layer) {
auto resource = mDisplayResources.find(display);
if (resource == mDisplayResources.end()) {
resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
}
if (!resource->second.layers.insert(layer).second) {
ALOGE("Duplicate layer id %" PRId64, layer);
return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
}
return ScopedAStatus::ok();
}
void VtsComposerClient::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
auto resource = mDisplayResources.find(display);
if (resource != mDisplayResources.end()) {
resource->second.layers.erase(layer);
}
}
bool VtsComposerClient::verifyComposerCallbackParams() {
bool isValid = true;
if (mComposerCallback != nullptr) {
if (mComposerCallback->getInvalidHotplugCount() != 0) {
ALOGE("Invalid hotplug count");
isValid = false;
}
if (mComposerCallback->getInvalidRefreshCount() != 0) {
ALOGE("Invalid refresh count");
isValid = false;
}
if (mComposerCallback->getInvalidVsyncCount() != 0) {
ALOGE("Invalid vsync count");
isValid = false;
}
if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
ALOGE("Invalid vsync period change count");
isValid = false;
}
if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
ALOGE("Invalid seamless possible count");
isValid = false;
}
}
return isValid;
}
bool VtsComposerClient::destroyAllLayers() {
for (const auto& it : mDisplayResources) {
const auto& [display, resource] = it;
for (auto layer : resource.layers) {
const auto error = destroyLayer(display, layer);
if (!error.isOk()) {
ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
layer, error.getDescription().c_str());
return false;
}
}
if (resource.isVirtual) {
const auto error = destroyVirtualDisplay(display);
if (!error.isOk()) {
ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
error.getDescription().c_str());
return false;
}
}
}
mDisplayResources.clear();
return true;
}
} // namespace aidl::android::hardware::graphics::composer3::vts

View file

@ -15,18 +15,11 @@
*/
#pragma once
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#include <aidl/android/hardware/graphics/composer3/BnComposerCallback.h>
#include <android-base/thread_annotations.h>
#include <mutex>
#include <unordered_set>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion
namespace aidl::android::hardware::graphics::composer3::vts {
class GraphicsComposerCallback : public BnComposerCallback {

View file

@ -16,11 +16,6 @@
#pragma once
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#include <GraphicsComposerCallback.h>
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
@ -28,11 +23,8 @@
#include <mapper-vts/2.1/MapperVts.h>
#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>
#include <memory>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion
#include "GraphicsComposerCallback.h"
namespace aidl::android::hardware::graphics::composer3::vts {

View file

@ -15,11 +15,6 @@
*/
#pragma once
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#include <ReadbackVts.h>
#include <mapper-vts/2.1/MapperVts.h>
#include <math/half.h>
#include <math/vec3.h>
@ -30,9 +25,7 @@
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <ui/Region.h>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion
#include "ReadbackVts.h"
namespace aidl::android::hardware::graphics::composer3::vts {

View file

@ -0,0 +1,232 @@
/**
* Copyright (c) 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.
*/
#pragma once
#include <aidl/android/hardware/graphics/common/BlendMode.h>
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
#include <aidl/android/hardware/graphics/common/FRect.h>
#include <aidl/android/hardware/graphics/common/Rect.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/IComposer.h>
#include <android-base/properties.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
#include <binder/ProcessState.h>
#include <gtest/gtest.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
#include <algorithm>
#include <numeric>
#include <string>
#include <thread>
#include <unordered_map>
#include "GraphicsComposerCallback.h"
using aidl::android::hardware::graphics::common::Dataspace;
using aidl::android::hardware::graphics::common::FRect;
using aidl::android::hardware::graphics::common::PixelFormat;
using aidl::android::hardware::graphics::common::Rect;
using namespace ::ndk;
namespace aidl::android::hardware::graphics::composer3::vts {
class VtsDisplay;
/**
* A wrapper to IComposerClient.
* This wrapper manages the IComposerClient instance and manages the resources for
* the tests with respect to the IComposerClient calls.
*/
class VtsComposerClient {
public:
VtsComposerClient(const std::string& name);
bool createClient();
bool tearDown();
std::pair<ScopedAStatus, VirtualDisplay> createVirtualDisplay(int32_t width, int32_t height,
PixelFormat pixelFormat,
int32_t bufferSlotCount);
ScopedAStatus destroyVirtualDisplay(int64_t display);
std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount);
ScopedAStatus destroyLayer(int64_t display, int64_t layer);
std::pair<ScopedAStatus, int32_t> getActiveConfig(int64_t display);
ScopedAStatus setActiveConfig(VtsDisplay& vtsDisplay, int32_t config);
std::pair<ScopedAStatus, int32_t> getDisplayAttribute(int64_t display, int32_t config,
DisplayAttribute displayAttribute);
ScopedAStatus setPowerMode(int64_t display, PowerMode powerMode);
ScopedAStatus setVsync(int64_t display, bool enable);
void setVsyncAllowed(bool isAllowed);
std::pair<ScopedAStatus, std::vector<float>> getDataspaceSaturationMatrix(Dataspace dataspace);
std::pair<ScopedAStatus, std::vector<CommandResultPayload>> executeCommands(
const std::vector<DisplayCommand>& commands);
std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline();
ScopedAStatus setContentType(int64_t display, ContentType contentType);
std::pair<ScopedAStatus, VsyncPeriodChangeTimeline> setActiveConfigWithConstraints(
VtsDisplay& vtsDisplay, int32_t config,
const VsyncPeriodChangeConstraints& constraints);
std::pair<ScopedAStatus, std::vector<DisplayCapability>> getDisplayCapabilities(
int64_t display);
ScopedAStatus dumpDebugInfo();
std::pair<ScopedAStatus, DisplayIdentification> getDisplayIdentificationData(int64_t display);
std::pair<ScopedAStatus, HdrCapabilities> getHdrCapabilities(int64_t display);
std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>> getPerFrameMetadataKeys(
int64_t display);
std::pair<ScopedAStatus, ReadbackBufferAttributes> getReadbackBufferAttributes(int64_t display);
ScopedAStatus setReadbackBuffer(int64_t display, const native_handle* buffer,
const ScopedFileDescriptor& releaseFence);
std::pair<ScopedAStatus, ScopedFileDescriptor> getReadbackBufferFence(int64_t display);
std::pair<ScopedAStatus, std::vector<ColorMode>> getColorModes(int64_t display);
std::pair<ScopedAStatus, std::vector<RenderIntent>> getRenderIntents(int64_t display,
ColorMode colorMode);
ScopedAStatus setColorMode(int64_t display, ColorMode colorMode, RenderIntent renderIntent);
std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
getDisplayedContentSamplingAttributes(int64_t display);
ScopedAStatus setDisplayedContentSamplingEnabled(int64_t display, bool isEnabled,
FormatColorComponent formatColorComponent,
int64_t maxFrames);
std::pair<ScopedAStatus, DisplayContentSample> getDisplayedContentSample(int64_t display,
int64_t maxFrames,
int64_t timestamp);
std::pair<ScopedAStatus, DisplayConnectionType> getDisplayConnectionType(int64_t display);
std::pair<ScopedAStatus, std::vector<int32_t>> getDisplayConfigs(int64_t display);
std::pair<ScopedAStatus, int32_t> getDisplayVsyncPeriod(int64_t display);
ScopedAStatus setAutoLowLatencyMode(int64_t display, bool isEnabled);
std::pair<ScopedAStatus, std::vector<ContentType>> getSupportedContentTypes(int64_t display);
std::pair<ScopedAStatus, int32_t> getMaxVirtualDisplayCount();
std::pair<ScopedAStatus, std::string> getDisplayName(int64_t display);
ScopedAStatus setClientTargetSlotCount(int64_t display, int32_t bufferSlotCount);
std::pair<ScopedAStatus, std::vector<Capability>> getCapabilities();
ScopedAStatus setBootDisplayConfig(int64_t display, int32_t config);
ScopedAStatus clearBootDisplayConfig(int64_t display);
std::pair<ScopedAStatus, int32_t> getPreferredBootDisplayConfig(int64_t display);
std::pair<ScopedAStatus, common::Transform> getDisplayPhysicalOrientation(int64_t display);
std::pair<ScopedAStatus, std::vector<VtsDisplay>> getDisplays();
private:
ScopedAStatus updateDisplayProperties(VtsDisplay& vtsDisplay, int32_t config);
ScopedAStatus addDisplayToDisplayResources(int64_t display, bool isVirtual);
ScopedAStatus addLayerToDisplayResources(int64_t display, int64_t layer);
void removeLayerFromDisplayResources(int64_t display, int64_t layer);
bool destroyAllLayers();
bool verifyComposerCallbackParams();
// Keep track of displays and layers. When a test fails/ends,
// the VtsComposerClient::tearDown should be called from the
// test tearDown to clean up the resources for the test.
struct DisplayResource {
DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}
bool isVirtual;
std::unordered_set<int64_t> layers;
};
std::shared_ptr<IComposer> mComposer;
std::shared_ptr<IComposerClient> mComposerClient;
std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
std::unordered_map<int64_t, DisplayResource> mDisplayResources;
};
class VtsDisplay {
public:
VtsDisplay(int64_t displayId) : mDisplayId(displayId) {}
int64_t get() const { return mDisplayId; }
FRect getCrop() const {
return {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)};
}
Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
void setDimensions(int32_t displayWidth, int32_t displayHeight) {
mDisplayWidth = displayWidth;
mDisplayHeight = displayHeight;
}
int32_t getDisplayWidth() const { return mDisplayWidth; }
int32_t getDisplayHeight() const { return mDisplayHeight; }
struct DisplayConfig {
DisplayConfig(int32_t vsyncPeriod_, int32_t configGroup_)
: vsyncPeriod(vsyncPeriod_), configGroup(configGroup_) {}
int32_t vsyncPeriod;
int32_t configGroup;
};
void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
displayConfigs.insert({config, displayConfig});
}
DisplayConfig getDisplayConfig(int32_t config) { return displayConfigs.find(config)->second; }
private:
const int64_t mDisplayId;
int32_t mDisplayWidth;
int32_t mDisplayHeight;
std::unordered_map<int32_t, DisplayConfig> displayConfigs;
};
} // namespace aidl::android::hardware::graphics::composer3::vts

View file

@ -194,7 +194,7 @@ class ComposerClientWriter {
void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
ZOrder zorder;
zorder.z = z;
zorder.z = static_cast<int32_t>(z);
getLayerCommand(display, layer).z.emplace(std::move(zorder));
}
@ -233,9 +233,9 @@ class ComposerClientWriter {
std::optional<LayerCommand> mLayerCommand;
std::vector<DisplayCommand> mCommands;
Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) {
Buffer getBuffer(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
Buffer bufferCommand;
bufferCommand.slot = slot;
bufferCommand.slot = static_cast<int32_t>(slot);
if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
return bufferCommand;