1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "ExynosHWCDebug.h"
17 #include "ExynosDisplay.h"
18 #include <sync/sync.h>
19 #include "exynos_sync.h"
20
21 uint32_t mErrLogSize = 0;
22 uint32_t mFenceLogSize = 0;
23
saveErrorLog(const String8 & errString,ExynosDisplay * display)24 int32_t saveErrorLog(const String8 &errString, ExynosDisplay *display)
25 {
26 int32_t ret = NO_ERROR;
27 if (mErrLogSize >= ERR_LOG_SIZE)
28 return -1;
29
30 FILE *pFile = NULL;
31 char filePath[128];
32 sprintf(filePath, "%s/hwc_error_log.txt", ERROR_LOG_PATH0);
33 pFile = fopen(filePath, "a");
34 if (pFile == NULL) {
35 ALOGE("Fail to open file %s/hwc_error_log.txt, error: %s", ERROR_LOG_PATH0, strerror(errno));
36 sprintf(filePath, "%s/hwc_error_log.txt", ERROR_LOG_PATH1);
37 pFile = fopen(filePath, "a");
38 }
39 if (pFile == NULL) {
40 ALOGE("Fail to open file %s/hwc_error_log.txt, error: %s", ERROR_LOG_PATH1, strerror(errno));
41 return -errno;
42 }
43
44 mErrLogSize = ftell(pFile);
45 if (mErrLogSize >= ERR_LOG_SIZE) {
46 if (pFile != NULL)
47 fclose(pFile);
48 return -1;
49 }
50
51 String8 saveString;
52 struct timeval tv;
53 gettimeofday(&tv, NULL);
54
55 if (display != NULL) {
56 saveString.appendFormat("%s %s %" PRIu64 ": %s\n", getLocalTimeStr(tv).string(),
57 display->mDisplayName.string(), display->mErrorFrameCount,
58 errString.string());
59 } else {
60 saveString.appendFormat("%s : %s\n", getLocalTimeStr(tv).string(), errString.string());
61 }
62
63 if (pFile != NULL) {
64 fwrite(saveString.string(), 1, saveString.size(), pFile);
65 mErrLogSize = (uint32_t)ftell(pFile);
66 ret = mErrLogSize;
67 fclose(pFile);
68 }
69 return ret;
70 }
71
saveFenceTrace(ExynosDisplay * display)72 int32_t saveFenceTrace(ExynosDisplay *display) {
73 int32_t ret = NO_ERROR;
74
75 if (mFenceLogSize >= FENCE_ERR_LOG_SIZE)
76 return -1;
77
78 FILE *pFile = NULL;
79 char filePath[128];
80 sprintf(filePath, "%s/hwc_fence_state.txt", ERROR_LOG_PATH0);
81 pFile = fopen(filePath, "a");
82 if (pFile == NULL) {
83 ALOGE("Fail to open file %s/hwc_fence_state.txt, error: %s", ERROR_LOG_PATH0, strerror(errno));
84 sprintf(filePath, "%s/hwc_fence_state.txt", ERROR_LOG_PATH1);
85 pFile = fopen(filePath, "a");
86 }
87 if (pFile == NULL) {
88 ALOGE("Fail to open file %s, error: %s", ERROR_LOG_PATH1, strerror(errno));
89 return -errno;
90 }
91
92 mFenceLogSize = ftell(pFile);
93 if (mFenceLogSize >= FENCE_ERR_LOG_SIZE) {
94 if (pFile != NULL)
95 fclose(pFile);
96 return -1;
97 }
98
99 ExynosDevice *device = display->mDevice;
100
101 String8 saveString;
102
103 struct timeval tv;
104 gettimeofday(&tv, NULL);
105 saveString.appendFormat("\n====== Fences at time:%s ======\n", getLocalTimeStr(tv).string());
106
107 if (device != NULL) {
108 for (const auto &[fd, info] : device->mFenceInfos) {
109 saveString.appendFormat("---- Fence FD : %d, Display(%d) ----\n", fd, info.displayId);
110 saveString.appendFormat("usage: %d, dupFrom: %d, pendingAllowed: %d, leaking: %d\n",
111 info.usage, info.dupFrom, info.pendingAllowed, info.leaking);
112
113 for (const auto &trace : info.traces) {
114 saveString.appendFormat("> dir: %d, type: %d, ip: %d, time:%s\n", trace.direction,
115 trace.type, trace.ip, getLocalTimeStr(trace.time).string());
116 }
117 }
118 }
119
120 if (pFile != NULL) {
121 fwrite(saveString.string(), 1, saveString.size(), pFile);
122 mFenceLogSize = (uint32_t)ftell(pFile);
123 ret = mFenceLogSize;
124 fclose(pFile);
125 }
126
127 return ret;
128 }
129