summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libhwc2.1/ExynosHWCDebug.cpp9
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.cpp8
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.h3
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.cpp5
-rw-r--r--libhwc2.1/libhwchelper/ExynosHWCHelper.cpp260
-rw-r--r--libhwc2.1/libhwchelper/ExynosHWCHelper.h32
6 files changed, 127 insertions, 190 deletions
diff --git a/libhwc2.1/ExynosHWCDebug.cpp b/libhwc2.1/ExynosHWCDebug.cpp
index e3e3fe8..982a54d 100644
--- a/libhwc2.1/ExynosHWCDebug.cpp
+++ b/libhwc2.1/ExynosHWCDebug.cpp
@@ -109,17 +109,14 @@ int32_t saveFenceTrace(ExynosDisplay *display) {
struct timeval tv;
ExynosDevice *device = display->mDevice;
- hwc_fence_info_t* _info = device->mFenceInfo;
if (device != NULL) {
- for(int i=0; i<1024;i ++){
-
+ for (const auto &[i, info] : device->mFenceInfos) {
+#if 0
bool sysFdOpen = false;
- hwc_fence_info_t info = _info[i];
// FIXME: sync_fence_info and sync_pt_info are deprecated
// HWC guys should fix this
-#if 0
struct sync_pt_info* pt_info = NULL;
info.sync_data = sync_fence_info(i);
if (info.sync_data != NULL) {
@@ -137,9 +134,9 @@ int32_t saveFenceTrace(ExynosDisplay *display) {
sysFdOpen = true;
sync_fence_info_free(info.sync_data);
}
-#endif
if ((info.usage == 0) && !sysFdOpen) continue;
+#endif
saveString.appendFormat("\n-- FD hwc : %d, usage %d\n", i, info.usage);
diff --git a/libhwc2.1/libdevice/ExynosDevice.cpp b/libhwc2.1/libdevice/ExynosDevice.cpp
index bb9743a..afcb3ec 100644
--- a/libhwc2.1/libdevice/ExynosDevice.cpp
+++ b/libhwc2.1/libdevice/ExynosDevice.cpp
@@ -764,18 +764,14 @@ bool ExynosDevice::canSkipValidate()
bool ExynosDevice::validateFences(ExynosDisplay *display) {
if (!validateFencePerFrame(display)) {
- String8 errString;
- errString.appendFormat("You should doubt fence leak!\n");
- ALOGE("%s", errString.string());
+ ALOGE("You should doubt fence leak!");
saveFenceTrace(display);
return false;
}
if (fenceWarn(display, MAX_FENCE_THRESHOLD)) {
- String8 errString;
- errString.appendFormat("Fence leak!\n");
- printLeakFds(display);
ALOGE("Fence leak! --");
+ printLeakFds(display);
saveFenceTrace(display);
return false;
}
diff --git a/libhwc2.1/libdevice/ExynosDevice.h b/libhwc2.1/libdevice/ExynosDevice.h
index 56c58d3..e206024 100644
--- a/libhwc2.1/libdevice/ExynosDevice.h
+++ b/libhwc2.1/libdevice/ExynosDevice.h
@@ -32,6 +32,7 @@
#include <utils/Vector.h>
#include <atomic>
+#include <map>
#include <thread>
#include "ExynosHWC.h"
@@ -199,7 +200,7 @@ class ExynosDevice {
uint32_t mDisplayMode;
// Variable for fence tracer
- hwc_fence_info mFenceInfo[MAX_FD_NUM];
+ std::map<int, hwc_fence_info_t> mFenceInfos;
/**
* This will be initialized with differnt class
diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp
index 4b8e350..46c0e43 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.cpp
+++ b/libhwc2.1/libdevice/ExynosDisplay.cpp
@@ -3425,8 +3425,6 @@ int32_t ExynosDisplay::presentDisplay(int32_t* outRetireFence) {
if (mDevice->canSkipValidate() == false)
goto not_validated;
else {
- // Reset current frame flags for Fence Tracer
- resetFenceCurFlag(this);
for (size_t i=0; i < mLayers.size(); i++) {
// Layer's acquire fence from SF
mLayers[i]->setSrcAcquireFence();
@@ -4443,9 +4441,6 @@ int32_t ExynosDisplay::validateDisplay(
else
mLayers.vector_sort();
- // Reset current frame flags for Fence Tracer
- resetFenceCurFlag(this);
-
for (size_t i = 0; i < mLayers.size(); i++) mLayers[i]->setSrcAcquireFence();
doPreProcessing();
diff --git a/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp b/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp
index 77a193f..75762fc 100644
--- a/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp
+++ b/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp
@@ -768,10 +768,6 @@ bool fence_valid(int fence) {
ALOGW("%s : fence (fd:%d) is less than 3", __func__, fence);
hwc_print_stack();
return true;
- } else if (fence >= MAX_FD_NUM) {
- ALOGW("%s : fence (fd:%d) over MAX fd number", __func__, fence);
- /* valid but fence will not be traced */
- return true;
}
return true;
}
@@ -823,17 +819,13 @@ struct tm* getLocalTime(struct timeval tv) {
return (struct tm*)localtime((time_t*)&tv.tv_sec);
}
-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, hwc_fdebug_fence_type type,
+ hwc_fdebug_ip_type ip, uint32_t direction, bool pendingAllowed) {
if (!fence_valid(fd) || display == NULL) return;
- /* valid but fence will not be traced */
- if (fd >= MAX_FD_NUM) return;
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = &device->mFenceInfo[fd];
- info->displayId = display->mDisplayId;
+ hwc_fence_info_t& info = device->mFenceInfos[fd];
+ info.displayId = display->mDisplayId;
struct timeval tv;
// FIXME: sync_fence_info, sync_pt_info are deprecated
@@ -841,18 +833,18 @@ void setFenceInfo(uint32_t fd, ExynosDisplay* display,
#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);
+ 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",
+ 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);
+ info.sync_data->name, info.sync_data->status, pt_info);
}
- sync_fence_info_free(info->sync_data);
+ sync_fence_info_free(info.sync_data);
}
}
#endif
@@ -861,23 +853,23 @@ void setFenceInfo(uint32_t fd, ExynosDisplay* display,
switch(direction) {
case FENCE_FROM:
- trace = &info->from;
- info->to.type = FENCE_TYPE_UNDEFINED;
- info->to.ip = FENCE_IP_UNDEFINED;
- info->usage++;
+ 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--;
+ trace = &info.to;
+ info.usage--;
break;
case FENCE_DUP:
- trace = &info->dup;
- info->usage++;
+ trace = &info.dup;
+ info.usage++;
break;
case FENCE_CLOSE:
- trace = &info->close;
- info->usage--;
- if (info->usage < 0) info->usage = 0;
+ trace = &info.close;
+ info.usage--;
+ if (info.usage < 0) info.usage = 0;
break;
default:
ALOGE("Fence trace : Undefined direction!");
@@ -891,12 +883,12 @@ void setFenceInfo(uint32_t fd, ExynosDisplay* display,
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);
+ // device->fenceTracing.appendFormat("FD : %d, From : %s\n", fd, info.trace.fromName);
}
#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,
+ 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,
@@ -905,12 +897,16 @@ void setFenceInfo(uint32_t fd, ExynosDisplay* display,
// 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.pendingAllowed = pendingAllowed;
- if (info->usage == 0)
- info->pendingAllowed = false;
+ info.last_dir = direction;
- info->last_dir = direction;
+ if (info.usage == 0) {
+ device->mFenceInfos.erase(fd);
+ } 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) {
@@ -918,114 +914,98 @@ void printLastFenceInfo(uint32_t fd, ExynosDisplay* display) {
struct timeval tv;
if (!fence_valid(fd)) return;
- /* valid but fence will not be traced */
- if (fd >= MAX_FD_NUM) return;
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = &device->mFenceInfo[fd];
- FT_LOGD("---- Fence FD : %d, Display(%d) ----", fd, info->displayId);
+ auto it = device->mFenceInfos.find(fd);
+ if (it == device->mFenceInfos.end()) return;
+ hwc_fence_info_t& info = it->second;
+ FT_LOGD("---- Fence FD : %d, Display(%d) ----", fd, info.displayId);
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;
+ 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;
+ FT_LOGD("Last state : %d, type(%d), ip(%d)", info.last_dir, trace->type, trace->ip);
+ tv = info.from.time;
}
- 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);
+ 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)));
+ 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 __unused depth) {
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = device->mFenceInfo;
FT_LOGD("Dump fence ++");
- for (int i=0; i < MAX_FD_NUM; i++){
- if ((info[i].usage >= 1 || info[i].usage <= -1) && (!info[i].pendingAllowed))
- printLastFenceInfo(i, display);
+ for (const auto& [fd, info] : device->mFenceInfos) {
+ if (!info.pendingAllowed) printLastFenceInfo(fd, display);
}
FT_LOGD("Dump fence --");
}
-void printLeakFds(ExynosDisplay *display){
-
+void printLeakFds(ExynosDisplay* display) {
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = device->mFenceInfo;
-
- int cnt = 1, i = 0;
- String8 errStringOne;
- String8 errStringMinus;
-
- errStringOne.appendFormat("Leak Fds (1) :\n");
- for (i=0; i < MAX_FD_NUM; i++){
- if(info[i].usage == 1) {
- errStringOne.appendFormat("%d,", i);
- if(cnt++%10 == 0)
- errStringOne.appendFormat("\n");
+ auto reportLeakFds = [&fenceInfos = device->mFenceInfos](int sign) {
+ String8 errString;
+ errString.appendFormat("Leak Fds (%d) :\n", sign);
+
+ int cnt = 0;
+ for (const auto& [fd, info] : fenceInfos) {
+ if (info.usage * sign > 0) {
+ errString.appendFormat("%d,", fd);
+ if ((++cnt % 10) == 0) {
+ errString.append("\n");
+ }
+ }
}
- }
- FT_LOGW("%s", errStringOne.string());
- errStringMinus.appendFormat("Leak Fds (-1) :\n");
+ FT_LOGW("%s", errString.string());
+ };
- cnt = 1;
- for (i=0; i < MAX_FD_NUM; i++){
- if(info[i].usage < 0) {
- errStringMinus.appendFormat("%d,", i);
- if(cnt++%10 == 0)
- errStringMinus.appendFormat("\n");
- }
- }
- FT_LOGW("%s", errStringMinus.string());
+ reportLeakFds(+1);
+ reportLeakFds(-1);
}
-void dumpNCheckLeak(ExynosDisplay *display, int32_t __unused depth) {
-
+void dumpNCheckLeak(ExynosDisplay* display, int32_t __unused depth) {
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = device->mFenceInfo;
FT_LOGD("Dump leaking fence ++");
- for (int i=0; i < MAX_FD_NUM; i++){
- if ((info[i].usage >= 1 || info[i].usage <= -1) && (!info[i].pendingAllowed))
+ for (auto& [fd, info] : device->mFenceInfos) {
+ if (!info.pendingAllowed) {
// leak is occured in this frame first
- if (!info[i].leaking) {
- info[i].leaking = true;
- printLastFenceInfo(i, display);
+ if (!info.leaking) {
+ info.leaking = true;
+ printLastFenceInfo(fd, display);
}
+ }
}
int priv = exynosHWCControl.fenceTracer;
@@ -1036,11 +1016,9 @@ void dumpNCheckLeak(ExynosDisplay *display, int32_t __unused depth) {
FT_LOGD("Dump leaking fence --");
}
-bool fenceWarn(ExynosDisplay *display, uint32_t threshold) {
-
- uint32_t cnt = 0, r_cnt = 0;
+bool fenceWarn(ExynosDisplay* display, uint32_t threshold) {
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = device->mFenceInfo;
+ uint32_t cnt = device->mFenceInfos.size(), r_cnt = 0;
// FIXME: sync_fence_info() is deprecated
// HWC guys should fix this.
@@ -1057,11 +1035,6 @@ bool fenceWarn(ExynosDisplay *display, uint32_t threshold) {
}
#endif
- for (int i=0; i < MAX_FD_NUM; i++){
- if(info[i].usage >= 1 || info[i].usage <= -1)
- cnt++;
- }
-
if ((cnt>threshold) || (exynosHWCControl.fenceTracer > 0))
dumpFenceInfo(display, 0);
@@ -1073,36 +1046,15 @@ bool fenceWarn(ExynosDisplay *display, uint32_t threshold) {
return (cnt>threshold) ? true : false;
}
-void resetFenceCurFlag(ExynosDisplay *display) {
- ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = device->mFenceInfo;
- for (int i=0; i < MAX_FD_NUM; i++){
- if (info[i].usage == 0) {
- info[i].displayId = HWC_DISPLAY_PRIMARY;
- info[i].leaking = false;
- info[i].from.curFlag = 0;
- info[i].to.curFlag = 0;
- info[i].dup.curFlag = 0;
- info[i].close.curFlag = 0;
- info[i].curFlag = 0;
- } else {
- info[i].curFlag = 0;
- }
- }
-}
-
-bool validateFencePerFrame(ExynosDisplay *display) {
-
+bool validateFencePerFrame(ExynosDisplay* display) {
ExynosDevice* device = display->mDevice;
- hwc_fence_info_t* info = device->mFenceInfo;
bool ret = true;
- for (int i=0; i < MAX_FD_NUM; i++){
- if (info[i].displayId != display->mDisplayId)
- continue;
- if ((info[i].usage >= 1 || info[i].usage <= -1) &&
- (!info[i].pendingAllowed) && (!info[i].leaking)) {
+ for (const auto& [fd, info] : device->mFenceInfos) {
+ if (info.displayId != display->mDisplayId) continue;
+ if ((!info.pendingAllowed) && (!info.leaking)) {
ret = false;
+ break;
}
}
@@ -1122,25 +1074,26 @@ void setFenceName(uint32_t fd, ExynosDisplay *display,
ExynosDevice* device = display->mDevice;
if (!fence_valid(fd) || device == NULL) return;
- /* valid but fence will not be traced */
- if (fd >= MAX_FD_NUM) return;
- hwc_fence_info_t* info = &device->mFenceInfo[fd];
- info->displayId = display->mDisplayId;
+ 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;
+ trace = &info.from;
break;
case FENCE_TO:
- trace = &info->to;
+ trace = &info.to;
break;
case FENCE_DUP:
- trace = &info->dup;
+ trace = &info.dup;
break;
case FENCE_CLOSE:
- trace = &info->close;
+ trace = &info.close;
break;
default:
ALOGE("Fence trace : Undefined direction!");
@@ -1153,10 +1106,7 @@ void setFenceName(uint32_t fd, ExynosDisplay *display,
FT_LOGD("FD : %d, direction : %d, type(%d), ip(%d) (changed)", fd, direction, type, ip);
}
- info->pendingAllowed = pendingAllowed;
-
- if (info->usage == 0)
- info->pendingAllowed = false;
+ info.pendingAllowed = pendingAllowed;
}
String8 getMPPStr(int typeId) {
diff --git a/libhwc2.1/libhwchelper/ExynosHWCHelper.h b/libhwc2.1/libhwchelper/ExynosHWCHelper.h
index 8146270..69d9fe1 100644
--- a/libhwc2.1/libhwchelper/ExynosHWCHelper.h
+++ b/libhwc2.1/libhwchelper/ExynosHWCHelper.h
@@ -493,23 +493,23 @@ enum {
};
typedef struct fenceTrace {
- hwc_fdebug_fence_type type;
- hwc_fdebug_ip_type ip;
- struct timeval time;
- int32_t curFlag;
+ hwc_fdebug_fence_type type = FENCE_TYPE_UNDEFINED;
+ hwc_fdebug_ip_type ip = FENCE_IP_UNDEFINED;
+ struct timeval time = {0, 0};
+ int32_t curFlag = 0;
} fenceTrace_t;
typedef struct hwc_fence_info {
- uint32_t displayId;
- struct sync_fence_info_data* sync_data;
- struct sync_pt_info* pt_info;
- fenceTrace_t from;
- fenceTrace_t to;
- fenceTrace_t dup;
- fenceTrace_t close;
- int32_t usage;
- int32_t curFlag;
- uint32_t last_dir;
+ 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;
bool pendingAllowed = false;
bool leaking = false;
} hwc_fence_info_t;
@@ -529,10 +529,8 @@ void setFenceName(uint32_t fd, ExynosDisplay *display,
void setFenceInfo(uint32_t fd, ExynosDisplay *display,
hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
uint32_t direction, bool pendingAllowed = false);
-void printFenceInfo(uint32_t fd, hwc_fence_info_t* info);
+void printLastFenceInfo(uint32_t fd, ExynosDisplay *display);
void dumpFenceInfo(ExynosDisplay *display, int32_t __unused depth);
-bool fenceWarn(hwc_fence_info_t **info, uint32_t threshold);
-void resetFenceCurFlag(ExynosDisplay *display);
bool fenceWarn(ExynosDisplay *display, uint32_t threshold);
void printLeakFds(ExynosDisplay *display);
bool validateFencePerFrame(ExynosDisplay *display);