fix incorrect pixelDeviceRatio

This commit is contained in:
Nick Fisher
2023-11-16 12:09:50 +08:00
parent f2a458b9ca
commit e67d4d7e1f
2 changed files with 70 additions and 80 deletions

View File

@@ -130,8 +130,11 @@ class FilamentControllerFFI extends FilamentController {
@override @override
Future setDimensions(Rect rect, double pixelRatio) async { Future setDimensions(Rect rect, double pixelRatio) async {
this.rect.value = Rect.fromLTWH(rect.left, rect.top, this.rect.value = Rect.fromLTWH(
rect.width * _pixelRatio, rect.height * _pixelRatio); (rect.left * _pixelRatio).floor().toDouble(),
rect.top * _pixelRatio.floor().toDouble(),
(rect.width * _pixelRatio).ceil().toDouble(),
(rect.height * _pixelRatio).ceil().toDouble());
_pixelRatio = pixelRatio; _pixelRatio = pixelRatio;
} }
@@ -318,64 +321,66 @@ class FilamentControllerFFI extends FilamentController {
throw Exception("Cannot resize without active viewer"); throw Exception("Cannot resize without active viewer");
} }
if (_resizing) { while (_resizing) {
throw Exception("Resize currently underway, ignoring"); await Future.delayed(Duration(milliseconds: 100));
} }
_resizing = true; try {
_resizing = true;
set_rendering_ffi(_viewer!, false); set_rendering_ffi(_viewer!, false);
if (!_usesBackingWindow) { if (!_usesBackingWindow) {
destroy_swap_chain_ffi(_viewer!); destroy_swap_chain_ffi(_viewer!);
}
if (requiresTextureWidget) {
if (textureDetails.value != null) {
await _channel.invokeMethod(
"destroyTexture", textureDetails.value!.textureId);
} }
} else if (Platform.isWindows) {
dev.log("Resizing window with rect $rect"); if (requiresTextureWidget) {
await _channel.invokeMethod("resizeWindow", [ if (textureDetails.value != null) {
rect.value!.width, await _channel.invokeMethod(
rect.value!.height, "destroyTexture", textureDetails.value!.textureId);
rect.value!.left, }
rect.value!.top } else if (Platform.isWindows) {
]); dev.log("Resizing window with rect $rect");
await _channel.invokeMethod("resizeWindow", [
rect.value!.width,
rect.value!.height,
rect.value!.left,
rect.value!.top
]);
}
var renderingSurface = await _createRenderingSurface();
if (_viewer!.address == 0) {
throw Exception("Failed to create viewer. Check logs for details");
}
_assetManager = get_asset_manager(_viewer!);
if (!_usesBackingWindow) {
create_swap_chain_ffi(_viewer!, renderingSurface.surface,
rect.value!.width.toInt(), rect.value!.height.toInt());
}
if (renderingSurface.textureHandle != 0) {
dev.log(
"Creating render target from native texture ${renderingSurface.textureHandle}");
create_render_target_ffi(_viewer!, renderingSurface.textureHandle,
rect.value!.width.toInt(), rect.value!.height.toInt());
}
textureDetails.value = TextureDetails(
textureId: renderingSurface.flutterTextureId,
width: rect.value!.width.toInt(),
height: rect.value!.height.toInt());
update_viewport_and_camera_projection_ffi(
_viewer!, rect.value!.width.toInt(), rect.value!.height.toInt(), 1.0);
await setRendering(_rendering);
} finally {
_resizing = false;
} }
var renderingSurface = await _createRenderingSurface();
if (_viewer!.address == 0) {
throw Exception("Failed to create viewer. Check logs for details");
}
_assetManager = get_asset_manager(_viewer!);
if (!_usesBackingWindow) {
create_swap_chain_ffi(_viewer!, renderingSurface.surface,
rect.value!.width.toInt(), rect.value!.height.toInt());
}
if (renderingSurface.textureHandle != 0) {
dev.log(
"Creating render target from native texture ${renderingSurface.textureHandle}");
create_render_target_ffi(_viewer!, renderingSurface.textureHandle,
rect.value!.width.toInt(), rect.value!.height.toInt());
}
textureDetails.value = TextureDetails(
textureId: renderingSurface.flutterTextureId,
width: rect.value!.width.toInt(),
height: rect.value!.height.toInt());
update_viewport_and_camera_projection_ffi(
_viewer!, rect.value!.width.toInt(), rect.value!.height.toInt(), 1.0);
await setRendering(_rendering);
_resizing = false;
} }
@override @override

View File

@@ -125,8 +125,6 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
late final AppLifecycleListener _appLifecycleListener; late final AppLifecycleListener _appLifecycleListener;
late double _pixelRatio;
Rect get _rect { Rect get _rect {
final renderBox = (context.findRenderObject()) as RenderBox; final renderBox = (context.findRenderObject()) as RenderBox;
final size = renderBox.size; final size = renderBox.size;
@@ -141,24 +139,22 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
); );
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
try { try {
_pixelRatio = MediaQuery.of(context).devicePixelRatio; widget.controller.setDimensions(_rect, MediaQuery.of(context).devicePixelRatio);
widget.controller.setDimensions(_rect, _pixelRatio);
} catch (err) { } catch (err) {
dev.log("Fatal error : $err"); dev.log("Fatal error : $err");
_error = err.toString(); _error = err.toString();
} }
setState(() {}); });
});
super.initState(); super.initState();
} }
Timer? _resizeTimer; Timer? _resizeTimer;
bool _resizing = false; bool _resizing = false;
Future _resize() { Future _resize() async {
dev.log("Resizing widget");
final completer = Completer(); final completer = Completer();
// resizing the window can be sluggish (particular in debug mode), exacerbated when simultaneously recreating the swapchain and resize the window. // resizing the window can be sluggish (particular in debug mode), exacerbated when simultaneously recreating the swapchain and resize the window.
// to address this, whenever the widget is resized, we set a timer for Xms in the future. // to address this, whenever the widget is resized, we set a timer for Xms in the future.
@@ -166,42 +162,31 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
// any subsequent widget resizes will cancel the timer and replace with a new one. // any subsequent widget resizes will cancel the timer and replace with a new one.
// debug mode does need a longer timeout. // debug mode does need a longer timeout.
_resizeTimer?.cancel(); _resizeTimer?.cancel();
_resizeTimer = Timer(Duration(milliseconds: (kReleaseMode || Platform.isWindows) ? 10 : 100), () async {
_resizeTimer = Timer(
Duration(milliseconds: (kReleaseMode || Platform.isWindows) ? 10 : 100),
() async {
if (!mounted) {
completer.complete();
return;
}
try { try {
while (_resizing) { while(_resizing) {
await Future.delayed(const Duration(milliseconds: 20)); await Future.delayed(const Duration(milliseconds: 20));
} }
_resizing = true; _resizing = true;
await widget.controller.setDimensions(_rect, _pixelRatio); await widget.controller.setDimensions(_rect, MediaQuery.of(context).devicePixelRatio);
await widget.controller.resize(); await widget.controller.resize();
_resizeTimer = null; _resizeTimer = null;
setState(() {}); setState(() {});
_resizing = false; _resizing = false;
} catch (err) { } catch (err) {
dev.log("Error resizing FilamentWidget: $err"); dev.log("Error resizing FilamentWidget: $err");
} finally { } finally {
completer.complete(); completer.complete();
} }
}); });
return completer.future; return completer.future;
} }
@override @override
void didUpdateWidget(_SizedFilamentWidget oldWidget) { void didUpdateWidget(_SizedFilamentWidget oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
_resize();
if (oldWidget.height != widget.height || oldWidget.width != widget.width) {
_resize();
}
} }
@override @override