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
This commit is contained in:
Courtney Goeltzenleuchter
2018-01-11 08:50:03 -08:00
parent b6371e782d
commit be92bb9fae
12 changed files with 941 additions and 1 deletions

View File

@@ -58,10 +58,12 @@ class Composer {
std::string dumpDebugInfo();
std::unique_ptr<ComposerClient> createClient();
protected:
sp<IComposer> mComposer;
private:
void init();
sp<IComposer> mComposer;
std::unordered_set<IComposer::Capability> mCapabilities;
};

View File

@@ -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,
}

View File

@@ -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 */
};

View File

@@ -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<PerFrameMetadata> 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<PerFrameMetadataKey> 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);
};

View File

@@ -0,0 +1,8 @@
# Graphics team
courtneygo@google.com
olv@google.com
stoza@google.com
# VTS team
yim@google.com
zhuoyao@google.com

View File

@@ -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"],
}

View File

@@ -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 <algorithm>
#include <limits>
#include <memory>
#include <vector>
#include <inttypes.h>
#include <string.h>
#include <android/hardware/graphics/composer/2.2/IComposer.h>
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <fmq/MessageQueue.h>
#include <log/log.h>
#include <sync/sync.h>
#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
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<uint32_t, kSynchronizedReadWrite>;
// 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<IComposerClient::PerFrameMetadata>& metadataVec) {
beginCommand2_2(IComposerClient::Command::SET_PER_FRAME_METADATA, metadataVec.size() * 2);
for (const auto& metadata : metadataVec) {
writeSigned(static_cast<int32_t>(metadata.key));
writeFloat(metadata.value);
}
endCommand();
}
protected:
void beginCommand2_2(IComposerClient::Command command, uint16_t length) {
V2_1::CommandWriterBase::beginCommand(
static_cast<V2_1::IComposerClient::Command>(static_cast<int32_t>(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

View File

@@ -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",
],
}

View File

@@ -0,0 +1,8 @@
# Graphics team
courtneygo@google.com
olv@google.com
stoza@google.com
# VTS team
yim@google.com
zhuoyao@google.com

View File

@@ -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 <VtsHalHidlTargetTestBase.h>
#include <hidl/HidlTransportUtils.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
#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<ComposerClient_v2_2> Composer_v2_2::createClient_v2_2() {
std::unique_ptr<ComposerClient_v2_2> 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<ComposerClient_v2_2>(IComposerClient::castFrom(tmpClient, true));
});
return client;
}
std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient_v2_2::getPerFrameMetadataKeys(
Display display) {
std::vector<IComposerClient::PerFrameMetadataKey> 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<hidl_handle> commandHandles;
ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
if (queueChanged) {
auto ret = mClient_v2_2->setInputCommandQueue(*writer->getMQDescriptor());
ASSERT_EQ(Error::NONE, static_cast<Error>(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

View File

@@ -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 <android-base/logging.h>
#include <android/hardware/graphics/mapper/2.1/IMapper.h>
#include <sync/sync.h>
#include "2.2/VtsHalGraphicsComposerTestUtils.h"
#include "GraphicsComposerCallback.h"
#include "TestCommandReader.h"
#include "VtsHalGraphicsComposerTestUtils.h"
#include "VtsHalGraphicsMapperTestUtils.h"
#include <VtsHalHidlTargetTestBase.h>
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<IComposer>(); }
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<Composer_v2_2>(
GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
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<Composer_v2_2> mComposer;
std::unique_ptr<ComposerClient_v2_2> mComposerClient;
sp<V2_1::tests::GraphicsComposerCallback> mComposerCallback;
// the first display and is assumed never to be removed
Display mPrimaryDisplay;
private:
Display waitForFirstDisplay() {
while (true) {
std::vector<Display> 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<Gralloc>());
mWriter = std::make_unique<V2_2::CommandWriterBase>(1024);
mReader = std::make_unique<V2_1::tests::TestCommandReader>();
}
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<uint64_t>(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<V2_2::CommandWriterBase> mWriter;
std::unique_ptr<V2_1::tests::TestCommandReader> mReader;
private:
std::unique_ptr<Gralloc> 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<IComposerClient::PerFrameMetadata> 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<IComposerClient::PowerMode> 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;
}

View File

@@ -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 <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <VtsHalGraphicsComposerTestUtils.h>
#include <VtsHalHidlTargetTestBase.h>
#include <android/hardware/graphics/composer/2.2/IComposer.h>
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
#include <utils/StrongPointer.h>
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<ComposerClient_v2_2> 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<IComposerClient>& 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<IComposerClient::PerFrameMetadataKey> 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<V2_2::IComposerClient> mClient_v2_2;
};
} // namespace tests
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android