diff --git a/graphics/composer/2.2/default/Android.bp b/graphics/composer/2.2/default/Android.bp new file mode 100644 index 0000000000..906479e6ac --- /dev/null +++ b/graphics/composer/2.2/default/Android.bp @@ -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\"" + ], +} diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS new file mode 100644 index 0000000000..4714be2d08 --- /dev/null +++ b/graphics/composer/2.2/default/OWNERS @@ -0,0 +1,5 @@ +# Graphics team +courtneygo@google.com +jessehall@google.com +olv@google.com +stoza@google.com diff --git a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc new file mode 100644 index 0000000000..a41d902cc9 --- /dev/null +++ b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc @@ -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 diff --git a/graphics/composer/2.2/default/service.cpp b/graphics/composer/2.2/default/service.cpp new file mode 100644 index 0000000000..8c5ef189c0 --- /dev/null +++ b/graphics/composer/2.2/default/service.cpp @@ -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 + +#include +#include +#include +#include + +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, ¶m) != 0) { + ALOGE("Couldn't set SCHED_FIFO: %d", errno); + } + + android::hardware::configureRpcThreadpool(4, true /* will join */); + + android::sp 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; +} diff --git a/graphics/composer/2.2/utils/hal/Android.bp b/graphics/composer/2.2/utils/hal/Android.bp new file mode 100644 index 0000000000..10dcae4dd7 --- /dev/null +++ b/graphics/composer/2.2/utils/hal/Android.bp @@ -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"], +} diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/Composer.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/Composer.h new file mode 100644 index 0000000000..58bbaa57c8 --- /dev/null +++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/Composer.h @@ -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 +#include +#include + +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 +class ComposerImpl : public V2_1::hal::detail::ComposerImpl { + public: + static std::unique_ptr create(std::unique_ptr hal) { + return std::make_unique(std::move(hal)); + } + + ComposerImpl(std::unique_ptr 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; + using BaseType2_1::mHal; + using BaseType2_1::onClientDestroyed; +}; + +} // namespace detail + +using Composer = detail::ComposerImpl; + +} // namespace hal +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h new file mode 100644 index 0000000000..d550f834b9 --- /dev/null +++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h @@ -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 +#include +#include +#include +#include + +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 +class ComposerClientImpl : public V2_1::hal::detail::ComposerClientImpl { + public: + static std::unique_ptr create(Hal* hal) { + auto client = std::make_unique(hal); + return client->init() ? std::move(client) : nullptr; + } + + ComposerClientImpl(Hal* hal) : BaseType2_1(hal) {} + + // IComposerClient 2.2 interface + + Return getPerFrameMetadataKeys( + Display display, IComposerClient::getPerFrameMetadataKeys_cb hidl_cb) override { + std::vector keys; + Error error = mHal->getPerFrameMetadataKeys(display, &keys); + hidl_cb(error, keys); + return Void(); + } + + Return getReadbackBufferAttributes( + Display display, IComposerClient::getReadbackBufferAttributes_cb hidl_cb) override { + PixelFormat format = static_cast(0); + Dataspace dataspace = Dataspace::UNKNOWN; + Error error = mHal->getReadbackBufferAttributes(display, &format, &dataspace); + hidl_cb(error, format, dataspace); + return Void(); + } + + Return 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 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(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 setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override { + return mHal->setPowerMode_2_2(display, mode); + } + + protected: + std::unique_ptr createResources() override { + return ComposerResources::create(); + } + + std::unique_ptr createCommandEngine() override { + return std::make_unique( + mHal, static_cast(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; + using BaseType2_1::mHal; + using BaseType2_1::mResources; +}; + +} // namespace detail + +using ComposerClient = detail::ComposerClientImpl; + +} // namespace hal +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h new file mode 100644 index 0000000000..adcac463d9 --- /dev/null +++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h @@ -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 +#include +#include +#include + +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(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 metadata; + metadata.reserve(length / 2); + while (length > 0) { + metadata.emplace_back(IComposerClient::PerFrameMetadata{ + static_cast(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 diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h new file mode 100644 index 0000000000..30b364398a --- /dev/null +++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h @@ -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 +#include +#include +#include + +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(mode)); + } + + virtual Error getPerFrameMetadataKeys( + Display display, std::vector* outKeys) = 0; + virtual Error setPerFrameMetadata( + Display display, const std::vector& 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 diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerResources.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerResources.h new file mode 100644 index 0000000000..85b665179c --- /dev/null +++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerResources.h @@ -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 + +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 create() { + auto resources = std::make_unique(); + 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 lock(mDisplayResourcesMutex); + + auto iter = mDisplayResources.find(display); + if (iter == mDisplayResources.end()) { + mImporter.freeBuffer(importedHandle); + return Error::BAD_DISPLAY; + } + ComposerDisplayResource& displayResource = + *static_cast(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 createDisplayResource( + ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) override { + return std::make_unique(type, mImporter, outputBufferCacheSize); + } +}; + +} // namespace hal +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/composer/2.2/utils/passthrough/Android.bp b/graphics/composer/2.2/utils/passthrough/Android.bp new file mode 100644 index 0000000000..318ce914ed --- /dev/null +++ b/graphics/composer/2.2/utils/passthrough/Android.bp @@ -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"], +} diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h new file mode 100644 index 0000000000..b251351f15 --- /dev/null +++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h @@ -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 + +#include +#include + +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 +class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl { + public: + // XXX when can we return Error::UNSUPPORTED? + + Error getPerFrameMetadataKeys( + Display display, std::vector* 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); + } + + std::vector keys(count); + error = mDispatch.getPerFrameMetadataKeys( + mDevice, display, &count, + reinterpret_cast::type*>( + keys.data())); + if (error != HWC2_ERROR_NONE) { + return static_cast(error); + } + + keys.resize(count); + *outKeys = std::move(keys); + return Error::NONE; + } + + Error setPerFrameMetadata( + Display display, const std::vector& metadata) override { + if (!mDispatch.setPerFrameMetadata) { + return Error::UNSUPPORTED; + } + + std::vector keys; + std::vector values; + keys.reserve(metadata.size()); + values.reserve(metadata.size()); + for (const auto& m : metadata) { + keys.push_back(static_cast(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 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(format); + *outDataspace = static_cast(dataspace); + } + return static_cast(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 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 setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override { + if (mode == IComposerClient::PowerMode::ON_SUSPEND) { + return Error::UNSUPPORTED; + } + return setPowerMode(display, static_cast(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); + } + + protected: + template + bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) { + auto pfn = mDevice->getFunction(mDevice, desc); + if (pfn) { + *outPfn = reinterpret_cast(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; + using BaseType2_1::mDevice; + using BaseType2_1::setPowerMode; +}; + +} // namespace detail + +using HwcHal = detail::HwcHalImpl; + +} // namespace passthrough +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h new file mode 100644 index 0000000000..cb4a238f9f --- /dev/null +++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h @@ -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 +#include +#include +#include + +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 createHal(const hw_module_t* module) { + auto hal = std::make_unique(); + return hal->initWithModule(module) ? std::move(hal) : nullptr; + } + + // create a ComposerHal instance, insert an adapter if necessary + static std::unique_ptr createHalWithAdapter(const hw_module_t* module) { + bool adapted; + hwc2_device_t* device = openDeviceWithAdapter(module, &adapted); + if (!device) { + return nullptr; + } + auto hal = std::make_unique(); + return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr; + } + + // create an IComposer instance + static std::unique_ptr createComposer(std::unique_ptr hal) { + return hal::Composer::create(std::move(hal)); + } +}; + +} // namespace passthrough +} // namespace V2_2 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android