Use mmap to read TFLite model.
The buffers in the model file are used directly by TFLite, and so a
small memory saving can be achieved by backing those memory pages with
the file itself.
Bug: 267050081
Test: atest libinput_tests
Change-Id: I743a3c94477d4bb778b6e0c4b4890a44f4e19aa4
diff --git a/libs/input/TfLiteMotionPredictor.cpp b/libs/input/TfLiteMotionPredictor.cpp
index fbb7106..10510d6 100644
--- a/libs/input/TfLiteMotionPredictor.cpp
+++ b/libs/input/TfLiteMotionPredictor.cpp
@@ -17,19 +17,21 @@
#define LOG_TAG "TfLiteMotionPredictor"
#include <input/TfLiteMotionPredictor.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdint>
-#include <fstream>
-#include <ios>
-#include <iterator>
#include <memory>
#include <span>
-#include <string>
#include <type_traits>
#include <utility>
+#include <android-base/logging.h>
+#include <android-base/mapped_file.h>
#define ATRACE_TAG ATRACE_TAG_INPUT
#include <cutils/trace.h>
#include <log/log.h>
@@ -206,21 +208,36 @@
std::unique_ptr<TfLiteMotionPredictorModel> TfLiteMotionPredictorModel::create(
const char* modelPath) {
- std::ifstream f(modelPath, std::ios::binary);
- LOG_ALWAYS_FATAL_IF(!f, "Could not read model from %s", modelPath);
+ const int fd = open(modelPath, O_RDONLY);
+ if (fd == -1) {
+ PLOG(FATAL) << "Could not read model from " << modelPath;
+ }
- std::string data;
- data.assign(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());
+ const off_t fdSize = lseek(fd, 0, SEEK_END);
+ if (fdSize == -1) {
+ PLOG(FATAL) << "Failed to determine file size";
+ }
+
+ std::unique_ptr<android::base::MappedFile> modelBuffer =
+ android::base::MappedFile::FromFd(fd, /*offset=*/0, fdSize, PROT_READ);
+ if (!modelBuffer) {
+ PLOG(FATAL) << "Failed to mmap model";
+ }
+ if (close(fd) == -1) {
+ PLOG(FATAL) << "Failed to close model fd";
+ }
return std::unique_ptr<TfLiteMotionPredictorModel>(
- new TfLiteMotionPredictorModel(std::move(data)));
+ new TfLiteMotionPredictorModel(std::move(modelBuffer)));
}
-TfLiteMotionPredictorModel::TfLiteMotionPredictorModel(std::string model)
+TfLiteMotionPredictorModel::TfLiteMotionPredictorModel(
+ std::unique_ptr<android::base::MappedFile> model)
: mFlatBuffer(std::move(model)) {
+ CHECK(mFlatBuffer);
mErrorReporter = std::make_unique<LoggingErrorReporter>();
- mModel = tflite::FlatBufferModel::VerifyAndBuildFromBuffer(mFlatBuffer.data(),
- mFlatBuffer.length(),
+ mModel = tflite::FlatBufferModel::VerifyAndBuildFromBuffer(mFlatBuffer->data(),
+ mFlatBuffer->size(),
/*extra_verifier=*/nullptr,
mErrorReporter.get());
LOG_ALWAYS_FATAL_IF(!mModel);