From be99ad6e757c3bb65d0b3febf68ec006b3897dbb Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 30 Jan 2018 21:18:59 -0800 Subject: [PATCH] graphics: convert composer default impl to a library Convert composer default impl to a header-only library, android.hardware.graphics.composer@2.1-passthrough. Test: builds and VTS Change-Id: I9251aadc28816fc4c1d9326e09e297f30e9c25fe --- graphics/composer/2.1/default/Android.bp | 18 +- graphics/composer/2.1/default/Hwc.cpp | 731 ------------------ graphics/composer/2.1/default/Hwc.h | 236 ------ graphics/composer/2.1/default/passthrough.cpp | 25 + .../composer/2.1/utils/passthrough/Android.bp | 22 + .../include/composer-passthrough/2.1/HwcHal.h | 670 ++++++++++++++++ .../composer-passthrough/2.1/HwcLoader.h | 152 ++++ 7 files changed, 877 insertions(+), 977 deletions(-) delete mode 100644 graphics/composer/2.1/default/Hwc.cpp delete mode 100644 graphics/composer/2.1/default/Hwc.h create mode 100644 graphics/composer/2.1/default/passthrough.cpp create mode 100644 graphics/composer/2.1/utils/passthrough/Android.bp create mode 100644 graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h create mode 100644 graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp index 6f25cbf0db..2de1e3caa4 100644 --- a/graphics/composer/2.1/default/Android.bp +++ b/graphics/composer/2.1/default/Android.bp @@ -1,9 +1,12 @@ cc_library_shared { name: "android.hardware.graphics.composer@2.1-impl", defaults: ["hidl_defaults"], - proprietary: true, + vendor: true, relative_install_path: "hw", - srcs: ["Hwc.cpp"], + srcs: ["passthrough.cpp"], + header_libs: [ + "android.hardware.graphics.composer@2.1-passthrough", + ], shared_libs: [ "android.hardware.graphics.composer@2.1", "android.hardware.graphics.mapper@2.0", @@ -19,26 +22,21 @@ cc_library_shared { "libhwc2on1adapter", "libhwc2onfbadapter", ], - header_libs: [ - "android.hardware.graphics.composer@2.1-command-buffer", - "android.hardware.graphics.composer@2.1-hal", + cflags: [ + "-DLOG_TAG=\"ComposerHal\"" ], } cc_binary { name: "android.hardware.graphics.composer@2.1-service", defaults: ["hidl_defaults"], - proprietary: true, + vendor: true, relative_install_path: "hw", srcs: ["service.cpp"], init_rc: ["android.hardware.graphics.composer@2.1-service.rc"], shared_libs: [ "android.hardware.graphics.composer@2.1", - "libbase", "libbinder", - "libcutils", - "libfmq", - "libhardware", "libhidlbase", "libhidltransport", "liblog", diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp deleted file mode 100644 index 412af5980a..0000000000 --- a/graphics/composer/2.1/default/Hwc.cpp +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright 2016 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 "HwcPassthrough" - -#include "Hwc.h" - -#include -#include - -#include -#include - -#include "hardware/fb.h" -#include "hardware/hwcomposer.h" -#include "hwc2on1adapter/HWC2On1Adapter.h" -#include "hwc2onfbadapter/HWC2OnFbAdapter.h" - -using namespace std::chrono_literals; - -namespace android { -namespace hardware { -namespace graphics { -namespace composer { -namespace V2_1 { -namespace implementation { - -HwcHal::HwcHal(const hw_module_t* module) - : mDevice(nullptr), mDispatch(), mMustValidateDisplay(true), mAdapter() { - uint32_t majorVersion; - if (module->id && strcmp(module->id, GRALLOC_HARDWARE_MODULE_ID) == 0) { - majorVersion = initWithFb(module); - } else { - majorVersion = initWithHwc(module); - } - - initCapabilities(); - if (majorVersion >= 2 && hasCapability(HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE)) { - ALOGE("Present fence must be reliable from HWC2 on."); - abort(); - } - - initDispatch(); -} - -HwcHal::~HwcHal() -{ - hwc2_close(mDevice); -} - -uint32_t HwcHal::initWithHwc(const hw_module_t* module) -{ - // Determine what kind of module is available (HWC2 vs HWC1.X). - hw_device_t* device = nullptr; - int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device); - if (error != 0) { - ALOGE("Failed to open HWC device (%s), aborting", strerror(-error)); - abort(); - } - uint32_t majorVersion = (device->version >> 24) & 0xF; - - // If we don't have a HWC2, we need to wrap whatever we have in an adapter. - if (majorVersion != 2) { - uint32_t minorVersion = device->version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK; - minorVersion = (minorVersion >> 16) & 0xF; - ALOGI("Found HWC implementation v%d.%d", majorVersion, minorVersion); - if (minorVersion < 1) { - ALOGE("Cannot adapt to HWC version %d.%d. Minimum supported is 1.1", - majorVersion, minorVersion); - abort(); - } - mAdapter = std::make_unique( - reinterpret_cast(device)); - - // Place the adapter in front of the device module. - mDevice = mAdapter.get(); - } else { - mDevice = reinterpret_cast(device); - } - - return majorVersion; -} - -uint32_t HwcHal::initWithFb(const hw_module_t* module) -{ - framebuffer_device_t* fb_device; - int error = framebuffer_open(module, &fb_device); - if (error != 0) { - ALOGE("Failed to open FB device (%s), aborting", strerror(-error)); - abort(); - } - - mFbAdapter = std::make_unique(fb_device); - mDevice = mFbAdapter.get(); - - return 0; -} - -void HwcHal::initCapabilities() -{ - uint32_t count = 0; - mDevice->getCapabilities(mDevice, &count, nullptr); - - std::vector caps(count); - mDevice->getCapabilities(mDevice, &count, caps.data()); - caps.resize(count); - - mCapabilities.reserve(count); - for (auto cap : caps) { - mCapabilities.insert(static_cast(cap)); - } -} - -template -void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn) -{ - auto pfn = mDevice->getFunction(mDevice, desc); - if (!pfn) { - LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc); - } - - *outPfn = reinterpret_cast(pfn); -} - -void HwcHal::initDispatch() -{ - initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES, - &mDispatch.acceptDisplayChanges); - initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer); - initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY, - &mDispatch.createVirtualDisplay); - initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer); - initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY, - &mDispatch.destroyVirtualDisplay); - initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump); - initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig); - initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES, - &mDispatch.getChangedCompositionTypes); - initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT, - &mDispatch.getClientTargetSupport); - initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes); - initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE, - &mDispatch.getDisplayAttribute); - initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS, - &mDispatch.getDisplayConfigs); - initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName); - initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS, - &mDispatch.getDisplayRequests); - initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType); - initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport); - initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES, - &mDispatch.getHdrCapabilities); - initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT, - &mDispatch.getMaxVirtualDisplayCount); - initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES, - &mDispatch.getReleaseFences); - initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay); - initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK, - &mDispatch.registerCallback); - initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig); - initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget); - initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode); - initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM, - &mDispatch.setColorTransform); - initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION, - &mDispatch.setCursorPosition); - initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE, - &mDispatch.setLayerBlendMode); - initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer); - initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor); - initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE, - &mDispatch.setLayerCompositionType); - initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE, - &mDispatch.setLayerDataspace); - initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME, - &mDispatch.setLayerDisplayFrame); - initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA, - &mDispatch.setLayerPlaneAlpha); - - if (hasCapability(HWC2_CAPABILITY_SIDEBAND_STREAM)) { - initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM, - &mDispatch.setLayerSidebandStream); - } - - initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP, - &mDispatch.setLayerSourceCrop); - initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE, - &mDispatch.setLayerSurfaceDamage); - initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM, - &mDispatch.setLayerTransform); - initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION, - &mDispatch.setLayerVisibleRegion); - initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder); - initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer); - initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode); - initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled); - initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay); -} - -bool HwcHal::hasCapability(hwc2_capability_t capability) { - return (mCapabilities.count(capability) > 0); -} - -std::string HwcHal::dumpDebugInfo() { - uint32_t len = 0; - mDispatch.dump(mDevice, &len, nullptr); - - std::vector buf(len + 1); - mDispatch.dump(mDevice, &len, buf.data()); - buf.resize(len + 1); - buf[len] = '\0'; - - return buf.data(); -} - -void HwcHal::hotplugHook(hwc2_callback_data_t callbackData, - hwc2_display_t display, int32_t connected) -{ - auto hal = static_cast(callbackData); - hal->mEventCallback->onHotplug(display, static_cast(connected)); -} - -void HwcHal::refreshHook(hwc2_callback_data_t callbackData, - hwc2_display_t display) -{ - auto hal = static_cast(callbackData); - hal->mMustValidateDisplay = true; - hal->mEventCallback->onRefresh(display); -} - -void HwcHal::vsyncHook(hwc2_callback_data_t callbackData, - hwc2_display_t display, int64_t timestamp) -{ - auto hal = static_cast(callbackData); - hal->mEventCallback->onVsync(display, timestamp); -} - -void HwcHal::registerEventCallback(EventCallback* callback) { - mMustValidateDisplay = true; - mEventCallback = callback; - - mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, - reinterpret_cast(hotplugHook)); - mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, - reinterpret_cast(refreshHook)); - mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, - reinterpret_cast(vsyncHook)); -} - -void HwcHal::unregisterEventCallback() { - // we assume the callback functions - // - // - can be unregistered - // - can be in-flight - // - will never be called afterward - // - // which is likely incorrect - mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr); - mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr); - mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, nullptr); - - mEventCallback = nullptr; -} - -uint32_t HwcHal::getMaxVirtualDisplayCount() -{ - return mDispatch.getMaxVirtualDisplayCount(mDevice); -} - -Error HwcHal::createVirtualDisplay(uint32_t width, uint32_t height, - PixelFormat* format, Display* outDisplay) -{ - int32_t hwc_format = static_cast(*format); - int32_t err = mDispatch.createVirtualDisplay(mDevice, width, height, - &hwc_format, outDisplay); - *format = static_cast(hwc_format); - - return static_cast(err); -} - -Error HwcHal::destroyVirtualDisplay(Display display) -{ - int32_t err = mDispatch.destroyVirtualDisplay(mDevice, display); - return static_cast(err); -} - -Error HwcHal::createLayer(Display display, Layer* outLayer) -{ - int32_t err = mDispatch.createLayer(mDevice, display, outLayer); - return static_cast(err); -} - -Error HwcHal::destroyLayer(Display display, Layer layer) -{ - int32_t err = mDispatch.destroyLayer(mDevice, display, layer); - return static_cast(err); -} - -Error HwcHal::getActiveConfig(Display display, Config* outConfig) -{ - int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig); - return static_cast(err); -} - -Error HwcHal::getClientTargetSupport(Display display, - uint32_t width, uint32_t height, - PixelFormat format, Dataspace dataspace) -{ - int32_t err = mDispatch.getClientTargetSupport(mDevice, display, - width, height, static_cast(format), - static_cast(dataspace)); - return static_cast(err); -} - -Error HwcHal::getColorModes(Display display, hidl_vec* outModes) -{ - uint32_t count = 0; - int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr); - if (err != HWC2_ERROR_NONE) { - return static_cast(err); - } - - outModes->resize(count); - err = mDispatch.getColorModes(mDevice, display, &count, - reinterpret_cast::type*>( - outModes->data())); - if (err != HWC2_ERROR_NONE) { - *outModes = hidl_vec(); - return static_cast(err); - } - - return Error::NONE; -} - -Error HwcHal::getDisplayAttribute(Display display, Config config, - IComposerClient::Attribute attribute, int32_t* outValue) -{ - int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config, - static_cast(attribute), outValue); - return static_cast(err); -} - -Error HwcHal::getDisplayConfigs(Display display, hidl_vec* outConfigs) -{ - uint32_t count = 0; - int32_t err = mDispatch.getDisplayConfigs(mDevice, display, - &count, nullptr); - if (err != HWC2_ERROR_NONE) { - return static_cast(err); - } - - outConfigs->resize(count); - err = mDispatch.getDisplayConfigs(mDevice, display, - &count, outConfigs->data()); - if (err != HWC2_ERROR_NONE) { - *outConfigs = hidl_vec(); - return static_cast(err); - } - - return Error::NONE; -} - -Error HwcHal::getDisplayName(Display display, hidl_string* outName) -{ - uint32_t count = 0; - int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr); - if (err != HWC2_ERROR_NONE) { - return static_cast(err); - } - - std::vector buf(count + 1); - err = mDispatch.getDisplayName(mDevice, display, &count, buf.data()); - if (err != HWC2_ERROR_NONE) { - return static_cast(err); - } - buf.resize(count + 1); - buf[count] = '\0'; - - *outName = buf.data(); - - return Error::NONE; -} - -Error HwcHal::getDisplayType(Display display, - IComposerClient::DisplayType* outType) -{ - int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID; - int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type); - *outType = static_cast(hwc_type); - - return static_cast(err); -} - -Error HwcHal::getDozeSupport(Display display, bool* outSupport) -{ - int32_t hwc_support = 0; - int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support); - *outSupport = hwc_support; - - return static_cast(err); -} - -Error HwcHal::getHdrCapabilities(Display display, hidl_vec* outTypes, - float* outMaxLuminance, float* outMaxAverageLuminance, - float* outMinLuminance) -{ - uint32_t count = 0; - int32_t err = mDispatch.getHdrCapabilities(mDevice, display, &count, - nullptr, outMaxLuminance, outMaxAverageLuminance, - outMinLuminance); - if (err != HWC2_ERROR_NONE) { - return static_cast(err); - } - - outTypes->resize(count); - err = mDispatch.getHdrCapabilities(mDevice, display, &count, - reinterpret_cast::type*>( - outTypes->data()), outMaxLuminance, - outMaxAverageLuminance, outMinLuminance); - if (err != HWC2_ERROR_NONE) { - *outTypes = hidl_vec(); - return static_cast(err); - } - - return Error::NONE; -} - -Error HwcHal::setActiveConfig(Display display, Config config) -{ - int32_t err = mDispatch.setActiveConfig(mDevice, display, config); - return static_cast(err); -} - -Error HwcHal::setColorMode(Display display, ColorMode mode) -{ - int32_t err = mDispatch.setColorMode(mDevice, display, - static_cast(mode)); - return static_cast(err); -} - -Error HwcHal::setPowerMode(Display display, IComposerClient::PowerMode mode) -{ - int32_t err = mDispatch.setPowerMode(mDevice, display, - static_cast(mode)); - return static_cast(err); -} - -Error HwcHal::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) -{ - int32_t err = mDispatch.setVsyncEnabled(mDevice, display, - static_cast(enabled)); - return static_cast(err); -} - -Error HwcHal::setColorTransform(Display display, const float* matrix, - int32_t hint) -{ - int32_t err = mDispatch.setColorTransform(mDevice, display, matrix, hint); - return static_cast(err); -} - -Error HwcHal::setClientTarget(Display display, buffer_handle_t target, - int32_t acquireFence, int32_t dataspace, - const std::vector& damage) -{ - hwc_region region = { damage.size(), damage.data() }; - int32_t err = mDispatch.setClientTarget(mDevice, display, target, - acquireFence, dataspace, region); - return static_cast(err); -} - -Error HwcHal::setOutputBuffer(Display display, buffer_handle_t buffer, - int32_t releaseFence) -{ - int32_t err = mDispatch.setOutputBuffer(mDevice, display, buffer, - releaseFence); - // unlike in setClientTarget, releaseFence is owned by us - if (err == HWC2_ERROR_NONE && releaseFence >= 0) { - close(releaseFence); - } - - return static_cast(err); -} - -Error HwcHal::validateDisplay(Display display, - std::vector* outChangedLayers, - std::vector* outCompositionTypes, - uint32_t* outDisplayRequestMask, - std::vector* outRequestedLayers, - std::vector* outRequestMasks) -{ - uint32_t types_count = 0; - uint32_t reqs_count = 0; - int32_t err = mDispatch.validateDisplay(mDevice, display, - &types_count, &reqs_count); - mMustValidateDisplay = false; - - if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) { - return static_cast(err); - } - - err = mDispatch.getChangedCompositionTypes(mDevice, display, - &types_count, nullptr, nullptr); - if (err != HWC2_ERROR_NONE) { - return static_cast(err); - } - - outChangedLayers->resize(types_count); - outCompositionTypes->resize(types_count); - err = mDispatch.getChangedCompositionTypes(mDevice, display, - &types_count, outChangedLayers->data(), - reinterpret_cast< - std::underlying_type::type*>( - outCompositionTypes->data())); - if (err != HWC2_ERROR_NONE) { - outChangedLayers->clear(); - outCompositionTypes->clear(); - return static_cast(err); - } - - int32_t display_reqs = 0; - err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs, - &reqs_count, nullptr, nullptr); - if (err != HWC2_ERROR_NONE) { - outChangedLayers->clear(); - outCompositionTypes->clear(); - return static_cast(err); - } - - outRequestedLayers->resize(reqs_count); - outRequestMasks->resize(reqs_count); - err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs, - &reqs_count, outRequestedLayers->data(), - reinterpret_cast(outRequestMasks->data())); - if (err != HWC2_ERROR_NONE) { - outChangedLayers->clear(); - outCompositionTypes->clear(); - - outRequestedLayers->clear(); - outRequestMasks->clear(); - return static_cast(err); - } - - *outDisplayRequestMask = display_reqs; - - return static_cast(err); -} - -Error HwcHal::acceptDisplayChanges(Display display) -{ - int32_t err = mDispatch.acceptDisplayChanges(mDevice, display); - return static_cast(err); -} - -Error HwcHal::presentDisplay(Display display, int32_t* outPresentFence, - std::vector* outLayers, std::vector* outReleaseFences) -{ - if (mMustValidateDisplay) { - return Error::NOT_VALIDATED; - } - - *outPresentFence = -1; - int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence); - if (err != HWC2_ERROR_NONE) { - return static_cast(err); - } - - uint32_t count = 0; - err = mDispatch.getReleaseFences(mDevice, display, &count, - nullptr, nullptr); - if (err != HWC2_ERROR_NONE) { - ALOGW("failed to get release fences"); - return Error::NONE; - } - - outLayers->resize(count); - outReleaseFences->resize(count); - err = mDispatch.getReleaseFences(mDevice, display, &count, - outLayers->data(), outReleaseFences->data()); - if (err != HWC2_ERROR_NONE) { - ALOGW("failed to get release fences"); - outLayers->clear(); - outReleaseFences->clear(); - return Error::NONE; - } - - return static_cast(err); -} - -Error HwcHal::setLayerCursorPosition(Display display, Layer layer, - int32_t x, int32_t y) -{ - int32_t err = mDispatch.setCursorPosition(mDevice, display, layer, x, y); - return static_cast(err); -} - -Error HwcHal::setLayerBuffer(Display display, Layer layer, - buffer_handle_t buffer, int32_t acquireFence) -{ - int32_t err = mDispatch.setLayerBuffer(mDevice, display, layer, - buffer, acquireFence); - return static_cast(err); -} - -Error HwcHal::setLayerSurfaceDamage(Display display, Layer layer, - const std::vector& damage) -{ - hwc_region region = { damage.size(), damage.data() }; - int32_t err = mDispatch.setLayerSurfaceDamage(mDevice, display, layer, - region); - return static_cast(err); -} - -Error HwcHal::setLayerBlendMode(Display display, Layer layer, int32_t mode) -{ - int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode); - return static_cast(err); -} - -Error HwcHal::setLayerColor(Display display, Layer layer, - IComposerClient::Color color) -{ - hwc_color_t hwc_color{color.r, color.g, color.b, color.a}; - int32_t err = mDispatch.setLayerColor(mDevice, display, layer, hwc_color); - return static_cast(err); -} - -Error HwcHal::setLayerCompositionType(Display display, Layer layer, - int32_t type) -{ - int32_t err = mDispatch.setLayerCompositionType(mDevice, display, layer, - type); - return static_cast(err); -} - -Error HwcHal::setLayerDataspace(Display display, Layer layer, - int32_t dataspace) -{ - int32_t err = mDispatch.setLayerDataspace(mDevice, display, layer, - dataspace); - return static_cast(err); -} - -Error HwcHal::setLayerDisplayFrame(Display display, Layer layer, - const hwc_rect_t& frame) -{ - int32_t err = mDispatch.setLayerDisplayFrame(mDevice, display, layer, - frame); - return static_cast(err); -} - -Error HwcHal::setLayerPlaneAlpha(Display display, Layer layer, float alpha) -{ - int32_t err = mDispatch.setLayerPlaneAlpha(mDevice, display, layer, - alpha); - return static_cast(err); -} - -Error HwcHal::setLayerSidebandStream(Display display, Layer layer, - buffer_handle_t stream) -{ - int32_t err = mDispatch.setLayerSidebandStream(mDevice, display, layer, - stream); - return static_cast(err); -} - -Error HwcHal::setLayerSourceCrop(Display display, Layer layer, - const hwc_frect_t& crop) -{ - int32_t err = mDispatch.setLayerSourceCrop(mDevice, display, layer, crop); - return static_cast(err); -} - -Error HwcHal::setLayerTransform(Display display, Layer layer, - int32_t transform) -{ - int32_t err = mDispatch.setLayerTransform(mDevice, display, layer, - transform); - return static_cast(err); -} - -Error HwcHal::setLayerVisibleRegion(Display display, Layer layer, - const std::vector& visible) -{ - hwc_region_t region = { visible.size(), visible.data() }; - int32_t err = mDispatch.setLayerVisibleRegion(mDevice, display, layer, - region); - return static_cast(err); -} - -Error HwcHal::setLayerZOrder(Display display, Layer layer, uint32_t z) -{ - int32_t err = mDispatch.setLayerZOrder(mDevice, display, layer, z); - return static_cast(err); -} - -IComposer* HIDL_FETCH_IComposer(const char*) -{ - const hw_module_t* module = nullptr; - int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module); - if (err) { - ALOGI("falling back to FB HAL"); - err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - } - if (err) { - ALOGE("failed to get hwcomposer or fb module"); - return nullptr; - } - - return Composer::create(std::make_unique(module)).release(); -} - -} // namespace implementation -} // namespace V2_1 -} // namespace composer -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h deleted file mode 100644 index 835b49ed1c..0000000000 --- a/graphics/composer/2.1/default/Hwc.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2016 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. - */ - -#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H -#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H - -#include -#include -#include -#include -#include -#include - -#include -#define HWC2_INCLUDE_STRINGIFICATION -#define HWC2_USE_CPP11 -#include -#undef HWC2_INCLUDE_STRINGIFICATION -#undef HWC2_USE_CPP11 -#include -#include - -namespace android { - class HWC2On1Adapter; - class HWC2OnFbAdapter; -} - -namespace android { -namespace hardware { -namespace graphics { -namespace composer { -namespace V2_1 { -namespace implementation { - -using namespace hal; - -using android::hardware::graphics::common::V1_0::PixelFormat; -using android::hardware::graphics::common::V1_0::Transform; -using android::hardware::graphics::common::V1_0::Dataspace; -using android::hardware::graphics::common::V1_0::ColorMode; -using android::hardware::graphics::common::V1_0::ColorTransform; -using android::hardware::graphics::common::V1_0::Hdr; - -class HwcHal : public ComposerHal { -public: - HwcHal(const hw_module_t* module); - virtual ~HwcHal(); - - bool hasCapability(hwc2_capability_t capability) override; - - std::string dumpDebugInfo() override; - void registerEventCallback(EventCallback* callback) override; - void unregisterEventCallback() override; - - uint32_t getMaxVirtualDisplayCount() override; - Error createVirtualDisplay(uint32_t width, uint32_t height, - PixelFormat* format, Display* outDisplay) override; - Error destroyVirtualDisplay(Display display) override; - - Error createLayer(Display display, Layer* outLayer) override; - Error destroyLayer(Display display, Layer layer) override; - - Error getActiveConfig(Display display, Config* outConfig) override; - Error getClientTargetSupport(Display display, - uint32_t width, uint32_t height, - PixelFormat format, Dataspace dataspace) override; - Error getColorModes(Display display, - hidl_vec* outModes) override; - Error getDisplayAttribute(Display display, Config config, - IComposerClient::Attribute attribute, int32_t* outValue) override; - Error getDisplayConfigs(Display display, - hidl_vec* outConfigs) override; - Error getDisplayName(Display display, hidl_string* outName) override; - Error getDisplayType(Display display, - IComposerClient::DisplayType* outType) override; - Error getDozeSupport(Display display, bool* outSupport) override; - Error getHdrCapabilities(Display display, hidl_vec* outTypes, - float* outMaxLuminance, float* outMaxAverageLuminance, - float* outMinLuminance) override; - - Error setActiveConfig(Display display, Config config) override; - Error setColorMode(Display display, ColorMode mode) override; - Error setPowerMode(Display display, - IComposerClient::PowerMode mode) override; - Error setVsyncEnabled(Display display, - IComposerClient::Vsync enabled) override; - - Error setColorTransform(Display display, const float* matrix, - int32_t hint) override; - Error setClientTarget(Display display, buffer_handle_t target, - int32_t acquireFence, int32_t dataspace, - const std::vector& damage) override; - Error setOutputBuffer(Display display, buffer_handle_t buffer, - int32_t releaseFence) override; - Error validateDisplay(Display display, - std::vector* outChangedLayers, - std::vector* outCompositionTypes, - uint32_t* outDisplayRequestMask, - std::vector* outRequestedLayers, - std::vector* outRequestMasks) override; - Error acceptDisplayChanges(Display display) override; - Error presentDisplay(Display display, int32_t* outPresentFence, - std::vector* outLayers, - std::vector* outReleaseFences) override; - - Error setLayerCursorPosition(Display display, Layer layer, - int32_t x, int32_t y) override; - Error setLayerBuffer(Display display, Layer layer, - buffer_handle_t buffer, int32_t acquireFence) override; - Error setLayerSurfaceDamage(Display display, Layer layer, - const std::vector& damage) override; - Error setLayerBlendMode(Display display, Layer layer, - int32_t mode) override; - Error setLayerColor(Display display, Layer layer, - IComposerClient::Color color) override; - Error setLayerCompositionType(Display display, Layer layer, - int32_t type) override; - Error setLayerDataspace(Display display, Layer layer, - int32_t dataspace) override; - Error setLayerDisplayFrame(Display display, Layer layer, - const hwc_rect_t& frame) override; - Error setLayerPlaneAlpha(Display display, Layer layer, - float alpha) override; - Error setLayerSidebandStream(Display display, Layer layer, - buffer_handle_t stream) override; - Error setLayerSourceCrop(Display display, Layer layer, - const hwc_frect_t& crop) override; - Error setLayerTransform(Display display, Layer layer, - int32_t transform) override; - Error setLayerVisibleRegion(Display display, Layer layer, - const std::vector& visible) override; - Error setLayerZOrder(Display display, Layer layer, uint32_t z) override; - -private: - uint32_t initWithHwc(const hw_module_t* module); - uint32_t initWithFb(const hw_module_t* module); - - void initCapabilities(); - - template - void initDispatch(hwc2_function_descriptor_t desc, T* outPfn); - void initDispatch(); - - static void hotplugHook(hwc2_callback_data_t callbackData, - hwc2_display_t display, int32_t connected); - static void refreshHook(hwc2_callback_data_t callbackData, - hwc2_display_t display); - static void vsyncHook(hwc2_callback_data_t callbackData, - hwc2_display_t display, int64_t timestamp); - - hwc2_device_t* mDevice; - - std::unordered_set mCapabilities; - - struct { - HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges; - HWC2_PFN_CREATE_LAYER createLayer; - HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay; - HWC2_PFN_DESTROY_LAYER destroyLayer; - HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay; - HWC2_PFN_DUMP dump; - HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig; - HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes; - HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport; - HWC2_PFN_GET_COLOR_MODES getColorModes; - HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute; - HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs; - HWC2_PFN_GET_DISPLAY_NAME getDisplayName; - HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests; - HWC2_PFN_GET_DISPLAY_TYPE getDisplayType; - HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport; - HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities; - HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount; - HWC2_PFN_GET_RELEASE_FENCES getReleaseFences; - HWC2_PFN_PRESENT_DISPLAY presentDisplay; - HWC2_PFN_REGISTER_CALLBACK registerCallback; - HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig; - HWC2_PFN_SET_CLIENT_TARGET setClientTarget; - HWC2_PFN_SET_COLOR_MODE setColorMode; - HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform; - HWC2_PFN_SET_CURSOR_POSITION setCursorPosition; - HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode; - HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer; - HWC2_PFN_SET_LAYER_COLOR setLayerColor; - HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType; - HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace; - HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame; - HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha; - HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream; - HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop; - HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage; - HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform; - HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion; - HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder; - HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer; - HWC2_PFN_SET_POWER_MODE setPowerMode; - HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled; - HWC2_PFN_VALIDATE_DISPLAY validateDisplay; - } mDispatch; - - std::atomic mMustValidateDisplay; - - // If the HWC implementation version is < 2.0, use an adapter to interface - // between HWC 2.0 <-> HWC 1.X. - std::unique_ptr mAdapter; - - // If there is no HWC implementation, use an adapter to interface between - // HWC 2.0 <-> FB HAL. - std::unique_ptr mFbAdapter; - - EventCallback* mEventCallback = nullptr; -}; - -extern "C" IComposer* HIDL_FETCH_IComposer(const char* name); - -} // namespace implementation -} // namespace V2_1 -} // namespace composer -} // namespace graphics -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H diff --git a/graphics/composer/2.1/default/passthrough.cpp b/graphics/composer/2.1/default/passthrough.cpp new file mode 100644 index 0000000000..ef7ed7c87a --- /dev/null +++ b/graphics/composer/2.1/default/passthrough.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2016 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 + +using android::hardware::graphics::composer::V2_1::IComposer; +using android::hardware::graphics::composer::V2_1::passthrough::HwcLoader; + +extern "C" IComposer* HIDL_FETCH_IComposer(const char* /* name */) { + return HwcLoader::load(); +} diff --git a/graphics/composer/2.1/utils/passthrough/Android.bp b/graphics/composer/2.1/utils/passthrough/Android.bp new file mode 100644 index 0000000000..4d3c976acd --- /dev/null +++ b/graphics/composer/2.1/utils/passthrough/Android.bp @@ -0,0 +1,22 @@ +cc_library_headers { + name: "android.hardware.graphics.composer@2.1-passthrough", + defaults: ["hidl_defaults"], + vendor: true, + shared_libs: [ + "libhardware", + "libhwc2on1adapter", + "libhwc2onfbadapter", + ], + export_shared_lib_headers: [ + "libhardware", + "libhwc2on1adapter", + "libhwc2onfbadapter", + ], + header_libs: [ + "android.hardware.graphics.composer@2.1-hal", + ], + export_header_lib_headers: [ + "android.hardware.graphics.composer@2.1-hal", + ], + export_include_dirs: ["include"], +} diff --git a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h new file mode 100644 index 0000000000..964e75bdc5 --- /dev/null +++ b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h @@ -0,0 +1,670 @@ +/* + * Copyright 2016 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 // for strerror +#include +#include +#include + +#include +#include +#define HWC2_INCLUDE_STRINGIFICATION +#define HWC2_USE_CPP11 +#include +#undef HWC2_INCLUDE_STRINGIFICATION +#undef HWC2_USE_CPP11 +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace composer { +namespace V2_1 { +namespace passthrough { + +namespace detail { + +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::Hdr; +using android::hardware::graphics::common::V1_0::PixelFormat; +using android::hardware::graphics::common::V1_0::Transform; + +// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2 +template +class HwcHalImpl : public Hal { + public: + virtual ~HwcHalImpl() { + if (mDevice) { + hwc2_close(mDevice); + } + } + + bool initWithModule(const hw_module_t* module) { + hwc2_device_t* device; + int result = hwc2_open(module, &device); + if (result) { + ALOGE("failed to open hwcomposer2 device: %s", strerror(-result)); + return false; + } + + return initWithDevice(std::move(device), true); + } + + bool initWithDevice(hwc2_device_t* device, bool requireReliablePresentFence) { + // we own the device from this point on + mDevice = device; + + initCapabilities(); + if (requireReliablePresentFence && + hasCapability(HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE)) { + ALOGE("present fence must be reliable"); + mDevice->common.close(&mDevice->common); + mDevice = nullptr; + return false; + } + + if (!initDispatch()) { + mDevice->common.close(&mDevice->common); + mDevice = nullptr; + return false; + } + + return true; + } + + bool hasCapability(hwc2_capability_t capability) override { + return (mCapabilities.count(capability) > 0); + } + + std::string dumpDebugInfo() override { + uint32_t len = 0; + mDispatch.dump(mDevice, &len, nullptr); + + std::vector buf(len + 1); + mDispatch.dump(mDevice, &len, buf.data()); + buf.resize(len + 1); + buf[len] = '\0'; + + return buf.data(); + } + + void registerEventCallback(hal::ComposerHal::EventCallback* callback) override { + mMustValidateDisplay = true; + mEventCallback = callback; + + mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, + reinterpret_cast(hotplugHook)); + mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, + reinterpret_cast(refreshHook)); + mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, + reinterpret_cast(vsyncHook)); + } + + void unregisterEventCallback() override { + // we assume the callback functions + // + // - can be unregistered + // - can be in-flight + // - will never be called afterward + // + // which is likely incorrect + mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr); + mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr); + mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, nullptr); + + mEventCallback = nullptr; + } + + uint32_t getMaxVirtualDisplayCount() override { + return mDispatch.getMaxVirtualDisplayCount(mDevice); + } + + Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, + Display* outDisplay) override { + int32_t hwc_format = static_cast(*format); + int32_t err = + mDispatch.createVirtualDisplay(mDevice, width, height, &hwc_format, outDisplay); + *format = static_cast(hwc_format); + + return static_cast(err); + } + + Error destroyVirtualDisplay(Display display) override { + int32_t err = mDispatch.destroyVirtualDisplay(mDevice, display); + return static_cast(err); + } + + Error createLayer(Display display, Layer* outLayer) override { + int32_t err = mDispatch.createLayer(mDevice, display, outLayer); + return static_cast(err); + } + + Error destroyLayer(Display display, Layer layer) override { + int32_t err = mDispatch.destroyLayer(mDevice, display, layer); + return static_cast(err); + } + + Error getActiveConfig(Display display, Config* outConfig) override { + int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig); + return static_cast(err); + } + + Error getClientTargetSupport(Display display, uint32_t width, uint32_t height, + PixelFormat format, Dataspace dataspace) override { + int32_t err = mDispatch.getClientTargetSupport(mDevice, display, width, height, + static_cast(format), + static_cast(dataspace)); + return static_cast(err); + } + + Error getColorModes(Display display, hidl_vec* outModes) override { + uint32_t count = 0; + int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + outModes->resize(count); + err = mDispatch.getColorModes( + mDevice, display, &count, + reinterpret_cast::type*>(outModes->data())); + if (err != HWC2_ERROR_NONE) { + *outModes = hidl_vec(); + return static_cast(err); + } + + return Error::NONE; + } + + Error getDisplayAttribute(Display display, Config config, IComposerClient::Attribute attribute, + int32_t* outValue) override { + int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config, + static_cast(attribute), outValue); + return static_cast(err); + } + + Error getDisplayConfigs(Display display, hidl_vec* outConfigs) override { + uint32_t count = 0; + int32_t err = mDispatch.getDisplayConfigs(mDevice, display, &count, nullptr); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + outConfigs->resize(count); + err = mDispatch.getDisplayConfigs(mDevice, display, &count, outConfigs->data()); + if (err != HWC2_ERROR_NONE) { + *outConfigs = hidl_vec(); + return static_cast(err); + } + + return Error::NONE; + } + + Error getDisplayName(Display display, hidl_string* outName) override { + uint32_t count = 0; + int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + std::vector buf(count + 1); + err = mDispatch.getDisplayName(mDevice, display, &count, buf.data()); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + buf.resize(count + 1); + buf[count] = '\0'; + + *outName = buf.data(); + + return Error::NONE; + } + + Error getDisplayType(Display display, IComposerClient::DisplayType* outType) override { + int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID; + int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type); + *outType = static_cast(hwc_type); + + return static_cast(err); + } + + Error getDozeSupport(Display display, bool* outSupport) override { + int32_t hwc_support = 0; + int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support); + *outSupport = hwc_support; + + return static_cast(err); + } + + Error getHdrCapabilities(Display display, hidl_vec* outTypes, float* outMaxLuminance, + float* outMaxAverageLuminance, float* outMinLuminance) override { + uint32_t count = 0; + int32_t err = + mDispatch.getHdrCapabilities(mDevice, display, &count, nullptr, outMaxLuminance, + outMaxAverageLuminance, outMinLuminance); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + outTypes->resize(count); + err = mDispatch.getHdrCapabilities( + mDevice, display, &count, + reinterpret_cast::type*>(outTypes->data()), outMaxLuminance, + outMaxAverageLuminance, outMinLuminance); + if (err != HWC2_ERROR_NONE) { + *outTypes = hidl_vec(); + return static_cast(err); + } + + return Error::NONE; + } + + Error setActiveConfig(Display display, Config config) override { + int32_t err = mDispatch.setActiveConfig(mDevice, display, config); + return static_cast(err); + } + + Error setColorMode(Display display, ColorMode mode) override { + int32_t err = mDispatch.setColorMode(mDevice, display, static_cast(mode)); + return static_cast(err); + } + + Error setPowerMode(Display display, IComposerClient::PowerMode mode) override { + int32_t err = mDispatch.setPowerMode(mDevice, display, static_cast(mode)); + return static_cast(err); + } + + Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override { + int32_t err = mDispatch.setVsyncEnabled(mDevice, display, static_cast(enabled)); + return static_cast(err); + } + + Error setColorTransform(Display display, const float* matrix, int32_t hint) override { + int32_t err = mDispatch.setColorTransform(mDevice, display, matrix, hint); + return static_cast(err); + } + + Error setClientTarget(Display display, buffer_handle_t target, int32_t acquireFence, + int32_t dataspace, const std::vector& damage) override { + hwc_region region = {damage.size(), damage.data()}; + int32_t err = + mDispatch.setClientTarget(mDevice, display, target, acquireFence, dataspace, region); + return static_cast(err); + } + + Error setOutputBuffer(Display display, buffer_handle_t buffer, int32_t releaseFence) override { + int32_t err = mDispatch.setOutputBuffer(mDevice, display, buffer, releaseFence); + // unlike in setClientTarget, releaseFence is owned by us + if (err == HWC2_ERROR_NONE && releaseFence >= 0) { + close(releaseFence); + } + + return static_cast(err); + } + + Error validateDisplay(Display display, std::vector* outChangedLayers, + std::vector* outCompositionTypes, + uint32_t* outDisplayRequestMask, std::vector* outRequestedLayers, + std::vector* outRequestMasks) override { + uint32_t typesCount = 0; + uint32_t reqsCount = 0; + int32_t err = mDispatch.validateDisplay(mDevice, display, &typesCount, &reqsCount); + mMustValidateDisplay = false; + + if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) { + return static_cast(err); + } + + err = mDispatch.getChangedCompositionTypes(mDevice, display, &typesCount, nullptr, nullptr); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + std::vector changedLayers(typesCount); + std::vector compositionTypes(typesCount); + err = mDispatch.getChangedCompositionTypes( + mDevice, display, &typesCount, changedLayers.data(), + reinterpret_cast::type*>( + compositionTypes.data())); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + int32_t displayReqs = 0; + err = mDispatch.getDisplayRequests(mDevice, display, &displayReqs, &reqsCount, nullptr, + nullptr); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + std::vector requestedLayers(reqsCount); + std::vector requestMasks(reqsCount); + err = mDispatch.getDisplayRequests(mDevice, display, &displayReqs, &reqsCount, + requestedLayers.data(), + reinterpret_cast(requestMasks.data())); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + *outChangedLayers = std::move(changedLayers); + *outCompositionTypes = std::move(compositionTypes); + *outDisplayRequestMask = displayReqs; + *outRequestedLayers = std::move(requestedLayers); + *outRequestMasks = std::move(requestMasks); + + return static_cast(err); + } + + Error acceptDisplayChanges(Display display) override { + int32_t err = mDispatch.acceptDisplayChanges(mDevice, display); + return static_cast(err); + } + + Error presentDisplay(Display display, int32_t* outPresentFence, std::vector* outLayers, + std::vector* outReleaseFences) override { + if (mMustValidateDisplay) { + return Error::NOT_VALIDATED; + } + + *outPresentFence = -1; + int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence); + if (err != HWC2_ERROR_NONE) { + return static_cast(err); + } + + uint32_t count = 0; + err = mDispatch.getReleaseFences(mDevice, display, &count, nullptr, nullptr); + if (err != HWC2_ERROR_NONE) { + ALOGW("failed to get release fences"); + return Error::NONE; + } + + outLayers->resize(count); + outReleaseFences->resize(count); + err = mDispatch.getReleaseFences(mDevice, display, &count, outLayers->data(), + outReleaseFences->data()); + if (err != HWC2_ERROR_NONE) { + ALOGW("failed to get release fences"); + outLayers->clear(); + outReleaseFences->clear(); + return Error::NONE; + } + + return static_cast(err); + } + + Error setLayerCursorPosition(Display display, Layer layer, int32_t x, int32_t y) override { + int32_t err = mDispatch.setCursorPosition(mDevice, display, layer, x, y); + return static_cast(err); + } + + Error setLayerBuffer(Display display, Layer layer, buffer_handle_t buffer, + int32_t acquireFence) override { + int32_t err = mDispatch.setLayerBuffer(mDevice, display, layer, buffer, acquireFence); + return static_cast(err); + } + + Error setLayerSurfaceDamage(Display display, Layer layer, + const std::vector& damage) override { + hwc_region region = {damage.size(), damage.data()}; + int32_t err = mDispatch.setLayerSurfaceDamage(mDevice, display, layer, region); + return static_cast(err); + } + + Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override { + int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode); + return static_cast(err); + } + + Error setLayerColor(Display display, Layer layer, IComposerClient::Color color) override { + hwc_color_t hwc_color{color.r, color.g, color.b, color.a}; + int32_t err = mDispatch.setLayerColor(mDevice, display, layer, hwc_color); + return static_cast(err); + } + + Error setLayerCompositionType(Display display, Layer layer, int32_t type) override { + int32_t err = mDispatch.setLayerCompositionType(mDevice, display, layer, type); + return static_cast(err); + } + + Error setLayerDataspace(Display display, Layer layer, int32_t dataspace) override { + int32_t err = mDispatch.setLayerDataspace(mDevice, display, layer, dataspace); + return static_cast(err); + } + + Error setLayerDisplayFrame(Display display, Layer layer, const hwc_rect_t& frame) override { + int32_t err = mDispatch.setLayerDisplayFrame(mDevice, display, layer, frame); + return static_cast(err); + } + + Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override { + int32_t err = mDispatch.setLayerPlaneAlpha(mDevice, display, layer, alpha); + return static_cast(err); + } + + Error setLayerSidebandStream(Display display, Layer layer, buffer_handle_t stream) override { + int32_t err = mDispatch.setLayerSidebandStream(mDevice, display, layer, stream); + return static_cast(err); + } + + Error setLayerSourceCrop(Display display, Layer layer, const hwc_frect_t& crop) override { + int32_t err = mDispatch.setLayerSourceCrop(mDevice, display, layer, crop); + return static_cast(err); + } + + Error setLayerTransform(Display display, Layer layer, int32_t transform) override { + int32_t err = mDispatch.setLayerTransform(mDevice, display, layer, transform); + return static_cast(err); + } + + Error setLayerVisibleRegion(Display display, Layer layer, + const std::vector& visible) override { + hwc_region_t region = {visible.size(), visible.data()}; + int32_t err = mDispatch.setLayerVisibleRegion(mDevice, display, layer, region); + return static_cast(err); + } + + Error setLayerZOrder(Display display, Layer layer, uint32_t z) override { + int32_t err = mDispatch.setLayerZOrder(mDevice, display, layer, z); + return static_cast(err); + } + + protected: + virtual void initCapabilities() { + uint32_t count = 0; + mDevice->getCapabilities(mDevice, &count, nullptr); + + std::vector caps(count); + mDevice->getCapabilities(mDevice, &count, caps.data()); + caps.resize(count); + + mCapabilities.reserve(count); + for (auto cap : caps) { + mCapabilities.insert(static_cast(cap)); + } + } + + template + bool initDispatch(hwc2_function_descriptor_t desc, T* outPfn) { + auto pfn = mDevice->getFunction(mDevice, desc); + if (pfn) { + *outPfn = reinterpret_cast(pfn); + return true; + } else { + ALOGE("failed to get hwcomposer2 function %d", desc); + return false; + } + } + + virtual bool initDispatch() { + if (!initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES, &mDispatch.acceptDisplayChanges) || + !initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer) || + !initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY, &mDispatch.createVirtualDisplay) || + !initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer) || + !initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY, + &mDispatch.destroyVirtualDisplay) || + !initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump) || + !initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig) || + !initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES, + &mDispatch.getChangedCompositionTypes) || + !initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT, + &mDispatch.getClientTargetSupport) || + !initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes) || + !initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE, &mDispatch.getDisplayAttribute) || + !initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS, &mDispatch.getDisplayConfigs) || + !initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName) || + !initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS, &mDispatch.getDisplayRequests) || + !initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType) || + !initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport) || + !initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES, &mDispatch.getHdrCapabilities) || + !initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT, + &mDispatch.getMaxVirtualDisplayCount) || + !initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES, &mDispatch.getReleaseFences) || + !initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay) || + !initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK, &mDispatch.registerCallback) || + !initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig) || + !initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget) || + !initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode) || + !initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM, &mDispatch.setColorTransform) || + !initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION, &mDispatch.setCursorPosition) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE, &mDispatch.setLayerBlendMode) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE, + &mDispatch.setLayerCompositionType) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE, &mDispatch.setLayerDataspace) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME, &mDispatch.setLayerDisplayFrame) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA, &mDispatch.setLayerPlaneAlpha)) { + return false; + } + + if (hasCapability(HWC2_CAPABILITY_SIDEBAND_STREAM)) { + if (!initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM, + &mDispatch.setLayerSidebandStream)) { + return false; + } + } + + if (!initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP, &mDispatch.setLayerSourceCrop) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE, + &mDispatch.setLayerSurfaceDamage) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM, &mDispatch.setLayerTransform) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION, + &mDispatch.setLayerVisibleRegion) || + !initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder) || + !initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer) || + !initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode) || + !initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled) || + !initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay)) { + return false; + } + + return true; + } + + static void hotplugHook(hwc2_callback_data_t callbackData, hwc2_display_t display, + int32_t connected) { + auto hal = static_cast(callbackData); + hal->mEventCallback->onHotplug(display, + static_cast(connected)); + } + + static void refreshHook(hwc2_callback_data_t callbackData, hwc2_display_t display) { + auto hal = static_cast(callbackData); + hal->mMustValidateDisplay = true; + hal->mEventCallback->onRefresh(display); + } + + static void vsyncHook(hwc2_callback_data_t callbackData, hwc2_display_t display, + int64_t timestamp) { + auto hal = static_cast(callbackData); + hal->mEventCallback->onVsync(display, timestamp); + } + + hwc2_device_t* mDevice = nullptr; + + std::unordered_set mCapabilities; + + struct { + HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges; + HWC2_PFN_CREATE_LAYER createLayer; + HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay; + HWC2_PFN_DESTROY_LAYER destroyLayer; + HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay; + HWC2_PFN_DUMP dump; + HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig; + HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes; + HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport; + HWC2_PFN_GET_COLOR_MODES getColorModes; + HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute; + HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs; + HWC2_PFN_GET_DISPLAY_NAME getDisplayName; + HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests; + HWC2_PFN_GET_DISPLAY_TYPE getDisplayType; + HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport; + HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities; + HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount; + HWC2_PFN_GET_RELEASE_FENCES getReleaseFences; + HWC2_PFN_PRESENT_DISPLAY presentDisplay; + HWC2_PFN_REGISTER_CALLBACK registerCallback; + HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig; + HWC2_PFN_SET_CLIENT_TARGET setClientTarget; + HWC2_PFN_SET_COLOR_MODE setColorMode; + HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform; + HWC2_PFN_SET_CURSOR_POSITION setCursorPosition; + HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode; + HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer; + HWC2_PFN_SET_LAYER_COLOR setLayerColor; + HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType; + HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace; + HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame; + HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha; + HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream; + HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop; + HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage; + HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform; + HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion; + HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder; + HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer; + HWC2_PFN_SET_POWER_MODE setPowerMode; + HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled; + HWC2_PFN_VALIDATE_DISPLAY validateDisplay; + } mDispatch = {}; + + hal::ComposerHal::EventCallback* mEventCallback = nullptr; + + std::atomic mMustValidateDisplay{true}; +}; + +} // namespace detail + +using HwcHal = detail::HwcHalImpl; + +} // namespace passthrough +} // namespace V2_1 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h new file mode 100644 index 0000000000..33c914dde1 --- /dev/null +++ b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h @@ -0,0 +1,152 @@ +/* + * Copyright 2016 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 +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace composer { +namespace V2_1 { +namespace passthrough { + +class 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)); + } + + // load hwcomposer2 module + static const hw_module_t* loadModule() { + const hw_module_t* module; + int error = hw_get_module(HWC_HARDWARE_MODULE_ID, &module); + if (error) { + ALOGI("falling back to gralloc module"); + error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + } + + if (error) { + ALOGE("failed to get hwcomposer or gralloc module"); + return nullptr; + } + + return module; + } + + // 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 IComposer* createComposer(std::unique_ptr hal) { + return hal::Composer::create(std::move(hal)).release(); + } + + protected: + // open hwcomposer2 device, install an adapter if necessary + static hwc2_device_t* openDeviceWithAdapter(const hw_module_t* module, bool* outAdapted) { + if (module->id && std::string(module->id) == GRALLOC_HARDWARE_MODULE_ID) { + *outAdapted = true; + return adaptGrallocModule(module); + } + + hw_device_t* device; + int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device); + if (error) { + ALOGE("failed to open hwcomposer device: %s", strerror(-error)); + return nullptr; + } + + int major = (device->version >> 24) & 0xf; + if (major != 2) { + *outAdapted = true; + return adaptHwc1Device(std::move(reinterpret_cast(device))); + } + + *outAdapted = false; + return reinterpret_cast(device); + } + + private: + static hwc2_device_t* adaptGrallocModule(const hw_module_t* module) { + framebuffer_device_t* device; + int error = framebuffer_open(module, &device); + if (error) { + ALOGE("failed to open framebuffer device: %s", strerror(-error)); + return nullptr; + } + + return new HWC2OnFbAdapter(device); + } + + static hwc2_device_t* adaptHwc1Device(hwc_composer_device_1* device) { + int minor = (device->common.version >> 16) & 0xf; + if (minor < 1) { + ALOGE("hwcomposer 1.0 is not supported"); + device->common.close(&device->common); + return nullptr; + } + + return new HWC2On1Adapter(device); + } +}; + +} // namespace passthrough +} // namespace V2_1 +} // namespace composer +} // namespace graphics +} // namespace hardware +} // namespace android