summaryrefslogtreecommitdiff
path: root/libhwc2.1/ExynosHWCDebug.cpp
diff options
context:
space:
mode:
authorHyunKyung Kim <hk310.kim@samsung.com>2019-08-12 15:27:36 +0900
committerHyunKyung Kim <hk310.kim@samsung.com>2019-09-18 19:34:02 +0900
commit6935a9b0ac01b978519d8d704dee3994440ff023 (patch)
treeb221bd0957f7ca7d936d598394dfc7dbf44ecdf7 /libhwc2.1/ExynosHWCDebug.cpp
parentac1c0535583ce3eeb8f2b59431ebe510619c0416 (diff)
Add initial source code
Change-Id: I285a55c44c9fd5d3a8abaa781ef9dc8d9d39f53a Signed-off-by: HyunKyung Kim <hk310.kim@samsung.com>
Diffstat (limited to 'libhwc2.1/ExynosHWCDebug.cpp')
-rw-r--r--libhwc2.1/ExynosHWCDebug.cpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/libhwc2.1/ExynosHWCDebug.cpp b/libhwc2.1/ExynosHWCDebug.cpp
new file mode 100644
index 0000000..e3e3fe8
--- /dev/null
+++ b/libhwc2.1/ExynosHWCDebug.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "ExynosHWCDebug.h"
+#include "ExynosDisplay.h"
+#include <sync/sync.h>
+#include "exynos_sync.h"
+
+uint32_t mErrLogSize = 0;
+uint32_t mFenceLogSize = 0;
+
+int32_t saveErrorLog(const String8 &errString, ExynosDisplay *display)
+{
+ int32_t ret = NO_ERROR;
+ if (mErrLogSize >= ERR_LOG_SIZE)
+ return -1;
+
+ FILE *pFile = NULL;
+ char filePath[128];
+ sprintf(filePath, "%s/hwc_error_log.txt", ERROR_LOG_PATH0);
+ pFile = fopen(filePath, "a");
+ if (pFile == NULL) {
+ ALOGE("Fail to open file %s/hwc_error_log.txt, error: %s", ERROR_LOG_PATH0, strerror(errno));
+ sprintf(filePath, "%s/hwc_error_log.txt", ERROR_LOG_PATH1);
+ pFile = fopen(filePath, "a");
+ }
+ if (pFile == NULL) {
+ ALOGE("Fail to open file %s/hwc_error_log.txt, error: %s", ERROR_LOG_PATH1, strerror(errno));
+ return -errno;
+ }
+
+ mErrLogSize = ftell(pFile);
+ if (mErrLogSize >= ERR_LOG_SIZE) {
+ if (pFile != NULL)
+ fclose(pFile);
+ return -1;
+ }
+
+ 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());
+ } 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());
+ }
+
+ if (pFile != NULL) {
+ fwrite(saveString.string(), 1, saveString.size(), pFile);
+ mErrLogSize = (uint32_t)ftell(pFile);
+ ret = mErrLogSize;
+ fclose(pFile);
+ }
+ return ret;
+}
+
+int32_t saveFenceTrace(ExynosDisplay *display) {
+ int32_t ret = NO_ERROR;
+
+ if (mFenceLogSize >= FENCE_ERR_LOG_SIZE)
+ return -1;
+
+ FILE *pFile = NULL;
+ char filePath[128];
+ sprintf(filePath, "%s/hwc_fence_state.txt", ERROR_LOG_PATH0);
+ pFile = fopen(filePath, "a");
+ if (pFile == NULL) {
+ ALOGE("Fail to open file %s/hwc_fence_state.txt, error: %s", ERROR_LOG_PATH0, strerror(errno));
+ sprintf(filePath, "%s/hwc_fence_state.txt", ERROR_LOG_PATH1);
+ pFile = fopen(filePath, "a");
+ }
+ if (pFile == NULL) {
+ ALOGE("Fail to open file %s, error: %s", ERROR_LOG_PATH1, strerror(errno));
+ return -errno;
+ }
+
+ mFenceLogSize = ftell(pFile);
+ if (mFenceLogSize >= FENCE_ERR_LOG_SIZE) {
+ if (pFile != NULL)
+ fclose(pFile);
+ return -1;
+ }
+
+ String8 saveString;
+ struct timeval tv;
+
+ ExynosDevice *device = display->mDevice;
+ hwc_fence_info_t* _info = device->mFenceInfo;
+
+ if (device != NULL) {
+ for(int i=0; i<1024;i ++){
+
+ 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) {
+ 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);
+ }
+#endif
+
+ if ((info.usage == 0) && !sysFdOpen) continue;
+
+ 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;
+ }
+
+ 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)));
+ }
+ }
+
+ if (pFile != NULL) {
+ fwrite(saveString.string(), 1, saveString.size(), pFile);
+ mFenceLogSize = (uint32_t)ftell(pFile);
+ ret = mFenceLogSize;
+ fclose(pFile);
+ }
+
+ return ret;
+}