summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-11 15:44:16 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-11 15:44:16 +0000
commit2cb11755c39eb3911e2b0394eaba620db9e2dec4 (patch)
tree75d231fc860f9ee34ff424d512110267547df67c
parentc8f94098b6bcf8b2cbb0f7b779714e1cacf35d8b (diff)
parent7324e6459d55ca5714a0e31ae2b85d508387db93 (diff)
downloadcommon-android13-frc-art-release.tar.gz
Snap for 8712302 from 7324e6459d55ca5714a0e31ae2b85d508387db93 to tm-frc-art-releaset_frc_art_330443060android13-frc-art-release
Change-Id: I4981c727462b3bbfd1e0c6bd099704112f2092a9
-rw-r--r--hwc3/Android.mk2
-rw-r--r--include/displaycolor/displaycolor.h10
-rw-r--r--libhwc2.1/Android.mk6
-rw-r--r--libhwc2.1/ExynosHWCDebug.cpp99
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.cpp131
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.h16
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.cpp109
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.h16
-rw-r--r--libhwc2.1/libdevice/ExynosLayer.cpp3
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp16
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp67
-rw-r--r--libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp16
-rw-r--r--libhwc2.1/libhwcService/ExynosHWCService.cpp6
-rw-r--r--libhwc2.1/libhwchelper/ExynosHWCHelper.cpp262
-rw-r--r--libhwc2.1/libhwchelper/ExynosHWCHelper.h110
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp25
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h2
-rw-r--r--libhwc2.1/libresource/ExynosMPP.cpp32
-rw-r--r--libhwc2.1/libvirtualdisplay/ExynosVirtualDisplay.cpp9
-rw-r--r--libhwc2.1/pixel-display-default.xml2
-rw-r--r--libhwc2.1/pixel-display.cpp15
-rw-r--r--libhwc2.1/pixel-display.h9
22 files changed, 445 insertions, 518 deletions
diff --git a/hwc3/Android.mk b/hwc3/Android.mk
index a942355..f233aab 100644
--- a/hwc3/Android.mk
+++ b/hwc3/Android.mk
@@ -35,7 +35,7 @@ LOCAL_SHARED_LIBRARIES := android.hardware.graphics.composer3-V1-ndk \
android.hardware.graphics.composer@2.1-resources \
android.hardware.graphics.composer@2.2-resources \
android.hardware.graphics.composer@2.4 \
- com.google.hardware.pixel.display-V4-ndk \
+ com.google.hardware.pixel.display-V6-ndk \
libbase \
libbinder \
libbinder_ndk \
diff --git a/include/displaycolor/displaycolor.h b/include/displaycolor/displaycolor.h
index eb96ce0..d9141ff 100644
--- a/include/displaycolor/displaycolor.h
+++ b/include/displaycolor/displaycolor.h
@@ -34,6 +34,7 @@ using android::hardware::graphics::common::V1_2::PixelFormat;
/**
* hwc/displaycolor interface history
*
+ * 6.1.0.2022-05-18 Get calibrated serial number.
* 6.0.0.2022-02-22 Get whether dimming in linear.
* 5.0.0.2022-02-17 Add layer dim ratio.
* 4.0.0.2021-12-20 Get pixel format and dataspace of blending stage.
@@ -60,7 +61,7 @@ constexpr struct DisplayColorIntfVer {
} kInterfaceVersion {
6,
- 0,
+ 1,
0,
};
@@ -382,6 +383,13 @@ class IDisplayColorGeneric {
hwc::PixelFormat &pixel_format,
hwc::Dataspace &dataspace,
bool &dimming_linear) const = 0;
+
+ /**
+ * @brief Get the serial number for the panel used during calibration.
+ * @param display to get the calibrated serial number.
+ * @return The calibrated serial number.
+ */
+ virtual const std::string& GetCalibratedSerialNumber(DisplayType display) const = 0;
};
extern "C" {
diff --git a/libhwc2.1/Android.mk b/libhwc2.1/Android.mk
index 7a5e885..1918890 100644
--- a/libhwc2.1/Android.mk
+++ b/libhwc2.1/Android.mk
@@ -68,7 +68,7 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware \
android.hardware.power-V2-ndk pixel-power-ext-V1-ndk
LOCAL_SHARED_LIBRARIES += android.hardware.graphics.composer3-V1-ndk \
- com.google.hardware.pixel.display-V4-ndk \
+ com.google.hardware.pixel.display-V6-ndk \
libbinder_ndk \
libbase \
libpng \
@@ -155,7 +155,7 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libbinder libexynosdisplay l
android.hardware.graphics.allocator@2.0 \
android.hardware.graphics.mapper@2.0
-LOCAL_SHARED_LIBRARIES += com.google.hardware.pixel.display-V4-ndk \
+LOCAL_SHARED_LIBRARIES += com.google.hardware.pixel.display-V6-ndk \
libbinder_ndk \
libbase
@@ -216,7 +216,7 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libexynosdisplay libacryl \
libui
LOCAL_SHARED_LIBRARIES += android.hardware.graphics.composer3-V1-ndk \
- com.google.hardware.pixel.display-V4-ndk \
+ com.google.hardware.pixel.display-V6-ndk \
libbinder_ndk \
libbase
diff --git a/libhwc2.1/ExynosHWCDebug.cpp b/libhwc2.1/ExynosHWCDebug.cpp
index 982a54d..bbf676c 100644
--- a/libhwc2.1/ExynosHWCDebug.cpp
+++ b/libhwc2.1/ExynosHWCDebug.cpp
@@ -50,23 +50,14 @@ int32_t saveErrorLog(const String8 &errString, ExynosDisplay *display)
String8 saveString;
struct timeval tv;
- struct tm* localTime;
gettimeofday(&tv, NULL);
- localTime = (struct tm*)localtime((time_t*)&tv.tv_sec);
if (display != NULL) {
- saveString.appendFormat("%02d-%02d %02d:%02d:%02d.%03lu(%lu) %s %" PRIu64 ": %s\n",
- localTime->tm_mon+1, localTime->tm_mday,
- localTime->tm_hour, localTime->tm_min,
- localTime->tm_sec, tv.tv_usec/1000, ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)),
- display->mDisplayName.string(), display->mErrorFrameCount,
- errString.string());
+ saveString.appendFormat("%s %s %" PRIu64 ": %s\n", getLocalTimeStr(tv).string(),
+ display->mDisplayName.string(), display->mErrorFrameCount,
+ errString.string());
} else {
- saveString.appendFormat("%02d-%02d %02d:%02d:%02d.%03lu(%lu) : %s\n",
- localTime->tm_mon+1, localTime->tm_mday,
- localTime->tm_hour, localTime->tm_min,
- localTime->tm_sec, tv.tv_usec/1000, ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)),
- errString.string());
+ saveString.appendFormat("%s : %s\n", getLocalTimeStr(tv).string(), errString.string());
}
if (pFile != NULL) {
@@ -105,80 +96,24 @@ int32_t saveFenceTrace(ExynosDisplay *display) {
return -1;
}
+ ExynosDevice *device = display->mDevice;
+
String8 saveString;
- struct timeval tv;
- ExynosDevice *device = display->mDevice;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ saveString.appendFormat("\n====== Fences at time:%s ======\n", getLocalTimeStr(tv).string());
if (device != NULL) {
- for (const auto &[i, info] : device->mFenceInfos) {
-#if 0
- bool sysFdOpen = false;
-
- // FIXME: sync_fence_info and sync_pt_info are deprecated
- // HWC guys should fix this
- struct sync_pt_info* pt_info = NULL;
- info.sync_data = sync_fence_info(i);
- if (info.sync_data != NULL) {
- pt_info = sync_pt_info(info.sync_data, pt_info);
- if (pt_info !=NULL) {
- saveString.appendFormat("\n-- FD sys : %d\n", i);
- saveString.appendFormat("real name : %s, status : %s, pt_obj : %s, pt_drv : %s, time : %llu",
- info.sync_data->name, info.sync_data->status==1 ? "Active":"Signaled",
- pt_info->obj_name, pt_info->driver_name, static_cast<unsigned long long>(pt_info->timestamp_ns));
- } else {
- saveString.appendFormat("\n-- FD sys : %d\n", i);
- saveString.appendFormat("real name : %s, status : %d, pt_info : %p",
- info.sync_data->name, info.sync_data->status, pt_info);
- }
- sysFdOpen = true;
- sync_fence_info_free(info.sync_data);
- }
-
- if ((info.usage == 0) && !sysFdOpen) continue;
-#endif
-
- saveString.appendFormat("\n-- FD hwc : %d, usage %d\n", i, info.usage);
-
- switch(info.last_dir) {
- case FENCE_FROM:
- saveString.appendFormat("Last state : from %d, %d\n",
- info.from.type, info.from.ip);
- tv = info.from.time;
- break;
- case FENCE_TO:
- saveString.appendFormat("Last state : to %d, %d\n",
- info.to.type, info.to.ip);
- tv = info.to.time;
- break;
- case FENCE_DUP:
- saveString.appendFormat("Last state : dup %d, %d\n",
- info.dup.type, info.dup.ip);
- tv = info.dup.time;
- break;
- case FENCE_CLOSE:
- saveString.appendFormat("Last state : Close %d, %d\n",
- info.close.type, info.close.ip);
- tv = info.close.time;
- break;
- break;
- default:
- saveString.appendFormat("Fence trace : Undefined direction!\n");
- break;
+ for (const auto &[fd, info] : device->mFenceInfos) {
+ saveString.appendFormat("---- Fence FD : %d, Display(%d) ----\n", fd, info.displayId);
+ saveString.appendFormat("usage: %d, dupFrom: %d, pendingAllowed: %d, leaking: %d\n",
+ info.usage, info.dupFrom, info.pendingAllowed, info.leaking);
+
+ for (const auto &trace : info.traces) {
+ saveString.appendFormat("> dir: %d, type: %d, ip: %d, time:%s\n", trace.direction,
+ trace.type, trace.ip, getLocalTimeStr(trace.time).string());
}
-
- struct tm* localTime = (struct tm*)localtime((time_t*)&tv.tv_sec);
-
- saveString.appendFormat("from : %d, %d (cur : %d), to : %d, %d (cur : %d), hwc_dup : %d, %d (cur : %d), hwc_close : %d, %d (cur : %d)\n",
- info.from.type, info.from.ip, info.from.curFlag,
- info.to.type, info.to.ip, info.to.curFlag,
- info.dup.type, info.dup.ip, info.dup.curFlag,
- info.close.type, info.close.ip, info.close.curFlag);
- saveString.appendFormat("usage : %d, time:%02d-%02d %02d:%02d:%02d.%03lu(%lu)", info.usage,
- localTime->tm_mon+1, localTime->tm_mday,
- localTime->tm_hour, localTime->tm_min,
- localTime->tm_sec, tv.tv_usec/1000,
- ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
}
}
diff --git a/libhwc2.1/libdevice/ExynosDevice.cpp b/libhwc2.1/libdevice/ExynosDevice.cpp
index fbc92f0..99f9438 100644
--- a/libhwc2.1/libdevice/ExynosDevice.cpp
+++ b/libhwc2.1/libdevice/ExynosDevice.cpp
@@ -311,8 +311,7 @@ void *ExynosDevice::dynamicRecompositionThreadLoop(void *data)
}
}
}
- if (result)
- dev->invalidate();
+ if (result) dev->onRefresh();
}
android_atomic_dec(&(dev->mDRThreadStatus));
@@ -439,14 +438,15 @@ int32_t ExynosDevice::registerCallback (
if (descriptor < 0 || descriptor > HWC2_CALLBACK_SEAMLESS_POSSIBLE)
return HWC2_ERROR_BAD_PARAMETER;
+ Mutex::Autolock lock(mDeviceCallbackMutex);
mCallbackInfos[descriptor].callbackData = callbackData;
mCallbackInfos[descriptor].funcPointer = point;
/* Call hotplug callback for primary display*/
if (descriptor == HWC2_CALLBACK_HOTPLUG) {
HWC2_PFN_HOTPLUG callbackFunc =
- (HWC2_PFN_HOTPLUG)mCallbackInfos[descriptor].funcPointer;
- if (callbackFunc != NULL) {
+ reinterpret_cast<HWC2_PFN_HOTPLUG>(mCallbackInfos[descriptor].funcPointer);
+ if (callbackFunc != nullptr) {
for (auto it : mDisplays) {
if (it->mPlugState)
callbackFunc(callbackData, getDisplayId(it->mType, it->mIndex),
@@ -466,16 +466,90 @@ int32_t ExynosDevice::registerCallback (
return HWC2_ERROR_NONE;
}
-void ExynosDevice::invalidate()
-{
+bool ExynosDevice::isCallbackRegisteredLocked(int32_t descriptor) {
+ if (descriptor < 0 || descriptor > HWC2_CALLBACK_SEAMLESS_POSSIBLE) {
+ ALOGE("%s:: %d callback is unknown", __func__, descriptor);
+ return false;
+ }
+
+ if (mCallbackInfos[descriptor].callbackData == nullptr ||
+ mCallbackInfos[descriptor].funcPointer == nullptr) {
+ ALOGE("%s:: %d callback is not registered", __func__, descriptor);
+ return false;
+ }
+
+ return true;
+}
+
+bool ExynosDevice::isCallbackAvailable(int32_t descriptor) {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
+ return isCallbackRegisteredLocked(descriptor);
+}
+
+void ExynosDevice::onHotPlug(uint32_t displayId, bool status) {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
+
+ if (!isCallbackRegisteredLocked(HWC2_CALLBACK_HOTPLUG)) return;
+
+ hwc2_callback_data_t callbackData = mCallbackInfos[HWC2_CALLBACK_HOTPLUG].callbackData;
+ HWC2_PFN_HOTPLUG callbackFunc =
+ reinterpret_cast<HWC2_PFN_HOTPLUG>(mCallbackInfos[HWC2_CALLBACK_HOTPLUG].funcPointer);
+ callbackFunc(callbackData, displayId,
+ status ? HWC2_CONNECTION_CONNECTED : HWC2_CONNECTION_DISCONNECTED);
+}
+
+void ExynosDevice::onRefresh() {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
+
+ if (!isCallbackRegisteredLocked(HWC2_CALLBACK_REFRESH)) return;
+
+ hwc2_callback_data_t callbackData = mCallbackInfos[HWC2_CALLBACK_REFRESH].callbackData;
HWC2_PFN_REFRESH callbackFunc =
- (HWC2_PFN_REFRESH)mCallbackInfos[HWC2_CALLBACK_REFRESH].funcPointer;
- if (callbackFunc != NULL)
- callbackFunc(mCallbackInfos[HWC2_CALLBACK_REFRESH].callbackData,
- getDisplayId(HWC_DISPLAY_PRIMARY, 0));
- else
- ALOGE("%s:: refresh callback is not registered", __func__);
+ reinterpret_cast<HWC2_PFN_REFRESH>(mCallbackInfos[HWC2_CALLBACK_REFRESH].funcPointer);
+ callbackFunc(callbackData, getDisplayId(HWC_DISPLAY_PRIMARY, 0));
+}
+
+void ExynosDevice::onVsync(uint32_t displayId, int64_t timestamp) {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
+
+ if (!isCallbackRegisteredLocked(HWC2_CALLBACK_VSYNC)) return;
+
+ hwc2_callback_data_t callbackData = mCallbackInfos[HWC2_CALLBACK_VSYNC].callbackData;
+ HWC2_PFN_VSYNC callbackFunc =
+ reinterpret_cast<HWC2_PFN_VSYNC>(mCallbackInfos[HWC2_CALLBACK_VSYNC].funcPointer);
+ callbackFunc(callbackData, displayId, timestamp);
+}
+
+bool ExynosDevice::onVsync_2_4(uint32_t displayId, int64_t timestamp, uint32_t vsyncPeriod) {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
+
+ if (!isCallbackRegisteredLocked(HWC2_CALLBACK_VSYNC_2_4)) return false;
+
+ hwc2_callback_data_t callbackData = mCallbackInfos[HWC2_CALLBACK_VSYNC_2_4].callbackData;
+ HWC2_PFN_VSYNC_2_4 callbackFunc = reinterpret_cast<HWC2_PFN_VSYNC_2_4>(
+ mCallbackInfos[HWC2_CALLBACK_VSYNC_2_4].funcPointer);
+ callbackFunc(callbackData, displayId, timestamp, vsyncPeriod);
+
+ return true;
+}
+
+void ExynosDevice::onVsyncPeriodTimingChanged(uint32_t displayId,
+ hwc_vsync_period_change_timeline_t *timeline) {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
+ if (!timeline) {
+ ALOGE("vsync period change timeline is null");
+ return;
+ }
+
+ if (!isCallbackRegisteredLocked(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED)) return;
+
+ hwc2_callback_data_t callbackData =
+ mCallbackInfos[HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED].callbackData;
+ HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED callbackFunc =
+ reinterpret_cast<HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED>(
+ mCallbackInfos[HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED].funcPointer);
+ callbackFunc(callbackData, displayId, timeline);
}
void ExynosDevice::setHWCDebug(unsigned int debug)
@@ -533,13 +607,13 @@ void ExynosDevice::setHWCControl(uint32_t display, uint32_t ctrl, int32_t val)
ALOGI("%s::HWC_CTL_FORCE_GPU on/off=%d", __func__, val);
exynosHWCControl.forceGpu = (unsigned int)val;
setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- invalidate();
+ onRefresh();
break;
case HWC_CTL_WINDOW_UPDATE:
ALOGI("%s::HWC_CTL_WINDOW_UPDATE on/off=%d", __func__, val);
exynosHWCControl.windowUpdate = (unsigned int)val;
setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- invalidate();
+ onRefresh();
break;
case HWC_CTL_FORCE_PANIC:
ALOGI("%s::HWC_CTL_FORCE_PANIC on/off=%d", __func__, val);
@@ -560,19 +634,19 @@ void ExynosDevice::setHWCControl(uint32_t display, uint32_t ctrl, int32_t val)
ALOGI("%s::HWC_CTL_SKIP_RESOURCE_ASSIGN on/off=%d", __func__, val);
exynosHWCControl.skipResourceAssign = (unsigned int)val;
setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- invalidate();
+ onRefresh();
break;
case HWC_CTL_SKIP_VALIDATE:
ALOGI("%s::HWC_CTL_SKIP_VALIDATE on/off=%d", __func__, val);
exynosHWCControl.skipValidate = (unsigned int)val;
setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- invalidate();
+ onRefresh();
break;
case HWC_CTL_DUMP_MID_BUF:
ALOGI("%s::HWC_CTL_DUMP_MID_BUF on/off=%d", __func__, val);
exynosHWCControl.dumpMidBuf = (unsigned int)val;
setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- invalidate();
+ onRefresh();
break;
case HWC_CTL_CAPTURE_READBACK:
captureScreenWithReadback(HWC_DISPLAY_PRIMARY);
@@ -581,7 +655,7 @@ void ExynosDevice::setHWCControl(uint32_t display, uint32_t ctrl, int32_t val)
ALOGI("%s::HWC_CTL_DISPLAY_MODE mode=%d", __func__, val);
setDisplayMode((uint32_t)val);
setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- invalidate();
+ onRefresh();
break;
// Support DDI scalser {
case HWC_CTL_DDI_RESOLUTION_CHANGE:
@@ -607,7 +681,7 @@ void ExynosDevice::setHWCControl(uint32_t display, uint32_t ctrl, int32_t val)
exynosDisplay->setDDIScalerEnable(width, height);
}
setGeometryChanged(GEOMETRY_DISPLAY_RESOLUTION_CHANGED);
- invalidate();
+ onRefresh();
break;
// } Support DDI scaler
case HWC_CTL_ENABLE_COMPOSITION_CROP:
@@ -625,7 +699,7 @@ void ExynosDevice::setHWCControl(uint32_t display, uint32_t ctrl, int32_t val)
exynosDisplay->setHWCControl(ctrl, val);
}
setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- invalidate();
+ onRefresh();
break;
case HWC_CTL_DYNAMIC_RECOMP:
ALOGI("%s::HWC_CTL_DYNAMIC_RECOMP on/off = %d", __func__, val);
@@ -772,16 +846,14 @@ bool ExynosDevice::validateFences(ExynosDisplay *display) {
}
if (fenceWarn(display, MAX_FENCE_THRESHOLD)) {
- ALOGE("Fence leak! --");
printLeakFds(display);
saveFenceTrace(display);
return false;
}
if (exynosHWCControl.doFenceFileDump) {
- ALOGE("Fence file dump !");
- if (mFenceLogSize != 0)
- ALOGE("Fence file not empty!");
+ ALOGD("Fence file dump !");
+ if (mFenceLogSize != 0) ALOGD("Fence file not empty!");
saveFenceTrace(display);
exynosHWCControl.doFenceFileDump = false;
}
@@ -921,7 +993,7 @@ void ExynosDevice::captureScreenWithReadback(uint32_t displayType)
}
/* Update screen */
- invalidate();
+ onRefresh();
/* Wait for handling readback */
uint32_t waitPeriod = display->mVsyncPeriod * 3;
@@ -969,7 +1041,7 @@ int32_t ExynosDevice::setDisplayDeviceMode(int32_t display_id, int32_t mode)
mode == static_cast<int32_t>(ext_hwc2_power_mode_t::RESUME)) {
ret = mDisplays[display_id]->setPowerMode(mode);
if (mode == static_cast<int32_t>(ext_hwc2_power_mode_t::RESUME) && ret == HWC2_ERROR_NONE) {
- invalidate();
+ onRefresh();
}
return ret;
} else {
@@ -1067,6 +1139,11 @@ bool ExynosDevice::getLhbmState() {
return false;
}
+PanelCalibrationStatus ExynosDevice::getPanelCalibrationStatus() {
+ auto display = getDisplay(getDisplayId(HWC_DISPLAY_PRIMARY, 0));
+ return display->getPanelCalibrationStatus();
+}
+
uint32_t ExynosDevice::getWindowPlaneNum()
{
/*
@@ -1129,6 +1206,7 @@ int ExynosDevice::setRefreshRateThrottle(const int delayMs) {
int32_t ExynosDevice::registerHwc3Callback(uint32_t descriptor, hwc2_callback_data_t callbackData,
hwc2_function_pointer_t point) {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
mHwc3CallbackInfos[descriptor].callbackData = callbackData;
mHwc3CallbackInfos[descriptor].funcPointer = point;
@@ -1136,6 +1214,7 @@ int32_t ExynosDevice::registerHwc3Callback(uint32_t descriptor, hwc2_callback_da
}
void ExynosDevice::onVsyncIdle(hwc2_display_t displayId) {
+ Mutex::Autolock lock(mDeviceCallbackMutex);
const auto &idleCallback = mHwc3CallbackInfos.find(IComposerCallback::TRANSACTION_onVsyncIdle);
if (idleCallback == mHwc3CallbackInfos.end()) return;
diff --git a/libhwc2.1/libdevice/ExynosDevice.h b/libhwc2.1/libdevice/ExynosDevice.h
index d5a02fe..1dd1145 100644
--- a/libhwc2.1/libdevice/ExynosDevice.h
+++ b/libhwc2.1/libdevice/ExynosDevice.h
@@ -59,6 +59,7 @@
using HbmState = ::aidl::com::google::hardware::pixel::display::HbmState;
using LbeState = ::aidl::com::google::hardware::pixel::display::LbeState;
+using PanelCalibrationStatus = ::aidl::com::google::hardware::pixel::display::PanelCalibrationStatus;
using namespace android;
@@ -185,6 +186,7 @@ class ExynosDevice {
exynos_callback_info_t mCallbackInfos[HWC2_CALLBACK_SEAMLESS_POSSIBLE + 1];
std::map<uint32_t, exynos_callback_info_t> mHwc3CallbackInfos;
+ Mutex mDeviceCallbackMutex;
/**
* Thread variables
@@ -202,7 +204,7 @@ class ExynosDevice {
uint32_t mDisplayMode;
// Variable for fence tracer
- std::map<int, hwc_fence_info_t> mFenceInfos;
+ std::map<int, HwcFenceInfo> mFenceInfos;
/**
* This will be initialized with differnt class
@@ -274,8 +276,13 @@ class ExynosDevice {
*/
int32_t registerCallback (
int32_t descriptor, hwc2_callback_data_t callbackData, hwc2_function_pointer_t point);
-
- void invalidate();
+ bool isCallbackAvailable(int32_t descriptor);
+ void onHotPlug(uint32_t displayId, bool status);
+ void onRefresh();
+ void onVsync(uint32_t displayId, int64_t timestamp);
+ bool onVsync_2_4(uint32_t displayId, int64_t timestamp, uint32_t vsyncPeriod);
+ void onVsyncPeriodTimingChanged(uint32_t displayId,
+ hwc_vsync_period_change_timeline_t *timeline);
void setHWCDebug(unsigned int debug);
uint32_t getHWCDebug();
@@ -335,6 +342,7 @@ class ExynosDevice {
Condition mCaptureCondition;
std::atomic<bool> mIsWaitingReadbackReqDone = false;
void setVBlankOffDelay(int vblankOffDelay);
+ bool isCallbackRegisteredLocked(int32_t descriptor);
public:
bool isLbeSupported();
@@ -350,6 +358,8 @@ class ExynosDevice {
bool isColorCalibratedByDevice();
+ PanelCalibrationStatus getPanelCalibrationStatus();
+
public:
void enterToTUI() { mIsInTUI = true; };
void exitFromTUI() { mIsInTUI = false; };
diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp
index 98256dc..78f65f2 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.cpp
+++ b/libhwc2.1/libdevice/ExynosDisplay.cpp
@@ -1581,7 +1581,7 @@ bool ExynosDisplay::skipStaticLayerChanged(ExynosCompositionInfo& compositionInf
}
void ExynosDisplay::requestLhbm(bool on) {
- mDevice->invalidate();
+ mDevice->onRefresh();
if (mBrightnessController) {
mBrightnessController->processLocalHbm(on);
}
@@ -1800,9 +1800,7 @@ int ExynosDisplay::doExynosComposition() {
mExynosCompositionInfo.setExynosImage(src_img, dst_img);
DISPLAY_LOGD(eDebugFence, "mExynosCompositionInfo acquireFencefd(%d)",
- mExynosCompositionInfo.mAcquireFence);
- // Test..
- // setFenceInfo(mExynosCompositionInfo.mAcquireFence, this, "G2D_DST_ACQ", FENCE_FROM);
+ mExynosCompositionInfo.mAcquireFence);
if ((ret = mExynosCompositionInfo.mM2mMPP->resetDstReleaseFence()) != NO_ERROR)
{
@@ -2384,15 +2382,9 @@ void ExynosDisplay::printDebugInfos(String8 &reason)
{
FILE *pFile = NULL;
struct timeval tv;
- struct tm* localTime;
gettimeofday(&tv, NULL);
- localTime = (struct tm*)localtime((time_t*)&tv.tv_sec);
- reason.appendFormat("errFrameNumber: %" PRId64 " time:%02d-%02d %02d:%02d:%02d.%03lu(%lu)\n",
- mErrorFrameCount,
- localTime->tm_mon+1, localTime->tm_mday,
- localTime->tm_hour, localTime->tm_min,
- localTime->tm_sec, tv.tv_usec/1000,
- ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
+ reason.appendFormat("errFrameNumber: %" PRId64 " time:%s\n", mErrorFrameCount,
+ getLocalTimeStr(tv).string());
ALOGD("%s", reason.string());
if (mErrorFrameCount < HWC_PRINT_FRAME_NUM) {
@@ -2710,8 +2702,8 @@ int ExynosDisplay::deliverWinConfigData() {
mRetireFenceAcquireTime = systemTime();
}
for (size_t i = 0; i < mDpuData.configs.size(); i++) {
- setFenceInfo(mDpuData.configs[i].acq_fence, this,
- FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_DPP, FENCE_TO);
+ setFenceInfo(mDpuData.configs[i].acq_fence, this, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_DPP,
+ HwcFenceDirection::TO);
}
if ((ret = mDisplayInterface->deliverWinConfigData()) < 0) {
@@ -2722,11 +2714,11 @@ int ExynosDisplay::deliverWinConfigData() {
}
for (size_t i = 0; i < mDpuData.configs.size(); i++) {
- setFenceInfo(mDpuData.configs[i].rel_fence, this,
- FENCE_TYPE_SRC_RELEASE, FENCE_IP_DPP, FENCE_FROM);
+ setFenceInfo(mDpuData.configs[i].rel_fence, this, FENCE_TYPE_SRC_RELEASE, FENCE_IP_DPP,
+ HwcFenceDirection::FROM);
}
- setFenceInfo(mDpuData.retire_fence, this,
- FENCE_TYPE_RETIRE, FENCE_IP_DPP, FENCE_FROM);
+ setFenceInfo(mDpuData.retire_fence, this, FENCE_TYPE_RETIRE, FENCE_IP_DPP,
+ HwcFenceDirection::FROM);
}
return ret;
@@ -2829,8 +2821,8 @@ int ExynosDisplay::setReleaseFences() {
if (config.rel_fence > 0) {
release_fd = config.rel_fence;
if (release_fd >= 0) {
- setFenceName(release_fd,
- this, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_DPP, FENCE_FROM, true);
+ setFenceInfo(release_fd, this, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_DPP,
+ HwcFenceDirection::UPDATE, true);
mLayers[i]->mM2mMPP->setDstAcquireFence(release_fd);
} else {
DISPLAY_LOGE("fail to dup, ret(%d, %s)", errno, strerror(errno));
@@ -2907,8 +2899,8 @@ int ExynosDisplay::setReleaseFences() {
mExynosCompositionInfo.mM2mMPP->setDstAcquireFence(-1);
#else
if (config.rel_fence > 0) {
- setFenceName(config.rel_fence,
- this, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_DPP, FENCE_FROM, true);
+ setFenceInfo(config.rel_fence, this, FENCE_TYPE_DST_ACQUIRE, FENCE_IP_DPP,
+ HwcFenceDirection::UPDATE, true);
mExynosCompositionInfo.mM2mMPP->setDstAcquireFence(config.rel_fence);
} else {
mExynosCompositionInfo.mM2mMPP->setDstAcquireFence(-1);
@@ -3460,7 +3452,7 @@ int32_t ExynosDisplay::presentDisplay(int32_t* outRetireFence) {
ret = HWC2_ERROR_NOT_VALIDATED;
}
mRenderingState = RENDERING_STATE_PRESENTED;
- mDevice->invalidate();
+ mDevice->onRefresh();
return ret;
}
@@ -3626,15 +3618,14 @@ int32_t ExynosDisplay::presentDisplay(int32_t* outRetireFence) {
*outRetireFence =
hwcCheckFenceDebug(this, FENCE_TYPE_RETIRE, FENCE_IP_DPP, mDpuData.retire_fence);
#endif
- setFenceInfo(mDpuData.retire_fence, this,
- FENCE_TYPE_RETIRE, FENCE_IP_LAYER, FENCE_TO);
+ setFenceInfo(mDpuData.retire_fence, this, FENCE_TYPE_RETIRE, FENCE_IP_LAYER,
+ HwcFenceDirection::TO);
} else
*outRetireFence = -1;
/* Update last retire fence */
mLastRetireFence = fence_close(mLastRetireFence, this, FENCE_TYPE_RETIRE, FENCE_IP_DPP);
- mLastRetireFence = hwc_dup((*outRetireFence), this, FENCE_TYPE_RETIRE, FENCE_IP_DPP);
- setFenceName(mLastRetireFence, this, FENCE_TYPE_RETIRE, FENCE_IP_DPP, FENCE_DUP, true);
+ mLastRetireFence = hwc_dup((*outRetireFence), this, FENCE_TYPE_RETIRE, FENCE_IP_DPP, true);
setFenceName(mLastRetireFence, FENCE_RETIRE);
increaseMPPDstBufIndex();
@@ -3668,16 +3659,14 @@ int32_t ExynosDisplay::presentDisplay(int32_t* outRetireFence) {
/* All of release fences are tranferred */
for (size_t i=0; i < mLayers.size(); i++) {
- setFenceInfo(mLayers[i]->mReleaseFence, this,
- FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, FENCE_TO);
+ setFenceInfo(mLayers[i]->mReleaseFence, this, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
+ HwcFenceDirection::TO);
}
doPostProcessing();
- if (!mDevice->validateFences(this)){
- String8 errString;
- errString.appendFormat("%s:: validate fence failed. \n", __func__);
- printDebugInfos(errString);
+ if (!mDevice->validateFences(this)) {
+ ALOGE("%s:: validate fence failed.", __func__);
}
mDpuData.reset();
@@ -3721,9 +3710,8 @@ err:
mDpuData.reset();
- if (!mDevice->validateFences(this)){
- errString.appendFormat("%s:: validate fence failed. \n", __func__);
- printDebugInfos(errString);
+ if (!mDevice->validateFences(this)) {
+ ALOGE("%s:: validate fence failed.", __func__);
}
mDisplayInterface->setForcePanic();
@@ -3841,8 +3829,7 @@ int32_t ExynosDisplay::setClientTarget(
}
}
mClientCompositionInfo.setTargetBuffer(this, handle, acquireFence, (android_dataspace)dataspace);
- setFenceInfo(acquireFence, this,
- FENCE_TYPE_SRC_RELEASE, FENCE_IP_FB, FENCE_FROM);
+ setFenceInfo(acquireFence, this, FENCE_TYPE_SRC_RELEASE, FENCE_IP_FB, HwcFenceDirection::FROM);
if (handle) {
mClientCompositionInfo.mCompressed = isAFBCCompressed(handle);
@@ -4094,7 +4081,8 @@ int32_t ExynosDisplay::setActiveConfigWithConstraints(hwc2_config_t config,
mXres, mYres, mVsyncPeriod, mXdpi, mYdpi);
if (mConfigRequestState == hwc_request_state_t::SET_CONFIG_STATE_REQUESTED) {
- DISPLAY_LOGI("%s, previous request config is processing", __func__);
+ DISPLAY_LOGI("%s, previous request config is processing (mDesiredConfig: %d)", __func__,
+ mDesiredConfig);
}
/* Config would be requested on present time */
mConfigRequestState = hwc_request_state_t::SET_CONFIG_STATE_PENDING;
@@ -4201,8 +4189,7 @@ int32_t ExynosDisplay::updateInternalDisplayConfigVariables(
getDisplayAttribute(mActiveConfig, HWC2_ATTRIBUTE_DPI_Y, (int32_t*)&mYdpi);
mHdrFullScrenAreaThreshold = mXres * mYres * kHdrFullScreen;
if (updateVsync) {
- mVsyncPeriod = getDisplayVsyncPeriodFromConfig(mActiveConfig);
- updateBtsVsyncPeriod(mVsyncPeriod, true);
+ resetConfigRequestStateLocked(config);
}
return NO_ERROR;
@@ -4226,11 +4213,12 @@ void ExynosDisplay::updateRefreshRateHint() {
}
/* This function must be called within a mDisplayMutex protection */
-int32_t ExynosDisplay::resetConfigRequestStateLocked() {
- mVsyncPeriod = getDisplayVsyncPeriodFromConfig(mActiveConfig);
+int32_t ExynosDisplay::resetConfigRequestStateLocked(hwc2_config_t config) {
+ ATRACE_CALL();
+
+ mVsyncPeriod = getDisplayVsyncPeriodFromConfig(config);
updateBtsVsyncPeriod(mVsyncPeriod, true);
- DISPLAY_LOGD(eDebugDisplayConfig, "Update mVsyncPeriod %d by mActiveConfig(%d)", mVsyncPeriod,
- mActiveConfig);
+ DISPLAY_LOGD(eDebugDisplayConfig, "Update mVsyncPeriod %d by config(%d)", mVsyncPeriod, config);
updateRefreshRateHint();
@@ -4248,8 +4236,11 @@ int32_t ExynosDisplay::resetConfigRequestStateLocked() {
int32_t ExynosDisplay::updateConfigRequestAppliedTime()
{
- if (mConfigRequestState != hwc_request_state_t::SET_CONFIG_STATE_REQUESTED)
+ if (mConfigRequestState != hwc_request_state_t::SET_CONFIG_STATE_REQUESTED) {
+ DISPLAY_LOGI("%s: mConfigRequestState (%d) is not REQUESTED", __func__,
+ mConfigRequestState);
return NO_ERROR;
+ }
/*
* config change was requested but
@@ -4264,14 +4255,6 @@ int32_t ExynosDisplay::updateConfigRequestAppliedTime()
int32_t ExynosDisplay::updateVsyncAppliedTimeLine(int64_t actualChangeTime)
{
ExynosDevice *dev = mDevice;
- hwc2_callback_data_t vsync_callbackData = nullptr;
- HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED vsync_callbackFunc = nullptr;
- if (dev->mCallbackInfos[HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED].funcPointer != NULL) {
- vsync_callbackData =
- dev->mCallbackInfos[HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED].callbackData;
- vsync_callbackFunc =
- (HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED)dev->mCallbackInfos[HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED].funcPointer;
- }
DISPLAY_LOGD(eDebugDisplayConfig,"Vsync applied time is changed (%" PRId64 "-> %" PRId64 ")",
mVsyncAppliedTimeLine.newVsyncAppliedTimeNanos,
@@ -4291,12 +4274,7 @@ int32_t ExynosDisplay::updateVsyncAppliedTimeLine(int64_t actualChangeTime)
mVsyncAppliedTimeLine.refreshRequired,
mVsyncAppliedTimeLine.newVsyncAppliedTimeNanos);
- if (vsync_callbackFunc != nullptr)
- vsync_callbackFunc(vsync_callbackData, getId(),
- &mVsyncAppliedTimeLine);
- else {
- ALOGD("callback function is null");
- }
+ dev->onVsyncPeriodTimingChanged(getId(), &mVsyncAppliedTimeLine);
return NO_ERROR;
}
@@ -4337,7 +4315,8 @@ int32_t ExynosDisplay::doDisplayConfigPostProcess(ExynosDevice *dev)
needSetActiveConfig = true;
ATRACE_INT("Pending ActiveConfig", 0);
} else {
- DISPLAY_LOGD(eDebugDisplayConfig, "setActiveConfig still pending");
+ DISPLAY_LOGD(eDebugDisplayConfig, "setActiveConfig still pending (mDesiredConfig %d)",
+ mDesiredConfig);
ATRACE_INT("Pending ActiveConfig", mDesiredConfig);
}
@@ -5766,8 +5745,8 @@ void ExynosDisplay::setReadbackBufferInternal(buffer_handle_t buffer,
DISPLAY_LOGE("previous readback release fence is not delivered to display device");
}
if (releaseFence >= 0) {
- setFenceInfo(releaseFence, this, FENCE_TYPE_READBACK_RELEASE,
- FENCE_IP_FB, FENCE_FROM);
+ setFenceInfo(releaseFence, this, FENCE_TYPE_READBACK_RELEASE, FENCE_IP_FB,
+ HwcFenceDirection::FROM);
}
mDpuData.readback_info.rel_fence = releaseFence;
@@ -5808,8 +5787,8 @@ int32_t ExynosDisplay::setReadbackBufferAcqFence(int32_t acqFence) {
* so validateFences should not check this fence
* in presentDisplay so this function sets pendingAllowed parameter.
*/
- setFenceInfo(acqFence, this, FENCE_TYPE_READBACK_ACQUIRE,
- FENCE_IP_DPP, FENCE_FROM, true);
+ setFenceInfo(acqFence, this, FENCE_TYPE_READBACK_ACQUIRE, FENCE_IP_DPP,
+ HwcFenceDirection::FROM, true);
}
return NO_ERROR;
diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h
index 028798e..e31a692 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.h
+++ b/libhwc2.1/libdevice/ExynosDisplay.h
@@ -1101,7 +1101,7 @@ class ExynosDisplay {
bool needNotChangeConfig(hwc2_config_t config);
int32_t updateInternalDisplayConfigVariables(
hwc2_config_t config, bool updateVsync = true);
- int32_t resetConfigRequestStateLocked();
+ int32_t resetConfigRequestStateLocked(hwc2_config_t config);
int32_t updateConfigRequestAppliedTime();
int32_t updateVsyncAppliedTimeLine(int64_t actualChangeTime);
int32_t getDisplayVsyncPeriodInternal(
@@ -1199,6 +1199,10 @@ class ExynosDisplay {
}
virtual void handleDisplayIdleEnter(const uint32_t __unused idleTeRefreshRate) {}
+ virtual PanelCalibrationStatus getPanelCalibrationStatus() {
+ return PanelCalibrationStatus::UNCALIBRATED;
+ }
+
/* getDisplayPreAssignBit support mIndex up to 1.
It supports only dual LCD and 2 external displays */
inline uint32_t getDisplayPreAssignBit() {
@@ -1239,6 +1243,13 @@ class ExynosDisplay {
// is the hint session both enabled and supported
bool usePowerHintSession();
+ void setMinDisplayVsyncPeriod(uint32_t period) { mMinDisplayVsyncPeriod = period; }
+
+ bool isCurrentPeakRefreshRate(void) {
+ return ((mConfigRequestState == hwc_request_state_t::SET_CONFIG_STATE_NONE) &&
+ (mVsyncPeriod == mMinDisplayVsyncPeriod));
+ }
+
private:
bool skipStaticLayerChanged(ExynosCompositionInfo& compositionInfo);
@@ -1253,6 +1264,9 @@ class ExynosDisplay {
static constexpr float kHdrFullScreen = 0.5;
uint32_t mHdrFullScrenAreaThreshold;
+ // vsync period of peak refresh rate
+ uint32_t mMinDisplayVsyncPeriod;
+
/* Display hint to notify power hal */
class PowerHalHintWorker : public Worker {
public:
diff --git a/libhwc2.1/libdevice/ExynosLayer.cpp b/libhwc2.1/libdevice/ExynosLayer.cpp
index b06b093..105437e 100644
--- a/libhwc2.1/libdevice/ExynosLayer.cpp
+++ b/libhwc2.1/libdevice/ExynosLayer.cpp
@@ -967,7 +967,8 @@ void ExynosLayer::setSrcAcquireFence() {
hwc_dup(mPrevAcquireFence, mDisplay,
FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER));
} else if (mAcquireFence != -1) {
- setFenceInfo(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, FENCE_FROM);
+ setFenceInfo(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
+ HwcFenceDirection::FROM);
}
}
diff --git a/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp
index 1836c11..1df6fe9 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp
+++ b/libhwc2.1/libdisplayinterface/ExynosDeviceDrmInterface.cpp
@@ -217,24 +217,16 @@ void ExynosDeviceDrmInterface::ExynosDrmEventHandler::init(ExynosDevice *exynosD
}
void ExynosDeviceDrmInterface::ExynosDrmEventHandler::handleEvent(uint64_t timestamp_us) {
- hwc2_callback_data_t callbackData =
- mExynosDevice->mCallbackInfos[HWC2_CALLBACK_HOTPLUG].callbackData;
- HWC2_PFN_HOTPLUG callbackFunc =
- (HWC2_PFN_HOTPLUG)mExynosDevice->mCallbackInfos[HWC2_CALLBACK_HOTPLUG].funcPointer;
-
- if (callbackData == NULL || callbackFunc == NULL)
- {
- ALOGE("%s:: callback info is NULL", __func__);
+ if (!mExynosDevice->isCallbackAvailable(HWC2_CALLBACK_HOTPLUG)) {
return;
}
for (auto it : mExynosDevice->mDisplays) {
/* Call UpdateModes to get plug status */
uint32_t numConfigs;
- it->getDisplayConfigs(&numConfigs, NULL);
- callbackFunc(callbackData, getDisplayId(it->mType, it->mIndex),
- it->mPlugState ? HWC2_CONNECTION_CONNECTED : HWC2_CONNECTION_DISCONNECTED);
+ it->getDisplayConfigs(&numConfigs, NULL);
+ mExynosDevice->onHotPlug(getDisplayId(it->mType, it->mIndex), it->mPlugState);
}
/* TODO: Check plug status hear or ExynosExternalDisplay::handleHotplugEvent() */
@@ -263,7 +255,7 @@ void ExynosDeviceDrmInterface::ExynosDrmEventHandler::handleTUIEvent() {
} else {
/* Received TUI Exit event */
if (mExynosDevice->isInTUI()) {
- mExynosDevice->invalidate();
+ mExynosDevice->onRefresh();
mExynosDevice->exitFromTUI();
ALOGV("%s:: DRM device out TUI", __func__);
}
diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
index 1ac22e8..82286a1 100644
--- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
+++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp
@@ -690,47 +690,42 @@ int32_t ExynosDisplayDrmInterface::initDrmDevice(DrmDevice *drmDevice)
void ExynosDisplayDrmInterface::Callback(
int display, int64_t timestamp)
{
- Mutex::Autolock lock(mExynosDisplay->getDisplayMutex());
- bool configApplied = mVsyncCallback.Callback(display, timestamp);
-
- if (configApplied) {
- if (mVsyncCallback.getDesiredVsyncPeriod()) {
- mExynosDisplay->resetConfigRequestStateLocked();
- mDrmConnector->set_active_mode(mActiveModeState.mode);
- mVsyncCallback.resetDesiredVsyncPeriod();
- }
+ {
+ Mutex::Autolock lock(mExynosDisplay->getDisplayMutex());
+ bool configApplied = mVsyncCallback.Callback(display, timestamp);
+
+ if (configApplied) {
+ if (mVsyncCallback.getDesiredVsyncPeriod()) {
+ mExynosDisplay->resetConfigRequestStateLocked(mActiveModeState.mode.id());
+ mDrmConnector->set_active_mode(mActiveModeState.mode);
+ mVsyncCallback.resetDesiredVsyncPeriod();
+ }
- /*
- * Disable vsync if vsync config change is done
- */
- if (!mVsyncCallback.getVSyncEnabled()) {
- mDrmVSyncWorker.VSyncControl(false);
- mVsyncCallback.resetVsyncTimeStamp();
+ /*
+ * Disable vsync if vsync config change is done
+ */
+ if (!mVsyncCallback.getVSyncEnabled()) {
+ mDrmVSyncWorker.VSyncControl(false);
+ mVsyncCallback.resetVsyncTimeStamp();
+ }
+ } else {
+ mExynosDisplay->updateConfigRequestAppliedTime();
}
- } else {
- mExynosDisplay->updateConfigRequestAppliedTime();
- }
- if (!mExynosDisplay->mPlugState || !mVsyncCallback.getVSyncEnabled()) {
- return;
+ if (!mExynosDisplay->mPlugState || !mVsyncCallback.getVSyncEnabled()) {
+ return;
+ }
}
ExynosDevice *exynosDevice = mExynosDisplay->mDevice;
- auto vsync_2_4CallbackInfo =
- exynosDevice->mCallbackInfos[HWC2_CALLBACK_VSYNC_2_4];
- if (vsync_2_4CallbackInfo.funcPointer && vsync_2_4CallbackInfo.callbackData) {
- ((HWC2_PFN_VSYNC_2_4)vsync_2_4CallbackInfo.funcPointer)(
- vsync_2_4CallbackInfo.callbackData,
- mExynosDisplay->mDisplayId,
- timestamp, mExynosDisplay->mVsyncPeriod);
+
+ if (exynosDevice->onVsync_2_4(mExynosDisplay->mDisplayId, timestamp,
+ mExynosDisplay->mVsyncPeriod)) {
ATRACE_INT(vsyncPeriodTag, static_cast<int32_t>(mExynosDisplay->mVsyncPeriod));
return;
}
- auto vsyncCallbackInfo = exynosDevice->mCallbackInfos[HWC2_CALLBACK_VSYNC];
- if (vsyncCallbackInfo.funcPointer && vsyncCallbackInfo.callbackData)
- ((HWC2_PFN_VSYNC)vsyncCallbackInfo.funcPointer)(vsyncCallbackInfo.callbackData,
- mExynosDisplay->mDisplayId, timestamp);
+ exynosDevice->onVsync(mExynosDisplay->mDisplayId, timestamp);
}
bool ExynosDisplayDrmInterface::ExynosVsyncCallback::Callback(
@@ -826,8 +821,7 @@ int32_t ExynosDisplayDrmInterface::setVsyncEnabled(uint32_t enabled)
mVsyncCallback.enableVSync(HWC2_VSYNC_ENABLE == enabled);
ExynosDevice *exynosDevice = mExynosDisplay->mDevice;
- auto vsync_2_4CallbackInfo = exynosDevice->mCallbackInfos[HWC2_CALLBACK_VSYNC_2_4];
- if (vsync_2_4CallbackInfo.funcPointer && vsync_2_4CallbackInfo.callbackData) {
+ if (exynosDevice->isCallbackAvailable(HWC2_CALLBACK_VSYNC_2_4)) {
ATRACE_INT(vsyncPeriodTag, 0);
}
@@ -885,6 +879,7 @@ int32_t ExynosDisplayDrmInterface::getDisplayConfigs(
/* key: (width<<32 | height) */
std::map<uint64_t, uint32_t> groupIds;
uint32_t groupId = 0;
+ uint32_t min_vsync_period = UINT_MAX;
for (const DrmMode &mode : mDrmConnector->modes()) {
displayConfigs_t configs;
@@ -905,11 +900,14 @@ int32_t ExynosDisplayDrmInterface::getDisplayConfigs(
configs.Xdpi = mm_width ? (mode.h_display() * kUmPerInch) / mm_width : -1;
// Dots per 1000 inches
configs.Ydpi = mm_height ? (mode.v_display() * kUmPerInch) / mm_height : -1;
+ // find min vsync period
+ if (configs.vsyncPeriod <= min_vsync_period) min_vsync_period = configs.vsyncPeriod;
mExynosDisplay->mDisplayConfigs.insert(std::make_pair(mode.id(), configs));
ALOGD("config group(%d), w(%d), h(%d), vsync(%d), xdpi(%d), ydpi(%d)",
configs.groupId, configs.width, configs.height,
configs.vsyncPeriod, configs.Xdpi, configs.Ydpi);
}
+ mExynosDisplay->setMinDisplayVsyncPeriod(min_vsync_period);
}
uint32_t num_modes = static_cast<uint32_t>(mDrmConnector->modes().size());
@@ -1070,6 +1068,9 @@ int32_t ExynosDisplayDrmInterface::setActiveConfigWithConstraints(
if ((mActiveModeState.blob_id != 0) &&
(mActiveModeState.mode.id() == config)) {
ALOGD("%s:: same mode %d", __func__, config);
+ /* trigger resetConfigRequestStateLocked() */
+ mVsyncCallback.setDesiredVsyncPeriod(nsecsPerSec / mActiveModeState.mode.v_refresh());
+ mDrmVSyncWorker.VSyncControl(true);
return HWC2_ERROR_NONE;
}
diff --git a/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp b/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp
index 8ba3020..39c2e79 100644
--- a/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp
+++ b/libhwc2.1/libexternaldisplay/ExynosExternalDisplay.cpp
@@ -149,12 +149,7 @@ int32_t ExynosExternalDisplay::getActiveConfig(hwc2_config_t* outConfig) {
void ExynosExternalDisplay::hotplug(){
DISPLAY_LOGD(eDebugExternalDisplay, "");
- hwc2_callback_data_t callbackData =
- mDevice->mCallbackInfos[HWC2_CALLBACK_HOTPLUG].callbackData;
- HWC2_PFN_HOTPLUG callbackFunc =
- (HWC2_PFN_HOTPLUG)mDevice->mCallbackInfos[HWC2_CALLBACK_HOTPLUG].funcPointer;
- if (callbackData != NULL && callbackFunc != NULL)
- callbackFunc(callbackData, mDisplayId, mHpdStatus ? HWC2_CONNECTION_CONNECTED : HWC2_CONNECTION_DISCONNECTED);
+ mDevice->onHotPlug(mDisplayId, mHpdStatus);
}
bool ExynosExternalDisplay::handleRotate()
@@ -314,7 +309,7 @@ int32_t ExynosExternalDisplay::presentDisplay(
ret = HWC2_ERROR_NOT_VALIDATED;
}
mRenderingState = RENDERING_STATE_PRESENTED;
- mDevice->invalidate();
+ mDevice->onRefresh();
return ret;
}
@@ -353,7 +348,7 @@ int32_t ExynosExternalDisplay::presentDisplay(
*/
setGeometryChanged(GEOMETRY_DISPLAY_FORCE_VALIDATE);
- mDevice->invalidate();
+ mDevice->onRefresh();
return HWC2_ERROR_NONE;
}
@@ -513,8 +508,7 @@ void ExynosExternalDisplay::handleHotplugEvent()
{
bool hpd_temp = 0;
- if (mDevice->mCallbackInfos[HWC2_CALLBACK_HOTPLUG].callbackData == NULL)
- return;
+ if (!mDevice->isCallbackAvailable(HWC2_CALLBACK_HOTPLUG)) return;
char cablestate_name[MAX_DEV_NAME + 1];
cablestate_name[MAX_DEV_NAME] = '\0';
@@ -550,7 +544,7 @@ void ExynosExternalDisplay::handleHotplugEvent()
closeExternalDisplay();
}
hotplug();
- mDevice->invalidate();
+ mDevice->onRefresh();
}
}
diff --git a/libhwc2.1/libhwcService/ExynosHWCService.cpp b/libhwc2.1/libhwcService/ExynosHWCService.cpp
index 9c09ecb..7974fee 100644
--- a/libhwc2.1/libhwcService/ExynosHWCService.cpp
+++ b/libhwc2.1/libhwcService/ExynosHWCService.cpp
@@ -252,7 +252,7 @@ void ExynosHWCService::enableMPP(uint32_t physicalType, uint32_t physicalIndex,
__func__, physicalType, physicalIndex, logicalIndex, enable);
ExynosResourceManager::enableMPP(physicalType, physicalIndex, logicalIndex, enable);
mHWCCtx->device->setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- mHWCCtx->device->invalidate();
+ mHWCCtx->device->onRefresh();
}
void ExynosHWCService::setScaleDownRatio(uint32_t physicalType,
@@ -262,7 +262,7 @@ void ExynosHWCService::setScaleDownRatio(uint32_t physicalType,
__func__, physicalType, physicalIndex, logicalIndex, scaleDownRatio);
ExynosResourceManager::setScaleDownRatio(physicalType, physicalIndex, logicalIndex, scaleDownRatio);
mHWCCtx->device->setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- mHWCCtx->device->invalidate();
+ mHWCCtx->device->onRefresh();
}
void ExynosHWCService::setLbeCtrl(uint32_t display_id, uint32_t state, uint32_t lux) {
@@ -482,7 +482,7 @@ int32_t ExynosHWCService::setDisplayRCDLayerEnabled(uint32_t displayIndex, bool
auto ret = primaryDisplay->setDebugRCDLayerEnabled(enable);
mHWCCtx->device->setGeometryChanged(GEOMETRY_DEVICE_CONFIG_CHANGED);
- mHWCCtx->device->invalidate();
+ mHWCCtx->device->onRefresh();
return ret;
}
diff --git a/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp b/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp
index 75762fc..60593c8 100644
--- a/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp
+++ b/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp
@@ -15,6 +15,7 @@
*/
#include "ExynosHWCHelper.h"
+#include <android-base/properties.h>
#include <linux/videodev2.h>
#include <linux/videodev2_exynos_media.h>
#include <png.h>
@@ -30,7 +31,6 @@
#include "ExynosLayer.h"
#include "ExynosResourceRestriction.h"
#include "VendorVideoAPI.h"
-#include "android-base/properties.h"
#include "exynos_sync.h"
using vendor::graphics::BufferUsage;
@@ -613,8 +613,7 @@ uint32_t getBytePerPixelOfPrimaryPlane(int format) {
return 0;
}
-void setFenceName(int fenceFd, hwc_fence_type fenceType)
-{
+void setFenceName(int fenceFd, HwcFenceType fenceType) {
if (fenceFd >= 3)
ioctl(fenceFd, SYNC_IOC_FENCE_NAME, fence_names[fenceType]);
else if (fenceFd == -1) {
@@ -753,10 +752,8 @@ int getBufLength(buffer_handle_t handle, uint32_t planerNum, size_t *length, int
return NO_ERROR;
}
-int fence_close(int fence, ExynosDisplay* display,
- hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip) {
- if (display != NULL)
- setFenceInfo(fence, display, type, ip, FENCE_CLOSE);
+int fence_close(int fence, ExynosDisplay* display, HwcFdebugFenceType type, HwcFdebugIpType ip) {
+ if (display != NULL) setFenceInfo(fence, display, type, ip, HwcFenceDirection::CLOSE);
return hwcFdClose(fence);
}
@@ -784,7 +781,7 @@ int hwcFdClose(int fd) {
return -1;
}
-int hwc_dup(int fd, ExynosDisplay* display, hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
+int hwc_dup(int fd, ExynosDisplay* display, HwcFdebugFenceType type, HwcFdebugIpType ip,
bool pendingAllowed) {
int dup_fd = -1;
@@ -802,7 +799,7 @@ int hwc_dup(int fd, ExynosDisplay* display, hwc_fdebug_fence_type type, hwc_fdeb
hwc_print_stack();
}
- setFenceInfo(dup_fd, display, type, ip, FENCE_FROM, pendingAllowed);
+ setFenceInfo(dup_fd, display, type, ip, HwcFenceDirection::DUP, pendingAllowed, fd);
FT_LOGD("duplicated %d from %d", dup_fd, fd);
return dup_fd;
@@ -815,157 +812,95 @@ int hwc_print_stack() {
return 0;
}
-struct tm* getLocalTime(struct timeval tv) {
- return (struct tm*)localtime((time_t*)&tv.tv_sec);
+String8 getLocalTimeStr(struct timeval tv) {
+ struct tm* localTime = (struct tm*)localtime((time_t*)&tv.tv_sec);
+ return String8::format("%02d-%02d %02d:%02d:%02d.%03lu(%lu)", localTime->tm_mon + 1,
+ localTime->tm_mday, localTime->tm_hour, localTime->tm_min,
+ localTime->tm_sec, tv.tv_usec / 1000,
+ ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
}
-void setFenceInfo(uint32_t fd, ExynosDisplay* display, hwc_fdebug_fence_type type,
- hwc_fdebug_ip_type ip, uint32_t direction, bool pendingAllowed) {
+void setFenceInfo(uint32_t fd, ExynosDisplay* display, HwcFdebugFenceType type, HwcFdebugIpType ip,
+ HwcFenceDirection direction, bool pendingAllowed, int32_t dupFrom) {
if (!fence_valid(fd) || display == NULL) return;
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t& info = device->mFenceInfos[fd];
+ HwcFenceInfo& info = device->mFenceInfos[fd];
info.displayId = display->mDisplayId;
- struct timeval tv;
-
- // FIXME: sync_fence_info, sync_pt_info are deprecated
- // HWC guys should fix this.
-#if 0
- if (exynosHWCControl.sysFenceLogging) {
- struct sync_pt_info* pt_info = NULL;
- info.sync_data = NULL;
- if (info.sync_data != NULL) {
- pt_info = sync_pt_info(info.sync_data, pt_info);
- if (pt_info !=NULL) {
- FT_LOGD("real name : %s status : %s pt_obj : %s pt_drv : %s",
- info.sync_data->name, info.sync_data->status==1 ? "Active":"Signaled",
- pt_info->obj_name, pt_info->driver_name);
- } else {
- FT_LOGD("real name : %s status : %d pt_info : %p",
- info.sync_data->name, info.sync_data->status, pt_info);
- }
- sync_fence_info_free(info.sync_data);
- }
- }
-#endif
-
- fenceTrace_t *trace = NULL;
- switch(direction) {
- case FENCE_FROM:
- trace = &info.from;
- info.to.type = FENCE_TYPE_UNDEFINED;
- info.to.ip = FENCE_IP_UNDEFINED;
- info.usage++;
- break;
- case FENCE_TO:
- trace = &info.to;
- info.usage--;
- break;
- case FENCE_DUP:
- trace = &info.dup;
- info.usage++;
- break;
- case FENCE_CLOSE:
- trace = &info.close;
- info.usage--;
- if (info.usage < 0) info.usage = 0;
- break;
- default:
- ALOGE("Fence trace : Undefined direction!");
- break;
+ if (info.leaking) {
+ return;
}
- if (trace != NULL) {
- trace->type = type;
- trace->ip = ip;
- gettimeofday(&trace->time, NULL);
- tv = trace->time;
- trace->curFlag = 1;
- FT_LOGW("FD : %d, direction : %d, type : %d, ip : %d", fd, direction, trace->type, trace->ip);
- // device->fenceTracing.appendFormat("FD : %d, From : %s\n", fd, info.trace.fromName);
+ switch (direction) {
+ case HwcFenceDirection::FROM:
+ info.usage++;
+ break;
+ case HwcFenceDirection::TO:
+ info.usage--;
+ break;
+ case HwcFenceDirection::DUP:
+ info.usage++;
+ info.dupFrom = dupFrom;
+ break;
+ case HwcFenceDirection::CLOSE:
+ info.usage--;
+ if (info.usage < 0) info.usage = 0;
+ break;
+ case HwcFenceDirection::UPDATE:
+ break;
+ default:
+ ALOGE("Fence trace : Undefined direction!");
+ break;
}
-#if 0 // To be used ?
- struct tm* localTime = getLocalTime(tv);
- device->fenceTracing.appendFormat("usage : %d, time:%02d-%02d %02d:%02d:%02d.%03lu(%lu)\n", info.usage,
- localTime->tm_mon+1, localTime->tm_mday,
- localTime->tm_hour, localTime->tm_min,
- localTime->tm_sec, tv.tv_usec/1000,
- ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
-#endif
-
- // Fence's usage count shuld be zero at end of frame(present done).
- // This flag means usage count of the fence can be pended over frame.
- info.pendingAllowed = pendingAllowed;
-
- info.last_dir = direction;
-
if (info.usage == 0) {
device->mFenceInfos.erase(fd);
+ return;
} else if (info.usage < 0) {
ALOGE("%s : Invalid negative usage (%d) for Fence FD:%d", __func__, info.usage, fd);
printLastFenceInfo(fd, display);
}
-}
-void printLastFenceInfo(uint32_t fd, ExynosDisplay* display) {
+ HwcFenceTrace trace = {.direction = direction, .type = type, .ip = ip, .time = {0, 0}};
+
+ gettimeofday(&trace.time, NULL);
- struct timeval tv;
+ info.traces.push_back(trace);
+ FT_LOGW("FD : %d, direction : %d, type : %d, ip : %d", fd, direction, type, ip);
+
+ // Fence's usage count shuld be zero at end of frame(present done).
+ // This flag means usage count of the fence can be pended over frame.
+ info.pendingAllowed = pendingAllowed;
+}
+
+void printLastFenceInfo(uint32_t fd, ExynosDisplay* display) {
if (!fence_valid(fd)) return;
ExynosDevice* device = display->mDevice;
auto it = device->mFenceInfos.find(fd);
if (it == device->mFenceInfos.end()) return;
- hwc_fence_info_t& info = it->second;
+ HwcFenceInfo& info = it->second;
FT_LOGD("---- Fence FD : %d, Display(%d) ----", fd, info.displayId);
+ FT_LOGD("usage: %d, dupFrom: %d, pendingAllowed: %d, leaking: %d", info.usage, info.dupFrom,
+ info.pendingAllowed, info.leaking);
- fenceTrace_t *trace = NULL;
-
- switch (info.last_dir) {
- case FENCE_FROM:
- trace = &info.from;
- break;
- case FENCE_TO:
- trace = &info.to;
- break;
- case FENCE_DUP:
- trace = &info.dup;
- break;
- case FENCE_CLOSE:
- trace = &info.close;
- break;
- default:
- ALOGE("Fence trace : Undefined direction!");
- break;
- }
-
- if (trace != NULL) {
- FT_LOGD("Last state : %d, type(%d), ip(%d)", info.last_dir, trace->type, trace->ip);
- tv = info.from.time;
+ for (const auto& trace : info.traces) {
+ FT_LOGD("> dir: %d, type: %d, ip: %d, time:%s", trace.direction, trace.type, trace.ip,
+ getLocalTimeStr(trace.time).string());
}
-
- FT_LOGD("from : %d, %d (cur : %d), to : %d, %d (cur : %d), hwc_dup : %d, %d (cur : "
- "%d),hwc_close : %d, %d (cur : %d)",
- info.from.type, info.from.ip, info.from.curFlag, info.to.type, info.to.ip,
- info.to.curFlag, info.dup.type, info.dup.ip, info.dup.curFlag, info.close.type,
- info.close.ip, info.close.curFlag);
-
- struct tm* localTime = getLocalTime(tv);
-
- FT_LOGD("usage : %d, time:%02d-%02d %02d:%02d:%02d.%03lu(%lu)", info.usage,
- localTime->tm_mon + 1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min,
- localTime->tm_sec, tv.tv_usec / 1000, ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
}
-void dumpFenceInfo(ExynosDisplay* display, int32_t __unused depth) {
+void dumpFenceInfo(ExynosDisplay* display, int32_t count) {
ExynosDevice* device = display->mDevice;
- FT_LOGD("Dump fence ++");
+ FT_LOGD("Dump fence (up to %d fences) ++", count);
for (const auto& [fd, info] : device->mFenceInfos) {
- if (!info.pendingAllowed) printLastFenceInfo(fd, display);
+ if (info.pendingAllowed) continue;
+ if (count-- <= 0) break;
+ printLastFenceInfo(fd, display);
}
FT_LOGD("Dump fence --");
}
@@ -979,6 +914,7 @@ void printLeakFds(ExynosDisplay* display) {
int cnt = 0;
for (const auto& [fd, info] : fenceInfos) {
+ if (!info.leaking) continue;
if (info.usage * sign > 0) {
errString.appendFormat("%d,", fd);
if ((++cnt % 10) == 0) {
@@ -1018,32 +954,17 @@ void dumpNCheckLeak(ExynosDisplay* display, int32_t __unused depth) {
bool fenceWarn(ExynosDisplay* display, uint32_t threshold) {
ExynosDevice* device = display->mDevice;
- uint32_t cnt = device->mFenceInfos.size(), r_cnt = 0;
-
- // FIXME: sync_fence_info() is deprecated
- // HWC guys should fix this.
-#if 0
- if (exynosHWCControl.sysFenceLogging) {
- for (int i=3; i < MAX_FD_NUM; i++){
- struct sync_fence_info_data* data = nullptr;
- data = NULL; //sync_fence_info(i);
- if (data != NULL) {
- r_cnt++;
- sync_fence_info_free(data);
- }
- }
- }
-#endif
-
- if ((cnt>threshold) || (exynosHWCControl.fenceTracer > 0))
- dumpFenceInfo(display, 0);
-
- if (r_cnt>threshold)
- ALOGE("Fence leak somewhare!!");
+ uint32_t cnt = device->mFenceInfos.size();
- FT_LOGD("fence hwc : %d, real : %d", cnt, r_cnt);
+ if (cnt > threshold) {
+ ALOGE("Fence leak! -- the number of fences(%d) exceeds threshold(%d)", cnt, threshold);
+ int priv = exynosHWCControl.fenceTracer;
+ exynosHWCControl.fenceTracer = 3;
+ dumpFenceInfo(display, 10);
+ exynosHWCControl.fenceTracer = priv;
+ }
- return (cnt>threshold) ? true : false;
+ return (cnt > threshold);
}
bool validateFencePerFrame(ExynosDisplay* display) {
@@ -1068,47 +989,6 @@ bool validateFencePerFrame(ExynosDisplay* display) {
return ret;
}
-void setFenceName(uint32_t fd, ExynosDisplay *display,
- hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
- uint32_t direction, bool pendingAllowed) {
-
- ExynosDevice* device = display->mDevice;
- if (!fence_valid(fd) || device == NULL) return;
-
- auto it = device->mFenceInfos.find(fd);
- if (it == device->mFenceInfos.end()) return;
-
- hwc_fence_info_t& info = it->second;
- info.displayId = display->mDisplayId;
- fenceTrace_t *trace = NULL;
-
- switch(direction) {
- case FENCE_FROM:
- trace = &info.from;
- break;
- case FENCE_TO:
- trace = &info.to;
- break;
- case FENCE_DUP:
- trace = &info.dup;
- break;
- case FENCE_CLOSE:
- trace = &info.close;
- break;
- default:
- ALOGE("Fence trace : Undefined direction!");
- break;
- }
-
- if (trace != NULL) {
- trace->type = type;
- trace->ip = ip;
- FT_LOGD("FD : %d, direction : %d, type(%d), ip(%d) (changed)", fd, direction, type, ip);
- }
-
- info.pendingAllowed = pendingAllowed;
-}
-
String8 getMPPStr(int typeId) {
if (typeId < MPP_DPP_NUM){
int cnt = sizeof(AVAILABLE_OTF_MPP_UNITS)/sizeof(exynos_mpp_t);
diff --git a/libhwc2.1/libhwchelper/ExynosHWCHelper.h b/libhwc2.1/libhwchelper/ExynosHWCHelper.h
index 69d9fe1..6fb9ea5 100644
--- a/libhwc2.1/libhwchelper/ExynosHWCHelper.h
+++ b/libhwc2.1/libhwchelper/ExynosHWCHelper.h
@@ -21,6 +21,7 @@
#include <utils/String8.h>
#include <fstream>
+#include <list>
#include <optional>
#include <sstream>
#include <string>
@@ -258,7 +259,7 @@ const format_description_t exynos_format_desc[] = {
constexpr size_t FORMAT_MAX_CNT = sizeof(exynos_format_desc) / sizeof(format_description);
-typedef enum hwc_fdebug_fence_type_t {
+enum HwcFdebugFenceType {
FENCE_TYPE_SRC_RELEASE = 1,
FENCE_TYPE_SRC_ACQUIRE = 2,
FENCE_TYPE_DST_RELEASE = 3,
@@ -271,9 +272,9 @@ typedef enum hwc_fdebug_fence_type_t {
FENCE_TYPE_READBACK_RELEASE = 10,
FENCE_TYPE_ALL = 11,
FENCE_TYPE_UNDEFINED = 100
-} hwc_fdebug_fence_type;
+};
-typedef enum hwc_fdebug_ip_type_t {
+enum HwcFdebugIpType {
FENCE_IP_DPP = 0,
FENCE_IP_MSC = 1,
FENCE_IP_G2D = 2,
@@ -281,30 +282,30 @@ typedef enum hwc_fdebug_ip_type_t {
FENCE_IP_LAYER = 4,
FENCE_IP_ALL = 5,
FENCE_IP_UNDEFINED = 100
-} hwc_fdebug_ip_type;
-
-typedef enum hwc_fence_type_t {
- FENCE_LAYER_RELEASE_DPP = 0,
- FENCE_LAYER_RELEASE_MPP = 1,
- FENCE_LAYER_RELEASE_MSC = 2,
- FENCE_LAYER_RELEASE_G2D = 3,
- FENCE_DPP_HW_STATE = 4,
- FENCE_MSC_HW_STATE = 5,
- FENCE_G2D_HW_STATE = 6,
- FENCE_MSC_SRC_LAYER = 7,
- FENCE_G2D_SRC_LAYER = 8,
- FENCE_MPP_DST_DPP = 9,
- FENCE_MSC_DST_DPP = 10,
- FENCE_G2D_DST_DPP = 11,
- FENCE_DPP_SRC_MPP = 12,
- FENCE_DPP_SRC_MSC = 13,
- FENCE_DPP_SRC_G2D = 14,
- FENCE_DPP_SRC_LAYER = 15,
- FENCE_MPP_FREE_BUF_ACQUIRE = 16,
- FENCE_MPP_FREE_BUF_RELEASE = 17,
- FENCE_RETIRE = 18,
+};
+
+enum HwcFenceType {
+ FENCE_LAYER_RELEASE_DPP = 0,
+ FENCE_LAYER_RELEASE_MPP = 1,
+ FENCE_LAYER_RELEASE_MSC = 2,
+ FENCE_LAYER_RELEASE_G2D = 3,
+ FENCE_DPP_HW_STATE = 4,
+ FENCE_MSC_HW_STATE = 5,
+ FENCE_G2D_HW_STATE = 6,
+ FENCE_MSC_SRC_LAYER = 7,
+ FENCE_G2D_SRC_LAYER = 8,
+ FENCE_MPP_DST_DPP = 9,
+ FENCE_MSC_DST_DPP = 10,
+ FENCE_G2D_DST_DPP = 11,
+ FENCE_DPP_SRC_MPP = 12,
+ FENCE_DPP_SRC_MSC = 13,
+ FENCE_DPP_SRC_G2D = 14,
+ FENCE_DPP_SRC_LAYER = 15,
+ FENCE_MPP_FREE_BUF_ACQUIRE = 16,
+ FENCE_MPP_FREE_BUF_RELEASE = 17,
+ FENCE_RETIRE = 18,
FENCE_MAX
-} hwc_fence_type;
+};
enum {
EXYNOS_ERROR_NONE = 0,
@@ -446,12 +447,11 @@ uint32_t getBufferNumOfFormat(int format, uint32_t compressType);
uint32_t getPlaneNumOfFormat(int format, uint32_t compressType);
uint32_t getBytePerPixelOfPrimaryPlane(int format);
-int fence_close(int fence, ExynosDisplay* display,
- hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip);
+int fence_close(int fence, ExynosDisplay *display, HwcFdebugFenceType type, HwcFdebugIpType ip);
bool fence_valid(int fence);
int hwcFdClose(int fd);
-int hwc_dup(int fd, ExynosDisplay *display, hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
+int hwc_dup(int fd, ExynosDisplay *display, HwcFdebugFenceType type, HwcFdebugIpType ip,
bool pendingAllowed = false);
int hwc_print_stack();
@@ -482,37 +482,29 @@ inline T pixel_align(const T x, const uint32_t a) {
uint32_t getExynosBufferYLength(uint32_t width, uint32_t height, int format);
int getBufLength(buffer_handle_t handle, uint32_t planer_num, size_t *length, int format, uint32_t width, uint32_t height);
-//class hwc_fence_info(sync_fence_info_data* data, sync_pt_info* info) {
-struct tm* getHwcFenceTime();
-
-enum {
- FENCE_FROM = 0,
- FENCE_TO,
- FENCE_DUP,
- FENCE_CLOSE,
+enum class HwcFenceDirection {
+ FROM = 0,
+ TO,
+ DUP,
+ CLOSE,
+ UPDATE,
};
-typedef struct fenceTrace {
- hwc_fdebug_fence_type type = FENCE_TYPE_UNDEFINED;
- hwc_fdebug_ip_type ip = FENCE_IP_UNDEFINED;
+struct HwcFenceTrace {
+ HwcFenceDirection direction = HwcFenceDirection::FROM;
+ HwcFdebugFenceType type = FENCE_TYPE_UNDEFINED;
+ HwcFdebugIpType ip = FENCE_IP_UNDEFINED;
struct timeval time = {0, 0};
- int32_t curFlag = 0;
-} fenceTrace_t;
+};
-typedef struct hwc_fence_info {
+struct HwcFenceInfo {
uint32_t displayId = HWC_DISPLAY_PRIMARY;
- struct sync_fence_info_data *sync_data = nullptr;
- struct sync_pt_info *pt_info = nullptr;
- fenceTrace_t from = {};
- fenceTrace_t to = {};
- fenceTrace_t dup = {};
- fenceTrace_t close = {};
int32_t usage = 0;
- int32_t curFlag = 0;
- uint32_t last_dir = 0;
+ int32_t dupFrom = -1;
bool pendingAllowed = false;
bool leaking = false;
-} hwc_fence_info_t;
+ std::list<HwcFenceTrace> traces = {};
+};
class funcReturnCallback {
public:
@@ -522,15 +514,13 @@ class funcReturnCallback {
const std::function<void(void)> mCb;
};
-void setFenceName(int fenceFd, hwc_fence_type fenceType);
-void setFenceName(uint32_t fd, ExynosDisplay *display,
- hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
- uint32_t direction, bool pendingAllowed = false);
-void setFenceInfo(uint32_t fd, ExynosDisplay *display,
- hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
- uint32_t direction, bool pendingAllowed = false);
+String8 getLocalTimeStr(struct timeval tv);
+
+void setFenceName(int fenceFd, HwcFenceType fenceType);
+void setFenceInfo(uint32_t fd, ExynosDisplay *display, HwcFdebugFenceType type, HwcFdebugIpType ip,
+ HwcFenceDirection direction, bool pendingAllowed = false, int32_t dupFrom = -1);
void printLastFenceInfo(uint32_t fd, ExynosDisplay *display);
-void dumpFenceInfo(ExynosDisplay *display, int32_t __unused depth);
+void dumpFenceInfo(ExynosDisplay *display, int32_t count);
bool fenceWarn(ExynosDisplay *display, uint32_t threshold);
void printLeakFds(ExynosDisplay *display);
bool validateFencePerFrame(ExynosDisplay *display);
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
index 35253a9..633b1d7 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
@@ -116,10 +116,9 @@ ExynosPrimaryDisplay::ExynosPrimaryDisplay(uint32_t index, ExynosDevice *device)
mEarlyWakeupDispFd = fopen(EARLY_WAKUP_NODE_0_BASE, "w");
if (mEarlyWakeupDispFd == nullptr)
ALOGE("open %s failed! %s", EARLY_WAKUP_NODE_0_BASE, strerror(errno));
- mBrightnessController =
- std::make_unique<BrightnessController>(mIndex,
- [this]() { mDevice->invalidate(); },
- [this]() { updatePresentColorConversionInfo(); });
+ mBrightnessController = std::make_unique<BrightnessController>(
+ mIndex, [this]() { mDevice->onRefresh(); },
+ [this]() { updatePresentColorConversionInfo(); });
}
ExynosPrimaryDisplay::~ExynosPrimaryDisplay()
@@ -496,6 +495,22 @@ int32_t ExynosPrimaryDisplay::SetCurrentPanelGammaSource(const DisplayType type,
int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
ATRACE_CALL();
+ if (enabled) {
+ ATRACE_NAME("wait for peak refresh rate");
+ for (int32_t i = 0; i <= kLhbmWaitForPeakRefreshRate; i++) {
+ if (!isCurrentPeakRefreshRate()) {
+ if (i == kLhbmWaitForPeakRefreshRate) {
+ ALOGW("setLhbmState(on) wait for peak refresh rate timeout !");
+ return TIMED_OUT;
+ }
+ usleep(mVsyncPeriod / 1000 + 1);
+ } else {
+ ALOGI_IF(i, "waited %d vsync to reach peak refresh rate", i);
+ break;
+ }
+ }
+ }
+
requestLhbm(enabled);
ALOGI("setLhbmState =%d", enabled);
@@ -511,7 +526,7 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) {
mDisplayInterface->waitVBlank();
ATRACE_NAME("frames to reach LHBM peak brightness");
for (int32_t i = mFramesToReachLhbmPeakBrightness; i > 0; i--) {
- mDevice->invalidate();
+ mDevice->onRefresh();
mDisplayInterface->waitVBlank();
}
}
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
index e544749..c4d79ea 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h
@@ -103,6 +103,8 @@ class ExynosPrimaryDisplay : public ExynosDisplay {
bool mLhbmOn;
bool mLhbmChanged;
int32_t mFramesToReachLhbmPeakBrightness;
+ // wait num of vsync periods for peak refresh rate
+ static constexpr uint32_t kLhbmWaitForPeakRefreshRate = 10;
std::mutex lhbm_mutex_;
std::condition_variable lhbm_cond_;
diff --git a/libhwc2.1/libresource/ExynosMPP.cpp b/libhwc2.1/libresource/ExynosMPP.cpp
index 09c937d..740cec7 100644
--- a/libhwc2.1/libresource/ExynosMPP.cpp
+++ b/libhwc2.1/libresource/ExynosMPP.cpp
@@ -1239,12 +1239,12 @@ int32_t ExynosMPP::setupLayer(exynos_mpp_img_info *srcImgInfo, struct exynos_ima
if (mPhysicalType == MPP_G2D) {
setFenceName(srcImgInfo->acrylicAcquireFenceFd, FENCE_G2D_SRC_LAYER);
- setFenceInfo(srcImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
- FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_G2D, FENCE_TO);
+ setFenceInfo(srcImgInfo->acrylicAcquireFenceFd, mAssignedDisplay, FENCE_TYPE_SRC_ACQUIRE,
+ FENCE_IP_G2D, HwcFenceDirection::TO);
} else if (mPhysicalType == MPP_MSC) {
setFenceName(srcImgInfo->acrylicAcquireFenceFd, FENCE_MSC_SRC_LAYER);
- setFenceInfo(srcImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
- FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_MSC, FENCE_TO);
+ setFenceInfo(srcImgInfo->acrylicAcquireFenceFd, mAssignedDisplay, FENCE_TYPE_SRC_ACQUIRE,
+ FENCE_IP_MSC, HwcFenceDirection::TO);
} else {
MPP_LOGE("%s:: invalid mPhysicalType(%d)", __func__, mPhysicalType);
}
@@ -1367,13 +1367,13 @@ int32_t ExynosMPP::setupDst(exynos_mpp_img_info *dstImgInfo)
if (mPhysicalType == MPP_G2D) {
setFenceName(dstImgInfo->acrylicAcquireFenceFd, FENCE_G2D_DST_DPP);
/* Might be closed next frame */
- setFenceInfo(dstImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
- FENCE_TYPE_DST_ACQUIRE, FENCE_IP_G2D, FENCE_TO);
+ setFenceInfo(dstImgInfo->acrylicAcquireFenceFd, mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE,
+ FENCE_IP_G2D, HwcFenceDirection::TO);
} else if (mPhysicalType == MPP_MSC) {
setFenceName(dstImgInfo->acrylicAcquireFenceFd, FENCE_MSC_DST_DPP);
/* Might be closed next frame */
- setFenceInfo(dstImgInfo->acrylicAcquireFenceFd, mAssignedDisplay,
- FENCE_TYPE_DST_ACQUIRE, FENCE_IP_MSC, FENCE_TO);
+ setFenceInfo(dstImgInfo->acrylicAcquireFenceFd, mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE,
+ FENCE_IP_MSC, HwcFenceDirection::TO);
} else {
MPP_LOGE("%s:: invalid mPhysicalType(%d)", __func__, mPhysicalType);
}
@@ -1512,23 +1512,23 @@ int32_t ExynosMPP::doPostProcessingInternal()
// set fence informations from acryl
if (mPhysicalType == MPP_G2D) {
- setFenceInfo(releaseFences[dstBufIdx], mAssignedDisplay,
- FENCE_TYPE_DST_ACQUIRE, FENCE_IP_G2D, FENCE_FROM);
+ setFenceInfo(releaseFences[dstBufIdx], mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE,
+ FENCE_IP_G2D, HwcFenceDirection::FROM);
if (usingFenceCnt > 1) {
for(size_t i = 0; i < sourceNum; i++) {
// TODO DPU release fence is tranferred to m2mMPP's source layer fence
- setFenceInfo(releaseFences[i], mAssignedDisplay,
- FENCE_TYPE_SRC_RELEASE, FENCE_IP_G2D, FENCE_FROM);
+ setFenceInfo(releaseFences[i], mAssignedDisplay, FENCE_TYPE_SRC_RELEASE,
+ FENCE_IP_G2D, HwcFenceDirection::FROM);
}
}
} else if (mPhysicalType == MPP_MSC) {
- setFenceInfo(releaseFences[dstBufIdx], mAssignedDisplay,
- FENCE_TYPE_DST_ACQUIRE, FENCE_IP_MSC, FENCE_FROM);
+ setFenceInfo(releaseFences[dstBufIdx], mAssignedDisplay, FENCE_TYPE_DST_ACQUIRE,
+ FENCE_IP_MSC, HwcFenceDirection::FROM);
if (usingFenceCnt > 1) {
for(size_t i = 0; i < sourceNum; i++) {
// TODO DPU release fence is tranferred to m2mMPP's source layer fence
- setFenceInfo(releaseFences[i], mAssignedDisplay,
- FENCE_TYPE_SRC_RELEASE, FENCE_IP_MSC, FENCE_FROM);
+ setFenceInfo(releaseFences[i], mAssignedDisplay, FENCE_TYPE_SRC_RELEASE,
+ FENCE_IP_MSC, HwcFenceDirection::FROM);
}
}
} else {
diff --git a/libhwc2.1/libvirtualdisplay/ExynosVirtualDisplay.cpp b/libhwc2.1/libvirtualdisplay/ExynosVirtualDisplay.cpp
index a9cadc3..d6ce85f 100644
--- a/libhwc2.1/libvirtualdisplay/ExynosVirtualDisplay.cpp
+++ b/libhwc2.1/libvirtualdisplay/ExynosVirtualDisplay.cpp
@@ -348,7 +348,8 @@ int ExynosVirtualDisplay::setReleaseFences()
ret = ExynosDisplay::setReleaseFences();
mOutputBufferReleaseFenceFd = hwcCheckFenceDebug(this, FENCE_TYPE_RETIRE, FENCE_IP_G2D, mExynosCompositionInfo.mAcquireFence);
- setFenceInfo(mExynosCompositionInfo.mAcquireFence, this, FENCE_TYPE_RETIRE, FENCE_IP_G2D, FENCE_TO);
+ setFenceInfo(mExynosCompositionInfo.mAcquireFence, this, FENCE_TYPE_RETIRE, FENCE_IP_G2D,
+ HwcFenceDirection::TO);
mExynosCompositionInfo.mAcquireFence = -1;
/* mClientCompositionInfo.mAcquireFence is delivered to G2D */
mClientCompositionInfo.mAcquireFence = -1;
@@ -505,12 +506,14 @@ void ExynosVirtualDisplay::handleAcquireFence()
if (layer->mValidateCompositionType == HWC2_COMPOSITION_DEVICE ||
layer->mValidateCompositionType == HWC2_COMPOSITION_EXYNOS) {
layer->mReleaseFence = layer->mAcquireFence;
- setFenceInfo(layer->mAcquireFence, this, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, FENCE_TO);
+ setFenceInfo(layer->mAcquireFence, this, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
+ HwcFenceDirection::TO);
layer->mAcquireFence = -1;
}
}
mClientCompositionInfo.mReleaseFence = mClientCompositionInfo.mAcquireFence;
- setFenceInfo(mClientCompositionInfo.mAcquireFence, this, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_FB, FENCE_TO);
+ setFenceInfo(mClientCompositionInfo.mAcquireFence, this, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_FB,
+ HwcFenceDirection::TO);
mClientCompositionInfo.mAcquireFence = -1;
mOutputBufferReleaseFenceFd = mOutputBufferAcquireFenceFd;
diff --git a/libhwc2.1/pixel-display-default.xml b/libhwc2.1/pixel-display-default.xml
index 31c569e..fc10d6a 100644
--- a/libhwc2.1/pixel-display-default.xml
+++ b/libhwc2.1/pixel-display-default.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>com.google.hardware.pixel.display</name>
- <version>4</version>
+ <version>6</version>
<fqname>IDisplay/default</fqname>
</hal>
</manifest>
diff --git a/libhwc2.1/pixel-display.cpp b/libhwc2.1/pixel-display.cpp
index 409cfe0..629a137 100644
--- a/libhwc2.1/pixel-display.cpp
+++ b/libhwc2.1/pixel-display.cpp
@@ -162,6 +162,21 @@ ndk::ScopedAStatus Display::setRefreshRateThrottle(int delayMs, int *_aidl_retur
}
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+
+ndk::ScopedAStatus Display::histogramSample(const RoiRect &roi, const Weight &weight,
+ HistogramPos pos, Priority pri,
+ std::vector<char16_t> *histogrambuffer,
+ HistogramErrorCode *_aidl_return) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Display::getPanelCalibrationStatus(PanelCalibrationStatus *_aidl_return){
+ if (mDevice) {
+ *_aidl_return = mDevice->getPanelCalibrationStatus();
+ return ndk::ScopedAStatus::ok();
+ }
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
} // namespace display
} // namespace pixel
} // namespace hardware
diff --git a/libhwc2.1/pixel-display.h b/libhwc2.1/pixel-display.h
index f0fd627..4ca69d7 100644
--- a/libhwc2.1/pixel-display.h
+++ b/libhwc2.1/pixel-display.h
@@ -28,6 +28,11 @@ namespace pixel {
namespace display {
using aidl::android::hardware::common::NativeHandle;
+using RoiRect = ::aidl::android::hardware::graphics::common::Rect;
+using Weight = ::aidl::com::google::hardware::pixel::display::Weight;
+using HistogramPos = ::aidl::com::google::hardware::pixel::display::HistogramPos;
+using Priority = ::aidl::com::google::hardware::pixel::display::Priority;
+using HistogramErrorCode = ::aidl::com::google::hardware::pixel::display::HistogramErrorCode;
// Default implementation
class Display : public BnDisplay {
@@ -49,6 +54,10 @@ public:
int *_aidl_return) override;
ndk::ScopedAStatus setMinIdleRefreshRate(int fps, int *_aidl_return) override;
ndk::ScopedAStatus setRefreshRateThrottle(int delayMs, int *_aidl_return) override;
+ ndk::ScopedAStatus histogramSample(const RoiRect &roi, const Weight &weight, HistogramPos pos,
+ Priority pri, std::vector<char16_t> *histogrambuffer,
+ HistogramErrorCode *_aidl_return) override;
+ ndk::ScopedAStatus getPanelCalibrationStatus(PanelCalibrationStatus *_aidl_return) override;
private:
ExynosDevice *mDevice = nullptr;