graphics: add composer 2.2 default impl

This adds

  android.hardware.graphics.composer@2.2-hal
  android.hardware.graphics.composer@2.2-passthrough
  android.hardware.graphics.composer@2.2-service

The -hal module makes it easier to write composer 2.2 HAL and is
reusable by vendors.  The -passthrough module provides a HwcHal
class that implements ComposerHal 2.2 on top of hwcomposer2, and is
also resuable by vendors.  Finally, the -service module provides a
(stub) default implementation.

Test: boots and VTS
Change-Id: I4f940a9dea656abc7d9d485bf48d852c13d2ed56
This commit is contained in:
Chia-I Wu
2018-02-01 16:12:35 -08:00
parent be99ad6e75
commit de0bd95d57
13 changed files with 943 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
cc_binary {
name: "android.hardware.graphics.composer@2.2-service",
defaults: ["hidl_defaults"],
vendor: true,
relative_install_path: "hw",
srcs: ["service.cpp"],
init_rc: ["android.hardware.graphics.composer@2.2-service.rc"],
header_libs: [
"android.hardware.graphics.composer@2.2-passthrough",
],
shared_libs: [
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.composer@2.2",
"android.hardware.graphics.mapper@2.0",
"libbase",
"libbinder",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"libhidltransport",
"libhwc2on1adapter",
"libhwc2onfbadapter",
"liblog",
"libsync",
"libutils",
],
cflags: [
"-DLOG_TAG=\"ComposerHal\""
],
}

View File

@@ -0,0 +1,5 @@
# Graphics team
courtneygo@google.com
jessehall@google.com
olv@google.com
stoza@google.com

View File

@@ -0,0 +1,6 @@
service vendor.hwcomposer-2-2 /vendor/bin/hw/android.hardware.graphics.composer@2.2-service
class hal animation
user system
group graphics drmrpc
capabilities SYS_NICE
onrestart restart surfaceflinger

View File

@@ -0,0 +1,55 @@
/*
* 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.
*/
#include <sched.h>
#include <android/hardware/graphics/composer/2.2/IComposer.h>
#include <binder/ProcessState.h>
#include <composer-passthrough/2.2/HwcLoader.h>
#include <hidl/HidlTransportSupport.h>
using android::hardware::graphics::composer::V2_2::IComposer;
using android::hardware::graphics::composer::V2_2::passthrough::HwcLoader;
int main() {
// the conventional HAL might start binder services
android::ProcessState::initWithDriver("/dev/vndbinder");
android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
android::ProcessState::self()->startThreadPool();
// same as SF main thread
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
ALOGE("Couldn't set SCHED_FIFO: %d", errno);
}
android::hardware::configureRpcThreadpool(4, true /* will join */);
android::sp<IComposer> composer = HwcLoader::load();
if (composer == nullptr) {
return 1;
}
if (composer->registerAsService() != android::NO_ERROR) {
ALOGE("failed to register service");
return 1;
}
android::hardware::joinRpcThreadpool();
ALOGE("service is terminating");
return 1;
}

View File

@@ -0,0 +1,35 @@
//
// 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_headers {
name: "android.hardware.graphics.composer@2.2-hal",
defaults: ["hidl_defaults"],
vendor_available: true,
shared_libs: [
"android.hardware.graphics.composer@2.2",
],
export_shared_lib_headers: [
"android.hardware.graphics.composer@2.2",
],
header_libs: [
"android.hardware.graphics.composer@2.2-command-buffer",
"android.hardware.graphics.composer@2.1-hal",
],
export_header_lib_headers: [
"android.hardware.graphics.composer@2.2-command-buffer",
"android.hardware.graphics.composer@2.1-hal",
],
export_include_dirs: ["include"],
}

View File

@@ -0,0 +1,74 @@
/*
* 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
#warning "Composer.h included without LOG_TAG"
#endif
#include <android/hardware/graphics/composer/2.2/IComposer.h>
#include <composer-hal/2.1/Composer.h>
#include <composer-hal/2.2/ComposerClient.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace hal {
namespace detail {
// ComposerImpl implements V2_*::IComposer on top of V2_*::ComposerHal
template <typename Interface, typename Hal>
class ComposerImpl : public V2_1::hal::detail::ComposerImpl<Interface, Hal> {
public:
static std::unique_ptr<ComposerImpl> create(std::unique_ptr<Hal> hal) {
return std::make_unique<ComposerImpl>(std::move(hal));
}
ComposerImpl(std::unique_ptr<Hal> hal) : BaseType2_1(std::move(hal)) {}
protected:
V2_1::IComposerClient* createClient() override {
auto client = ComposerClient::create(mHal.get());
if (!client) {
return nullptr;
}
auto clientDestroyed = [this]() { onClientDestroyed(); };
client->setOnClientDestroyed(clientDestroyed);
return client.release();
}
private:
using BaseType2_1 = V2_1::hal::detail::ComposerImpl<Interface, Hal>;
using BaseType2_1::mHal;
using BaseType2_1::onClientDestroyed;
};
} // namespace detail
using Composer = detail::ComposerImpl<IComposer, ComposerHal>;
} // namespace hal
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,162 @@
/*
* 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
#warning "ComposerClient.h included without LOG_TAG"
#endif
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <composer-hal/2.1/ComposerClient.h>
#include <composer-hal/2.2/ComposerCommandEngine.h>
#include <composer-hal/2.2/ComposerHal.h>
#include <composer-hal/2.2/ComposerResources.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace hal {
namespace detail {
// ComposerClientImpl implements V2_*::IComposerClient on top of V2_*::ComposerHal
template <typename Interface, typename Hal>
class ComposerClientImpl : public V2_1::hal::detail::ComposerClientImpl<Interface, Hal> {
public:
static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
auto client = std::make_unique<ComposerClientImpl>(hal);
return client->init() ? std::move(client) : nullptr;
}
ComposerClientImpl(Hal* hal) : BaseType2_1(hal) {}
// IComposerClient 2.2 interface
Return<void> getPerFrameMetadataKeys(
Display display, IComposerClient::getPerFrameMetadataKeys_cb hidl_cb) override {
std::vector<IComposerClient::PerFrameMetadataKey> keys;
Error error = mHal->getPerFrameMetadataKeys(display, &keys);
hidl_cb(error, keys);
return Void();
}
Return<void> getReadbackBufferAttributes(
Display display, IComposerClient::getReadbackBufferAttributes_cb hidl_cb) override {
PixelFormat format = static_cast<PixelFormat>(0);
Dataspace dataspace = Dataspace::UNKNOWN;
Error error = mHal->getReadbackBufferAttributes(display, &format, &dataspace);
hidl_cb(error, format, dataspace);
return Void();
}
Return<void> getReadbackBufferFence(
Display display, IComposerClient::getReadbackBufferFence_cb hidl_cb) override {
base::unique_fd fenceFd;
Error error = mHal->getReadbackBufferFence(display, &fenceFd);
if (error != Error::NONE) {
hidl_cb(error, nullptr);
return Void();
}
NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
return Void();
}
Return<Error> setReadbackBuffer(Display display, const hidl_handle& buffer,
const hidl_handle& releaseFence) override {
base::unique_fd fenceFd;
Error error = getFenceFd(releaseFence, &fenceFd);
if (error != Error::NONE) {
return error;
}
auto resources = static_cast<ComposerResources*>(mResources.get());
const native_handle_t* readbackBuffer;
ComposerResources::ReplacedBufferHandle replacedReadbackBuffer;
error = resources->getDisplayReadbackBuffer(display, buffer.getNativeHandle(),
&readbackBuffer, &replacedReadbackBuffer);
if (error != Error::NONE) {
return error;
}
return mHal->setReadbackBuffer(display, readbackBuffer, std::move(fenceFd));
}
Return<Error> setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
return mHal->setPowerMode_2_2(display, mode);
}
protected:
std::unique_ptr<V2_1::hal::ComposerResources> createResources() override {
return ComposerResources::create();
}
std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
return std::make_unique<ComposerCommandEngine>(
mHal, static_cast<ComposerResources*>(mResources.get()));
}
// convert fenceFd to or from hidl_handle
static Error getFenceFd(const hidl_handle& fenceHandle, base::unique_fd* outFenceFd) {
auto handle = fenceHandle.getNativeHandle();
if (handle && handle->numFds > 1) {
ALOGE("invalid fence handle with %d fds", handle->numFds);
return Error::BAD_PARAMETER;
}
int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
if (fenceFd >= 0) {
fenceFd = dup(fenceFd);
if (fenceFd < 0) {
return Error::NO_RESOURCES;
}
}
outFenceFd->reset(fenceFd);
return Error::NONE;
}
static hidl_handle getFenceHandle(const base::unique_fd& fenceFd, char* handleStorage) {
native_handle_t* handle = nullptr;
if (fenceFd >= 0) {
handle = native_handle_init(handleStorage, 1, 0);
handle->data[0] = fenceFd;
}
return hidl_handle(handle);
}
private:
using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
using BaseType2_1::mHal;
using BaseType2_1::mResources;
};
} // namespace detail
using ComposerClient = detail::ComposerClientImpl<IComposerClient, ComposerHal>;
} // namespace hal
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,103 @@
/*
* 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
#warning "ComposerCommandEngine.h included without LOG_TAG"
#endif
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
#include <composer-hal/2.1/ComposerCommandEngine.h>
#include <composer-hal/2.2/ComposerHal.h>
#include <composer-hal/2.2/ComposerResources.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace hal {
class ComposerCommandEngine : public V2_1::hal::ComposerCommandEngine {
public:
ComposerCommandEngine(ComposerHal* hal, ComposerResources* resources)
: BaseType2_1(hal, resources), mHal(hal) {}
protected:
bool executeCommand(V2_1::IComposerClient::Command command, uint16_t length) override {
switch (static_cast<IComposerClient::Command>(command)) {
case IComposerClient::Command::SET_PER_FRAME_METADATA:
return executeSetPerFrameMetadata(length);
case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
return executeSetLayerFloatColor(length);
default:
return BaseType2_1::executeCommand(command, length);
}
}
bool executeSetPerFrameMetadata(uint16_t length) {
// (key, value) pairs
if (length % 2 != 0) {
return false;
}
std::vector<IComposerClient::PerFrameMetadata> metadata;
metadata.reserve(length / 2);
while (length > 0) {
metadata.emplace_back(IComposerClient::PerFrameMetadata{
static_cast<IComposerClient::PerFrameMetadataKey>(readSigned()), readFloat()});
length -= 2;
}
auto err = mHal->setPerFrameMetadata(mCurrentDisplay, metadata);
if (err != Error::NONE) {
mWriter.setError(getCommandLoc(), err);
}
return true;
}
bool executeSetLayerFloatColor(uint16_t length) {
if (length != CommandWriterBase::kSetLayerFloatColorLength) {
return false;
}
auto err = mHal->setLayerFloatColor(mCurrentDisplay, mCurrentLayer, readFloatColor());
if (err != Error::NONE) {
mWriter.setError(getCommandLoc(), err);
}
return true;
}
IComposerClient::FloatColor readFloatColor() {
return IComposerClient::FloatColor{readFloat(), readFloat(), readFloat(), readFloat()};
}
private:
using BaseType2_1 = V2_1::hal::ComposerCommandEngine;
using BaseType2_1::mWriter;
ComposerHal* mHal;
};
} // namespace hal
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,66 @@
/*
* 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
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer/2.2/IComposer.h>
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <composer-hal/2.1/ComposerHal.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace hal {
using common::V1_0::Dataspace;
using common::V1_0::PixelFormat;
using V2_1::Display;
using V2_1::Error;
using V2_1::Layer;
class ComposerHal : public V2_1::hal::ComposerHal {
public:
// superceded by setPowerMode_2_2
Error setPowerMode(Display display, V2_1::IComposerClient::PowerMode mode) override {
return setPowerMode_2_2(display, static_cast<IComposerClient::PowerMode>(mode));
}
virtual Error getPerFrameMetadataKeys(
Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
virtual Error setPerFrameMetadata(
Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
virtual Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
Dataspace* outDataspace) = 0;
virtual Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
base::unique_fd fenceFd) = 0;
virtual Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) = 0;
virtual Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) = 0;
virtual Error setLayerFloatColor(Display display, Layer layer,
IComposerClient::FloatColor color) = 0;
};
} // namespace hal
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,105 @@
/*
* 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
#warning "ComposerResources.h included without LOG_TAG"
#endif
#include <composer-hal/2.1/ComposerResources.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace hal {
using V2_1::hal::ComposerHandleCache;
using V2_1::hal::ComposerHandleImporter;
class ComposerDisplayResource : public V2_1::hal::ComposerDisplayResource {
public:
ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
uint32_t outputBufferCacheSize)
: V2_1::hal::ComposerDisplayResource(type, importer, outputBufferCacheSize),
mReadbackBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, 1) {}
Error getReadbackBuffer(const native_handle_t* inHandle, const native_handle_t** outHandle,
const native_handle** outReplacedHandle) {
const uint32_t slot = 0;
const bool fromCache = false;
return mReadbackBufferCache.getHandle(slot, fromCache, inHandle, outHandle,
outReplacedHandle);
}
protected:
ComposerHandleCache mReadbackBufferCache;
};
class ComposerResources : public V2_1::hal::ComposerResources {
public:
static std::unique_ptr<ComposerResources> create() {
auto resources = std::make_unique<ComposerResources>();
return resources->init() ? std::move(resources) : nullptr;
}
Error getDisplayReadbackBuffer(Display display, const native_handle_t* rawHandle,
const native_handle_t** outHandle,
ReplacedBufferHandle* outReplacedHandle) {
// import buffer
const native_handle_t* importedHandle;
Error error = mImporter.importBuffer(rawHandle, &importedHandle);
if (error != Error::NONE) {
return error;
}
std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
auto iter = mDisplayResources.find(display);
if (iter == mDisplayResources.end()) {
mImporter.freeBuffer(importedHandle);
return Error::BAD_DISPLAY;
}
ComposerDisplayResource& displayResource =
*static_cast<ComposerDisplayResource*>(iter->second.get());
// update cache
const native_handle_t* replacedHandle;
error = displayResource.getReadbackBuffer(importedHandle, outHandle, &replacedHandle);
if (error != Error::NONE) {
mImporter.freeBuffer(importedHandle);
return error;
}
outReplacedHandle->reset(&mImporter, replacedHandle);
return Error::NONE;
}
protected:
std::unique_ptr<V2_1::hal::ComposerDisplayResource> createDisplayResource(
ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) override {
return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
}
};
} // namespace hal
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,14 @@
cc_library_headers {
name: "android.hardware.graphics.composer@2.2-passthrough",
defaults: ["hidl_defaults"],
vendor: true,
header_libs: [
"android.hardware.graphics.composer@2.1-passthrough",
"android.hardware.graphics.composer@2.2-hal",
],
export_header_lib_headers: [
"android.hardware.graphics.composer@2.1-passthrough",
"android.hardware.graphics.composer@2.2-hal",
],
export_include_dirs: ["include"],
}

View File

@@ -0,0 +1,208 @@
/*
* 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
#warning "HwcHal.h included without LOG_TAG"
#endif
#include <type_traits>
#include <composer-hal/2.2/ComposerHal.h>
#include <composer-passthrough/2.1/HwcHal.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace passthrough {
namespace detail {
using common::V1_0::Dataspace;
using common::V1_0::PixelFormat;
using V2_1::Display;
using V2_1::Error;
using V2_1::Layer;
// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
template <typename Hal>
class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
public:
// XXX when can we return Error::UNSUPPORTED?
Error getPerFrameMetadataKeys(
Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override {
if (!mDispatch.getPerFrameMetadataKeys) {
return Error::UNSUPPORTED;
}
uint32_t count = 0;
int32_t error = mDispatch.getPerFrameMetadataKeys(mDevice, display, &count, nullptr);
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
std::vector<IComposerClient::PerFrameMetadataKey> keys(count);
error = mDispatch.getPerFrameMetadataKeys(
mDevice, display, &count,
reinterpret_cast<std::underlying_type<IComposerClient::PerFrameMetadataKey>::type*>(
keys.data()));
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
keys.resize(count);
*outKeys = std::move(keys);
return Error::NONE;
}
Error setPerFrameMetadata(
Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
if (!mDispatch.setPerFrameMetadata) {
return Error::UNSUPPORTED;
}
std::vector<int32_t> keys;
std::vector<float> values;
keys.reserve(metadata.size());
values.reserve(metadata.size());
for (const auto& m : metadata) {
keys.push_back(static_cast<int32_t>(m.key));
values.push_back(m.value);
}
int32_t error = mDispatch.setPerFrameMetadata(mDevice, display, metadata.size(),
keys.data(), values.data());
return static_cast<Error>(error);
}
Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
Dataspace* outDataspace) override {
if (!mDispatch.getReadbackBufferAttributes) {
return Error::UNSUPPORTED;
}
int32_t format = 0;
int32_t dataspace = 0;
int32_t error =
mDispatch.getReadbackBufferAttributes(mDevice, display, &format, &dataspace);
if (error == HWC2_ERROR_NONE) {
*outFormat = static_cast<PixelFormat>(format);
*outDataspace = static_cast<Dataspace>(dataspace);
}
return static_cast<Error>(error);
}
Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
base::unique_fd fenceFd) override {
if (!mDispatch.setReadbackBuffer) {
return Error::UNSUPPORTED;
}
int32_t error =
mDispatch.setReadbackBuffer(mDevice, display, bufferHandle, fenceFd.release());
return static_cast<Error>(error);
}
Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) override {
if (!mDispatch.getReadbackBufferFence) {
return Error::UNSUPPORTED;
}
int32_t fenceFd = -1;
int32_t error = mDispatch.getReadbackBufferFence(mDevice, display, &fenceFd);
outFenceFd->reset(fenceFd);
return static_cast<Error>(error);
}
Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
return Error::UNSUPPORTED;
}
return setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
}
Error setLayerFloatColor(Display display, Layer layer,
IComposerClient::FloatColor color) override {
if (!mDispatch.setLayerFloatColor) {
return Error::UNSUPPORTED;
}
int32_t error = mDispatch.setLayerFloatColor(
mDevice, display, layer, hwc_float_color{color.r, color.g, color.b, color.a});
return static_cast<Error>(error);
}
protected:
template <typename T>
bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
auto pfn = mDevice->getFunction(mDevice, desc);
if (pfn) {
*outPfn = reinterpret_cast<T>(pfn);
return true;
} else {
return false;
}
}
bool initDispatch() override {
if (!BaseType2_1::initDispatch()) {
return false;
}
initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, &mDispatch.setLayerFloatColor);
initOptionalDispatch(HWC2_FUNCTION_SET_PER_FRAME_METADATA, &mDispatch.setPerFrameMetadata);
initOptionalDispatch(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS,
&mDispatch.getPerFrameMetadataKeys);
initOptionalDispatch(HWC2_FUNCTION_SET_READBACK_BUFFER, &mDispatch.setReadbackBuffer);
initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES,
&mDispatch.getReadbackBufferAttributes);
initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE,
&mDispatch.getReadbackBufferFence);
return true;
}
struct {
HWC2_PFN_SET_LAYER_FLOAT_COLOR setLayerFloatColor;
HWC2_PFN_SET_PER_FRAME_METADATA setPerFrameMetadata;
HWC2_PFN_GET_PER_FRAME_METADATA_KEYS getPerFrameMetadataKeys;
HWC2_PFN_SET_READBACK_BUFFER setReadbackBuffer;
HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES getReadbackBufferAttributes;
HWC2_PFN_GET_READBACK_BUFFER_FENCE getReadbackBufferFence;
} mDispatch = {};
private:
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1::mDevice;
using BaseType2_1::setPowerMode;
};
} // namespace detail
using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
} // namespace passthrough
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,79 @@
/*
* 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
#warning "HwcLoader.h included without LOG_TAG"
#endif
#include <composer-hal/2.2/Composer.h>
#include <composer-hal/2.2/ComposerHal.h>
#include <composer-passthrough/2.1/HwcLoader.h>
#include <composer-passthrough/2.2/HwcHal.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_2 {
namespace passthrough {
class HwcLoader : public V2_1::passthrough::HwcLoader {
public:
static IComposer* load() {
const hw_module_t* module = loadModule();
if (!module) {
return nullptr;
}
auto hal = createHalWithAdapter(module);
if (!hal) {
return nullptr;
}
return createComposer(std::move(hal)).release();
}
// create a ComposerHal instance
static std::unique_ptr<hal::ComposerHal> createHal(const hw_module_t* module) {
auto hal = std::make_unique<HwcHal>();
return hal->initWithModule(module) ? std::move(hal) : nullptr;
}
// create a ComposerHal instance, insert an adapter if necessary
static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) {
bool adapted;
hwc2_device_t* device = openDeviceWithAdapter(module, &adapted);
if (!device) {
return nullptr;
}
auto hal = std::make_unique<HwcHal>();
return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr;
}
// create an IComposer instance
static std::unique_ptr<IComposer> createComposer(std::unique_ptr<hal::ComposerHal> hal) {
return hal::Composer::create(std::move(hal));
}
};
} // namespace passthrough
} // namespace V2_2
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android