summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libhwc2.1/ExynosHWCDebug.cpp77
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.cpp15
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.cpp132
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.h45
4 files changed, 157 insertions, 112 deletions
diff --git a/libhwc2.1/ExynosHWCDebug.cpp b/libhwc2.1/ExynosHWCDebug.cpp
index bbf676c..dc42369 100644
--- a/libhwc2.1/ExynosHWCDebug.cpp
+++ b/libhwc2.1/ExynosHWCDebug.cpp
@@ -18,33 +18,13 @@
#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 saveErrorLog(const String8 &errString, ExynosDisplay *display) {
+ if (display == nullptr) return -1;
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;
- }
+ auto &fileWriter = display->mErrLogFileWriter;
- mErrLogSize = ftell(pFile);
- if (mErrLogSize >= ERR_LOG_SIZE) {
- if (pFile != NULL)
- fclose(pFile);
+ if (!fileWriter.chooseOpenedFile()) {
return -1;
}
@@ -52,47 +32,19 @@ int32_t saveErrorLog(const String8 &errString, ExynosDisplay *display)
struct timeval tv;
gettimeofday(&tv, NULL);
- if (display != NULL) {
- saveString.appendFormat("%s %s %" PRIu64 ": %s\n", getLocalTimeStr(tv).string(),
- display->mDisplayName.string(), display->mErrorFrameCount,
- errString.string());
- } else {
- saveString.appendFormat("%s : %s\n", getLocalTimeStr(tv).string(), errString.string());
- }
+ saveString.appendFormat("%s errFrameNumber %" PRIu64 ": %s\n", getLocalTimeStr(tv).string(),
+ display->mErrorFrameCount, errString.string());
- if (pFile != NULL) {
- fwrite(saveString.string(), 1, saveString.size(), pFile);
- mErrLogSize = (uint32_t)ftell(pFile);
- ret = mErrLogSize;
- fclose(pFile);
- }
+ fileWriter.write(saveString);
+ fileWriter.flush();
return ret;
}
int32_t saveFenceTrace(ExynosDisplay *display) {
int32_t ret = NO_ERROR;
+ auto &fileWriter = display->mFenceFileWriter;
- 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);
+ if (!fileWriter.chooseOpenedFile()) {
return -1;
}
@@ -117,12 +69,7 @@ int32_t saveFenceTrace(ExynosDisplay *display) {
}
}
- if (pFile != NULL) {
- fwrite(saveString.string(), 1, saveString.size(), pFile);
- mFenceLogSize = (uint32_t)ftell(pFile);
- ret = mFenceLogSize;
- fclose(pFile);
- }
-
+ fileWriter.write(saveString);
+ fileWriter.flush();
return ret;
}
diff --git a/libhwc2.1/libdevice/ExynosDevice.cpp b/libhwc2.1/libdevice/ExynosDevice.cpp
index 5bf43c2..42eb27d 100644
--- a/libhwc2.1/libdevice/ExynosDevice.cpp
+++ b/libhwc2.1/libdevice/ExynosDevice.cpp
@@ -43,7 +43,6 @@ using aidl::android::hardware::graphics::composer3::IComposerCallback;
class ExynosDevice;
-extern uint32_t mFenceLogSize;
extern void PixelDisplayInit(ExynosDisplay *exynos_display, const std::string_view instance_str);
static const std::map<const uint32_t, const std::string_view> pixelDisplayIntfName =
@@ -161,10 +160,15 @@ ExynosDevice::ExynosDevice()
sprintf(fence_names[i], "_%2dh", i);
}
- String8 saveString;
- saveString.appendFormat("ExynosDevice is initialized");
- uint32_t errFileSize = saveErrorLog(saveString);
- ALOGI("Initial errlog size: %d bytes\n", errFileSize);
+ for (auto it : mDisplays) {
+ std::string displayName = std::string(it->mDisplayName.string());
+ it->mErrLogFileWriter.setPrefixName(displayName + "_hwc_error_log");
+ it->mDebugDumpFileWriter.setPrefixName(displayName + "_hwc_debug");
+ it->mFenceFileWriter.setPrefixName(displayName + "_hwc_fence_state");
+ String8 saveString;
+ saveString.appendFormat("ExynosDisplay %s is initialized", it->mDisplayName.string());
+ saveErrorLog(saveString, it);
+ }
initDeviceInterface(mInterfaceType);
@@ -859,7 +863,6 @@ bool ExynosDevice::validateFences(ExynosDisplay *display) {
if (exynosHWCControl.doFenceFileDump) {
ALOGD("Fence file dump !");
- if (mFenceLogSize != 0) ALOGD("Fence file not empty!");
saveFenceTrace(display);
exynosHWCControl.doFenceFileDump = false;
}
diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp
index bc17c2e..cd20a92 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.cpp
+++ b/libhwc2.1/libdevice/ExynosDisplay.cpp
@@ -1018,7 +1018,10 @@ ExynosDisplay::ExynosDisplay(uint32_t index, ExynosDevice *device)
mVsyncPeriodChangeConstraints{systemTime(SYSTEM_TIME_MONOTONIC), 0},
mVsyncAppliedTimeLine{false, 0, systemTime(SYSTEM_TIME_MONOTONIC)},
mConfigRequestState(hwc_request_state_t::SET_CONFIG_STATE_NONE),
- mPowerHalHint(getDisplayId(mDisplayId, mIndex)) {
+ mPowerHalHint(getDisplayId(mDisplayId, mIndex)),
+ mErrLogFileWriter(2, ERR_LOG_SIZE),
+ mDebugDumpFileWriter(10, 1, ".dump"),
+ mFenceFileWriter(2, FENCE_ERR_LOG_SIZE) {
mDisplayControl.enableCompositionCrop = true;
mDisplayControl.enableExynosCompositionOptimization = true;
mDisplayControl.enableClientCompositionOptimization = true;
@@ -2407,31 +2410,15 @@ int ExynosDisplay::setWinConfigData() {
return 0;
}
-void ExynosDisplay::printDebugInfos(String8 &reason)
-{
- FILE *pFile = NULL;
+void ExynosDisplay::printDebugInfos(String8 &reason) {
struct timeval tv;
gettimeofday(&tv, NULL);
reason.appendFormat("errFrameNumber: %" PRId64 " time:%s\n", mErrorFrameCount,
getLocalTimeStr(tv).string());
ALOGD("%s", reason.string());
- if (mErrorFrameCount < HWC_PRINT_FRAME_NUM) {
- char filePath[128];
- sprintf(filePath, "%s/%s_hwc_debug%d.dump", ERROR_LOG_PATH0, mDisplayName.string(), (int)mErrorFrameCount);
- pFile = fopen(filePath, "wb");
- if (pFile == NULL) {
- ALOGE("Fail to open file %s, error: %s", filePath, strerror(errno));
- sprintf(filePath, "%s/%s_hwc_debug%d.dump", ERROR_LOG_PATH1, mDisplayName.string(), (int)mErrorFrameCount);
- pFile = fopen(filePath, "wb");
- }
- if (pFile == NULL) {
- ALOGE("Fail to open file %s, error: %s", filePath, strerror(errno));
- } else {
- ALOGI("%s was created", filePath);
- fwrite(reason.string(), 1, reason.size(), pFile);
- }
- }
+ bool fileOpened = mDebugDumpFileWriter.chooseOpenedFile();
+ mDebugDumpFileWriter.write(reason);
mErrorFrameCount++;
android::String8 result;
@@ -2443,24 +2430,20 @@ void ExynosDisplay::printDebugInfos(String8 &reason)
clientCompInfo.dump(result);
exynosCompInfo.dump(result);
ALOGD("%s", result.string());
- if (pFile != NULL) {
- fwrite(result.string(), 1, result.size(), pFile);
- }
+ mDebugDumpFileWriter.write(result);
result.clear();
result.appendFormat("======================= dump exynos layers (%zu) ================================\n",
mLayers.size());
ALOGD("%s", result.string());
- if (pFile != NULL) {
- fwrite(result.string(), 1, result.size(), pFile);
- }
+ mDebugDumpFileWriter.write(result);
result.clear();
for (uint32_t i = 0; i < mLayers.size(); i++) {
ExynosLayer *layer = mLayers[i];
layer->printLayer();
- if (pFile != NULL) {
+ if (fileOpened) {
layer->dump(result);
- fwrite(result.string(), 1, result.size(), pFile);
+ mDebugDumpFileWriter.write(result);
result.clear();
}
}
@@ -2469,16 +2452,14 @@ void ExynosDisplay::printDebugInfos(String8 &reason)
result.appendFormat("======================= dump ignore layers (%zu) ================================\n",
mIgnoreLayers.size());
ALOGD("%s", result.string());
- if (pFile != NULL) {
- fwrite(result.string(), 1, result.size(), pFile);
- }
+ mDebugDumpFileWriter.write(result);
result.clear();
for (uint32_t i = 0; i < mIgnoreLayers.size(); i++) {
ExynosLayer *layer = mIgnoreLayers[i];
layer->printLayer();
- if (pFile != NULL) {
+ if (fileOpened) {
layer->dump(result);
- fwrite(result.string(), 1, result.size(), pFile);
+ mDebugDumpFileWriter.write(result);
result.clear();
}
}
@@ -2486,23 +2467,19 @@ void ExynosDisplay::printDebugInfos(String8 &reason)
result.appendFormat("============================= dump win configs ===================================\n");
ALOGD("%s", result.string());
- if (pFile != NULL) {
- fwrite(result.string(), 1, result.size(), pFile);
- }
+ mDebugDumpFileWriter.write(result);
result.clear();
for (size_t i = 0; i < mDpuData.configs.size(); i++) {
ALOGD("config[%zu]", i);
printConfig(mDpuData.configs[i]);
- if (pFile != NULL) {
+ if (fileOpened) {
result.appendFormat("config[%zu]\n", i);
dumpConfig(result, mDpuData.configs[i]);
- fwrite(result.string(), 1, result.size(), pFile);
+ mDebugDumpFileWriter.write(result);
result.clear();
}
}
- if (pFile != NULL) {
- fclose(pFile);
- }
+ mDebugDumpFileWriter.flush();
}
int32_t ExynosDisplay::validateWinConfigData()
@@ -6082,3 +6059,76 @@ int ExynosDisplay::lookupDisplayConfigs(const int32_t &width,
}
return HWC2_ERROR_BAD_CONFIG;
}
+
+FILE *ExynosDisplay::RotatingLogFileWriter::openLogFile(const std::string &filename,
+ const std::string &mode) {
+ FILE *file = nullptr;
+ auto fullpath = std::string(ERROR_LOG_PATH0) + "/" + filename;
+ file = fopen(fullpath.c_str(), mode.c_str());
+ if (file != nullptr) {
+ return file;
+ }
+ ALOGE("Fail to open file %s, error: %s", fullpath.c_str(), strerror(errno));
+ fullpath = std::string(ERROR_LOG_PATH1) + "/" + filename;
+ file = fopen(fullpath.c_str(), mode.c_str());
+ if (file == nullptr) {
+ ALOGE("Fail to open file %s, error: %s", fullpath.c_str(), strerror(errno));
+ }
+ return file;
+}
+
+std::optional<nsecs_t> ExynosDisplay::RotatingLogFileWriter::getLastModifiedTimestamp(
+ const std::string &filename) {
+ struct stat fileStat;
+ auto fullpath = std::string(ERROR_LOG_PATH0) + "/" + filename;
+ if (stat(fullpath.c_str(), &fileStat) == 0) {
+ return fileStat.st_mtim.tv_sec * nsecsPerSec + fileStat.st_mtim.tv_nsec;
+ }
+ fullpath = std::string(ERROR_LOG_PATH1) + "/" + filename;
+ if (stat(fullpath.c_str(), &fileStat) == 0) {
+ return fileStat.st_mtim.tv_sec * nsecsPerSec + fileStat.st_mtim.tv_nsec;
+ }
+ return std::nullopt;
+}
+
+bool ExynosDisplay::RotatingLogFileWriter::chooseOpenedFile() {
+ if (mLastFileIndex < 0) {
+ // HWC could be restarted, so choose to open new file or continue the last modified file
+ int chosenIndex = 0;
+ nsecs_t lastModifTimestamp = 0;
+ for (int i = 0; i < mMaxFileCount; ++i) {
+ auto timestamp = getLastModifiedTimestamp(mPrefixName + std::to_string(i) + mExtension);
+ if (!timestamp.has_value()) {
+ chosenIndex = i;
+ break;
+ }
+ if (i == 0 || lastModifTimestamp < *timestamp) {
+ chosenIndex = i;
+ lastModifTimestamp = *timestamp;
+ }
+ }
+ auto filename = mPrefixName + std::to_string(chosenIndex) + mExtension;
+ mFile = openLogFile(filename, "ab");
+ if (mFile == nullptr) {
+ ALOGE("Unable to open log file for %s", filename.c_str());
+ return false;
+ }
+ mLastFileIndex = chosenIndex;
+ }
+
+ // Choose to use the same last file or move on to the next file
+ for (int i = 0; i < 2; ++i) {
+ if (mFile == nullptr) {
+ mFile = openLogFile(mPrefixName + std::to_string(mLastFileIndex) + mExtension,
+ (i == 0) ? "ab" : "wb");
+ }
+ if (mFile != nullptr) {
+ auto fileSize = ftell(mFile);
+ if (fileSize < mThresholdSizePerFile) return true;
+ fclose(mFile);
+ mFile = nullptr;
+ }
+ mLastFileIndex = (mLastFileIndex + 1) % mMaxFileCount;
+ }
+ return false;
+}
diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h
index 12ad1f1..6fd6df9 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.h
+++ b/libhwc2.1/libdevice/ExynosDisplay.h
@@ -1519,6 +1519,51 @@ class ExynosDisplay {
// Resource TDM (Time-Division Multiplexing)
std::map<uint32_t, displayTDMInfo> mDisplayTDMInfo;
+
+ class RotatingLogFileWriter {
+ public:
+ RotatingLogFileWriter(uint32_t maxFileCount, uint32_t thresholdSizePerFile,
+ std::string extension = ".txt")
+ : mMaxFileCount(maxFileCount),
+ mThresholdSizePerFile(thresholdSizePerFile),
+ mPrefixName(""),
+ mExtension(extension),
+ mLastFileIndex(-1),
+ mFile(nullptr) {}
+
+ ~RotatingLogFileWriter() {
+ if (mFile) {
+ fclose(mFile);
+ }
+ }
+
+ bool chooseOpenedFile();
+ void write(const String8& content) {
+ if (mFile) {
+ fwrite(content.string(), 1, content.size(), mFile);
+ }
+ }
+ void flush() {
+ if (mFile) {
+ fflush(mFile);
+ }
+ }
+ void setPrefixName(const std::string& prefixName) { mPrefixName = prefixName; }
+
+ private:
+ FILE* openLogFile(const std::string& filename, const std::string& mode);
+ std::optional<nsecs_t> getLastModifiedTimestamp(const std::string& filename);
+
+ uint32_t mMaxFileCount;
+ uint32_t mThresholdSizePerFile;
+ std::string mPrefixName;
+ std::string mExtension;
+ int32_t mLastFileIndex;
+ FILE* mFile;
+ };
+ RotatingLogFileWriter mErrLogFileWriter;
+ RotatingLogFileWriter mDebugDumpFileWriter;
+ RotatingLogFileWriter mFenceFileWriter;
};
#endif //_EXYNOSDISPLAY_H