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 struct tm* localTime;
54 gettimeofday(&tv, NULL);
55 localTime = (struct tm*)localtime((time_t*)&tv.tv_sec);
56
57 if (display != NULL) {
58 saveString.appendFormat("%02d-%02d %02d:%02d:%02d.%03lu(%lu) %s %" PRIu64 ": %s\n",
59 localTime->tm_mon+1, localTime->tm_mday,
60 localTime->tm_hour, localTime->tm_min,
61 localTime->tm_sec, tv.tv_usec/1000, ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)),
62 display->mDisplayName.string(), display->mErrorFrameCount,
63 errString.string());
64 } else {
65 saveString.appendFormat("%02d-%02d %02d:%02d:%02d.%03lu(%lu) : %s\n",
66 localTime->tm_mon+1, localTime->tm_mday,
67 localTime->tm_hour, localTime->tm_min,
68 localTime->tm_sec, tv.tv_usec/1000, ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)),
69 errString.string());
70 }
71
72 if (pFile != NULL) {
73 fwrite(saveString.string(), 1, saveString.size(), pFile);
74 mErrLogSize = (uint32_t)ftell(pFile);
75 ret = mErrLogSize;
76 fclose(pFile);
77 }
78 return ret;
79 }
80
saveFenceTrace(ExynosDisplay * display)81 int32_t saveFenceTrace(ExynosDisplay *display) {
82 int32_t ret = NO_ERROR;
83
84 if (mFenceLogSize >= FENCE_ERR_LOG_SIZE)
85 return -1;
86
87 FILE *pFile = NULL;
88 char filePath[128];
89 sprintf(filePath, "%s/hwc_fence_state.txt", ERROR_LOG_PATH0);
90 pFile = fopen(filePath, "a");
91 if (pFile == NULL) {
92 ALOGE("Fail to open file %s/hwc_fence_state.txt, error: %s", ERROR_LOG_PATH0, strerror(errno));
93 sprintf(filePath, "%s/hwc_fence_state.txt", ERROR_LOG_PATH1);
94 pFile = fopen(filePath, "a");
95 }
96 if (pFile == NULL) {
97 ALOGE("Fail to open file %s, error: %s", ERROR_LOG_PATH1, strerror(errno));
98 return -errno;
99 }
100
101 mFenceLogSize = ftell(pFile);
102 if (mFenceLogSize >= FENCE_ERR_LOG_SIZE) {
103 if (pFile != NULL)
104 fclose(pFile);
105 return -1;
106 }
107
108 String8 saveString;
109 struct timeval tv;
110
111 ExynosDevice *device = display->mDevice;
112 hwc_fence_info_t* _info = device->mFenceInfo;
113
114 if (device != NULL) {
115 for(int i=0; i<1024;i ++){
116
117 bool sysFdOpen = false;
118 hwc_fence_info_t info = _info[i];
119
120 // FIXME: sync_fence_info and sync_pt_info are deprecated
121 // HWC guys should fix this
122 #if 0
123 struct sync_pt_info* pt_info = NULL;
124 info.sync_data = sync_fence_info(i);
125 if (info.sync_data != NULL) {
126 pt_info = sync_pt_info(info.sync_data, pt_info);
127 if (pt_info !=NULL) {
128 saveString.appendFormat("\n-- FD sys : %d\n", i);
129 saveString.appendFormat("real name : %s, status : %s, pt_obj : %s, pt_drv : %s, time : %llu",
130 info.sync_data->name, info.sync_data->status==1 ? "Active":"Signaled",
131 pt_info->obj_name, pt_info->driver_name, static_cast<unsigned long long>(pt_info->timestamp_ns));
132 } else {
133 saveString.appendFormat("\n-- FD sys : %d\n", i);
134 saveString.appendFormat("real name : %s, status : %d, pt_info : %p",
135 info.sync_data->name, info.sync_data->status, pt_info);
136 }
137 sysFdOpen = true;
138 sync_fence_info_free(info.sync_data);
139 }
140 #endif
141
142 if ((info.usage == 0) && !sysFdOpen) continue;
143
144 saveString.appendFormat("\n-- FD hwc : %d, usage %d\n", i, info.usage);
145
146 switch(info.last_dir) {
147 case FENCE_FROM:
148 saveString.appendFormat("Last state : from %d, %d\n",
149 info.from.type, info.from.ip);
150 tv = info.from.time;
151 break;
152 case FENCE_TO:
153 saveString.appendFormat("Last state : to %d, %d\n",
154 info.to.type, info.to.ip);
155 tv = info.to.time;
156 break;
157 case FENCE_DUP:
158 saveString.appendFormat("Last state : dup %d, %d\n",
159 info.dup.type, info.dup.ip);
160 tv = info.dup.time;
161 break;
162 case FENCE_CLOSE:
163 saveString.appendFormat("Last state : Close %d, %d\n",
164 info.close.type, info.close.ip);
165 tv = info.close.time;
166 break;
167 break;
168 default:
169 saveString.appendFormat("Fence trace : Undefined direction!\n");
170 break;
171 }
172
173 struct tm* localTime = (struct tm*)localtime((time_t*)&tv.tv_sec);
174
175 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",
176 info.from.type, info.from.ip, info.from.curFlag,
177 info.to.type, info.to.ip, info.to.curFlag,
178 info.dup.type, info.dup.ip, info.dup.curFlag,
179 info.close.type, info.close.ip, info.close.curFlag);
180 saveString.appendFormat("usage : %d, time:%02d-%02d %02d:%02d:%02d.%03lu(%lu)", info.usage,
181 localTime->tm_mon+1, localTime->tm_mday,
182 localTime->tm_hour, localTime->tm_min,
183 localTime->tm_sec, tv.tv_usec/1000,
184 ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
185 }
186 }
187
188 if (pFile != NULL) {
189 fwrite(saveString.string(), 1, saveString.size(), pFile);
190 mFenceLogSize = (uint32_t)ftell(pFile);
191 ret = mFenceLogSize;
192 fclose(pFile);
193 }
194
195 return ret;
196 }
197