diff --git a/lib/main.dart b/lib/main.dart index 321f7c4..26ce6bb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -92,7 +92,8 @@ class MyApp extends StatelessWidget { } if (snapshot.hasError) { log.w("here is builder future throws error you should see it"); - log.w(snapshot.error); + final e = snapshot.error as Error; + log.w(snapshot.error, stackTrace: e.stackTrace); } SudokuState sudokuState = snapshot.data ?? SudokuState(); BootstrapPage bootstrapPage = BootstrapPage(title: "Loading"); diff --git a/lib/ml/yolov8/yolov8_detector.dart b/lib/ml/yolov8/yolov8_detector.dart index 34b45bb..6ff9f6c 100644 --- a/lib/ml/yolov8/yolov8_detector.dart +++ b/lib/ml/yolov8/yolov8_detector.dart @@ -44,14 +44,9 @@ class YoloV8Detector extends Predictor { /// int8 quantitative model seem not enough validation,not recommend to use @deprecated bool enableInt8Quantize = false, }) async { - // default enable GPU - final options = InterpreterOptions(); - if (Platform.isAndroid) { - options.addDelegate(GpuDelegateV2()); - } else { - options.addDelegate(GpuDelegate()); - } - var interpreter = await Interpreter.fromAsset(modelPath, options: options); + + var interpreter = await _buildInterpreterFromAsset(modelPath); + // var interpreter = await Interpreter.fromAsset(modelPath, options: options); String yamlContent = await rootBundle.loadString(metadataPath); var metadata = loadYaml(yamlContent); @@ -284,4 +279,38 @@ class YoloV8Detector extends Predictor { YoloV8Output predict(YoloV8Input input) { return _predict(input); } + + static _buildInterpreterFromAsset(String modelPath) async { + // default enable GPU + var interpreter = null; + final delegates = []; + if (Platform.isAndroid) { + delegates.add(GpuDelegateV2()); + delegates.add(XNNPackDelegate()); + } else { + delegates.add(GpuDelegate()); + } + + // try to use gpu delegate , but didn't know device support delegate + final delegateIterator = delegates.iterator; + while (delegateIterator.moveNext()) { + final gpuDelegate = delegateIterator.current; + final options = InterpreterOptions()..addDelegate(gpuDelegate); + try { + log.i("use gpu delegate: $gpuDelegate"); + interpreter = await Interpreter.fromAsset(modelPath, options: options); + break; + } catch (_) { + // seem not support gpu delegate , change one + log.w("use gpu delegate: $gpuDelegate failure"); + } + } + + if (interpreter == null) { + // interpreter without gpu delegate + interpreter = await Interpreter.fromAsset(modelPath); + } + + return interpreter; + } } diff --git a/lib/page/ai_scan.dart b/lib/page/ai_scan.dart index ac2d354..979adbb 100644 --- a/lib/page/ai_scan.dart +++ b/lib/page/ai_scan.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'dart:ui' as ui; import 'package:camera/camera.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/sudoku_localizations.dart'; import 'package:image/image.dart' as img; @@ -13,6 +14,8 @@ import 'package:sudoku/ml/yolov8/yolov8_output.dart'; import 'package:sudoku/page/ai_detection.dart'; import 'package:sudoku/util/image_util.dart'; +import '../util/crashlytics_util.dart'; + final Logger log = Logger(); class AIScanPage extends StatefulWidget { @@ -220,7 +223,9 @@ class AIScanPageState extends State { ), ); } catch (e) { - log.e(e); + e as Error; + log.e(e, stackTrace: e.stackTrace); + CrashlyticsUtil.recordError(e, e.stackTrace); } } diff --git a/lib/util/crashlytics_util.dart b/lib/util/crashlytics_util.dart new file mode 100644 index 0000000..9602300 --- /dev/null +++ b/lib/util/crashlytics_util.dart @@ -0,0 +1,16 @@ +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:logger/logger.dart'; +import 'package:sudoku/constant.dart'; + +Logger log = Logger(); + +class CrashlyticsUtil { + static void recordError(dynamic error, dynamic stackTrace) { + if (!Constant.enableGoogleFirebase) { + log.w("not enable google firebase crashlytics service"); + log.w(error, stackTrace: stackTrace); + return; + } + FirebaseCrashlytics.instance.recordError(error, stackTrace); + } +}