diff options
author | Yichi Chen <yichichen@google.com> | 2022-03-15 07:21:58 +0800 |
---|---|---|
committer | Yichi Chen <yichichen@google.com> | 2022-04-08 05:25:15 +0800 |
commit | d767263ad9fb5c93da0864c4311b0ec8a8ab5a08 (patch) | |
tree | 37a0edd8f53962bc73562773d3945aff0f0b772d | |
parent | 5fb2b2e3057510c14a68d947552adf3bbdcc90cb (diff) |
hwc3: implement VsyncIdle callback for HWC3
The patch creates the new method to register the HWC3 callback function.
The corresponding VsyncIdle callback function will be called when idle
TE vrefresh is changed in the idle.
Bug: 194068871
Test: switch refresh rates, enable panel idle at 60hz
Change-Id: I4876fdfd341366ca2012a3ce6704a2c8de5866d2
-rw-r--r-- | hwc3/impl/HalImpl.cpp | 13 | ||||
-rw-r--r-- | libhwc2.1/libdevice/ExynosDevice.cpp | 44 | ||||
-rw-r--r-- | libhwc2.1/libdevice/ExynosDevice.h | 6 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp | 18 |
4 files changed, 62 insertions, 19 deletions
diff --git a/hwc3/impl/HalImpl.cpp b/hwc3/impl/HalImpl.cpp index 1029fe8..38c8b02 100644 --- a/hwc3/impl/HalImpl.cpp +++ b/hwc3/impl/HalImpl.cpp @@ -14,15 +14,17 @@ * limitations under the License. */ +#include "HalImpl.h" + +#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h> #include <android-base/logging.h> #include <hardware/hwcomposer2.h> -#include "ExynosDeviceModule.h" #include "ExynosDevice.h" +#include "ExynosDeviceModule.h" #include "ExynosDisplay.h" #include "ExynosHWCService.h" #include "ExynosLayer.h" -#include "HalImpl.h" #include "TranslateHwcAidl.h" #include "Util.h" @@ -185,6 +187,10 @@ void HalImpl::registerEventCallback(EventCallback* callback) { reinterpret_cast<hwc2_function_pointer_t>(hook::vsyncPeriodTimingChanged)); mDevice->registerCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this, reinterpret_cast<hwc2_function_pointer_t>(hook::seamlessPossible)); + + // register HWC3 Callback + mDevice->registerHwc3Callback(IComposerCallback::TRANSACTION_onVsyncIdle, this, + reinterpret_cast<hwc2_function_pointer_t>(hook::vsyncIdle)); } void HalImpl::unregisterEventCallback() { @@ -194,6 +200,9 @@ void HalImpl::unregisterEventCallback() { mDevice->registerCallback(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this, nullptr); mDevice->registerCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this, nullptr); + // unregister HWC3 Callback + mDevice->registerHwc3Callback(IComposerCallback::TRANSACTION_onVsyncIdle, this, nullptr); + mEventCallback = nullptr; } diff --git a/libhwc2.1/libdevice/ExynosDevice.cpp b/libhwc2.1/libdevice/ExynosDevice.cpp index afcb3ec..fbc92f0 100644 --- a/libhwc2.1/libdevice/ExynosDevice.cpp +++ b/libhwc2.1/libdevice/ExynosDevice.cpp @@ -14,24 +14,28 @@ * limitations under the License. */ -#include "BrightnessController.h" #include "ExynosDevice.h" + +#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h> +#include <sync/sync.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "BrightnessController.h" +#include "ExynosDeviceDrmInterface.h" #include "ExynosDisplay.h" +#include "ExynosExternalDisplayModule.h" +#include "ExynosHWCDebug.h" +#include "ExynosHWCHelper.h" #include "ExynosLayer.h" #include "ExynosPrimaryDisplayModule.h" #include "ExynosResourceManagerModule.h" -#include "ExynosExternalDisplayModule.h" #include "ExynosVirtualDisplayModule.h" -#include "ExynosHWCDebug.h" -#include "ExynosHWCHelper.h" -#include "ExynosDeviceDrmInterface.h" -#include <unistd.h> -#include <sync/sync.h> -#include <sys/mman.h> #include "VendorGraphicBuffer.h" using namespace vendor::graphics; using namespace SOC_VERSION; +using aidl::android::hardware::graphics::composer3::IComposerCallback; /** * ExynosDevice implementation @@ -39,8 +43,6 @@ using namespace SOC_VERSION; class ExynosDevice; -extern void vsync_callback(hwc2_callback_data_t callbackData, - hwc2_display_t displayId, int64_t timestamp); extern uint32_t mFenceLogSize; extern void PixelDisplayInit(ExynosDevice *device); @@ -1124,3 +1126,25 @@ int ExynosDevice::setRefreshRateThrottle(const int delayMs) { } return BAD_VALUE; } + +int32_t ExynosDevice::registerHwc3Callback(uint32_t descriptor, hwc2_callback_data_t callbackData, + hwc2_function_pointer_t point) { + mHwc3CallbackInfos[descriptor].callbackData = callbackData; + mHwc3CallbackInfos[descriptor].funcPointer = point; + + return HWC2_ERROR_NONE; +} + +void ExynosDevice::onVsyncIdle(hwc2_display_t displayId) { + const auto &idleCallback = mHwc3CallbackInfos.find(IComposerCallback::TRANSACTION_onVsyncIdle); + + if (idleCallback == mHwc3CallbackInfos.end()) return; + + const auto &callbackInfo = idleCallback->second; + if (callbackInfo.funcPointer == nullptr || callbackInfo.callbackData == nullptr) return; + + auto callbackFunc = + reinterpret_cast<void (*)(hwc2_callback_data_t callbackData, + hwc2_display_t hwcDisplay)>(callbackInfo.funcPointer); + callbackFunc(callbackInfo.callbackData, displayId); +} diff --git a/libhwc2.1/libdevice/ExynosDevice.h b/libhwc2.1/libdevice/ExynosDevice.h index e206024..d5a02fe 100644 --- a/libhwc2.1/libdevice/ExynosDevice.h +++ b/libhwc2.1/libdevice/ExynosDevice.h @@ -184,6 +184,8 @@ class ExynosDevice { /** TODO : Array size shuld be checked */ exynos_callback_info_t mCallbackInfos[HWC2_CALLBACK_SEAMLESS_POSSIBLE + 1]; + std::map<uint32_t, exynos_callback_info_t> mHwc3CallbackInfos; + /** * Thread variables */ @@ -320,6 +322,10 @@ class ExynosDevice { uint32_t getSpecialPlaneId(uint32_t index); uint64_t getSpecialPlaneAttr(uint32_t index); + int32_t registerHwc3Callback(uint32_t descriptor, hwc2_callback_data_t callbackData, + hwc2_function_pointer_t point); + void onVsyncIdle(hwc2_display_t displayId); + protected: void initDeviceInterface(uint32_t interfaceType); protected: diff --git a/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp index c3746ef..1836c11 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp @@ -272,7 +272,7 @@ void ExynosDeviceDrmInterface::ExynosDrmEventHandler::handleTUIEvent() { constexpr size_t IDLE_ENTER_EVENT_DATA_SIZE = 3; void ExynosDeviceDrmInterface::ExynosDrmEventHandler::handleIdleEnterEvent(char const *event) { - /* PANEL_IDLE_ENTER=<display id>,<vrefresh>,<idle te vrefresh> */ + /* PANEL_IDLE_ENTER=<display index>,<vrefresh>,<idle te vrefresh> */ std::string_view idle_event_str(event); auto prefix_shift_pos = idle_event_str.find("="); if (prefix_shift_pos == std::string::npos) { @@ -280,7 +280,9 @@ void ExynosDeviceDrmInterface::ExynosDrmEventHandler::handleIdleEnterEvent(char } int count = 0; - int value[IDLE_ENTER_EVENT_DATA_SIZE] = {0}; /* display id, vrefresh, idle_te_vrefresh */ + int value[IDLE_ENTER_EVENT_DATA_SIZE] = {0}; + const auto &[displayIndex, vrefresh, idleTeVrefresh] = value; + auto start_pos = prefix_shift_pos + 1; auto end_pos = idle_event_str.find(",", start_pos); while (end_pos != std::string::npos && count < IDLE_ENTER_EVENT_DATA_SIZE) { @@ -300,12 +302,14 @@ void ExynosDeviceDrmInterface::ExynosDrmEventHandler::handleIdleEnterEvent(char return; } - /* TODO: b/194068871 sending vsyncIdle callback */ - // if (value[1] != value[2]) - ExynosDisplay *primaryDisplay = - mExynosDevice->getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, value[0])); + mExynosDevice->getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, displayIndex)); if (primaryDisplay) { - primaryDisplay->handleDisplayIdleEnter(value[2]); + /* sending vsyncIdle callback */ + if (vrefresh != idleTeVrefresh) { + mExynosDevice->onVsyncIdle(primaryDisplay->getId()); + } + + primaryDisplay->handleDisplayIdleEnter(idleTeVrefresh); } } |