From f9468db266525483112f5def84a8a7fdc4b322ca Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Mon, 14 Oct 2024 11:23:56 +1100 Subject: [PATCH] Windows embedder fixes --- thermion_dart/hook/build.dart | 70 ++++++++++--------- .../viewer/src/ffi/src/thermion_dart.g.dart | 11 +++ .../src/ffi/src/thermion_viewer_ffi.dart | 7 +- .../native/include/ThermionDartApi.h | 2 +- .../include/ThermionDartRenderThreadApi.h | 2 +- thermion_dart/native/src/ThermionDartApi.cpp | 2 +- .../src/ThermionDartRenderThreadApi.cpp | 19 ++--- .../widgets/src/thermion_widget_windows.dart | 18 +++-- .../windows/thermion_flutter_plugin.cpp | 11 ++- .../thermion_flutter/windows/wgl_context.cpp | 2 +- .../lib/thermion_flutter_windows.dart | 6 +- 11 files changed, 91 insertions(+), 59 deletions(-) diff --git a/thermion_dart/hook/build.dart b/thermion_dart/hook/build.dart index fd374f66..aecda6b2 100644 --- a/thermion_dart/hook/build.dart +++ b/thermion_dart/hook/build.dart @@ -32,18 +32,14 @@ void main(List args) async { final name = "thermion_dart.dart"; final libUri = config.outputDirectory .resolve(config.targetOS.libraryFileName(name, linkMode)); - output.addAsset( - - NativeCodeAsset( - package: config.packageName, - name: name, - file: libUri, - linkMode: linkMode, - os: config.targetOS, - architecture: config.dryRun ? null : config.targetArchitecture, - ) - - ); + output.addAsset(NativeCodeAsset( + package: config.packageName, + name: name, + file: libUri, + linkMode: linkMode, + os: config.targetOS, + architecture: config.dryRun ? null : config.targetArchitecture, + )); return; } @@ -91,7 +87,6 @@ void main(List args) async { "basis_transcoder" ]; - if (platform == "windows") { libDir = Directory(libDir).uri.toFilePath(); libs = libs.map((lib) => "${libDir}${lib}.lib").toList(); @@ -117,7 +112,12 @@ void main(List args) async { defines["WIN32"] = "1"; defines["_DEBUG"] = "1"; defines["_DLL"] = "1"; - flags.addAll(["/std:c++20", "/MDd", "/VERBOSE", ...defines.keys.map((k) => "/D$k=${defines[k]}").toList()]); + flags.addAll([ + "/std:c++20", + "/MDd", + "/VERBOSE", + ...defines.keys.map((k) => "/D$k=${defines[k]}").toList() + ]); } if (platform == "ios") { @@ -148,24 +148,23 @@ void main(List args) async { name: packageName, language: Language.cpp, assetName: 'thermion_dart.dart', - sources: platform == "windows" ? [] : -sources, - includes: platform == "windows"? [] : ['native/include', 'native/include/filament'], + sources: platform == "windows" ? [] : sources, + includes: platform == "windows" + ? [] + : ['native/include', 'native/include/filament'], defines: platform == "windows" ? {} : defines, flags: [ if (platform == "macos") '-mmacosx-version-min=13.0', if (platform == "ios") '-mios-version-min=13.0', ...flags, ...frameworks, - if (platform != "windows") - ...libs.map((lib) => "-l$lib"), - if (platform != "windows") - "-L$libDir", - if(platform == "windows") - ...[ - "/I${config.packageRoot.toFilePath()}\\native\\include", "/I${config.packageRoot.toFilePath()}native\\include\\filament", + if (platform != "windows") ...libs.map((lib) => "-l$lib"), + if (platform != "windows") "-L$libDir", + if (platform == "windows") ...[ + "/I${config.packageRoot.toFilePath()}\\native\\include", + "/I${config.packageRoot.toFilePath()}native\\include\\filament", ...sources, - '/link', + '/link', "/LIBPATH:$libDir", '/DLL', ] @@ -187,17 +186,24 @@ sources, Architecture.ia32 => "i686-linux-android", _ => throw FormatException('Invalid') }; - + var compilerPath = config.cCompiler.compiler!.path; - - if(Platform.isWindows && compilerPath.startsWith("/")) { + + if (Platform.isWindows && compilerPath.startsWith("/")) { compilerPath = compilerPath.substring(1); } - - var ndkRoot = File(compilerPath).parent.parent.uri.toFilePath(windows:true); - var stlPath = - File([ndkRoot, "sysroot", "usr", "lib", archExtension, "libc++_shared.so"].join(Platform.pathSeparator)); + var ndkRoot = + File(compilerPath).parent.parent.uri.toFilePath(windows: true); + + var stlPath = File([ + ndkRoot, + "sysroot", + "usr", + "lib", + archExtension, + "libc++_shared.so" + ].join(Platform.pathSeparator)); output.addAsset(NativeCodeAsset( package: "thermion_dart", name: "libc++_shared.so", diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart index 39cf49e4..19600d8a 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart @@ -142,6 +142,17 @@ external void Viewer_setViewRenderable( bool renderable, ); +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, ffi.Float, + ffi.Pointer>)>(isLeaf: true) +external void Viewer_loadIblRenderThread( + ffi.Pointer viewer, + ffi.Pointer iblPath, + double intensity, + ffi.Pointer> onComplete, +); + + @ffi.Native< ffi.Void Function( ffi.Pointer, diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart index 3cf8a614..050219d6 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart @@ -360,7 +360,12 @@ class ThermionViewerFFI extends ThermionViewer { Future loadIbl(String lightingPath, {double intensity = 30000}) async { final pathPtr = lightingPath.toNativeUtf8(allocator: allocator).cast(); - load_ibl(_viewer!, pathPtr, intensity); + + await withVoidCallback((cb) { + Viewer_loadIblRenderThread(_viewer!, pathPtr, intensity, cb); + }); + + } /// diff --git a/thermion_dart/native/include/ThermionDartApi.h b/thermion_dart/native/include/ThermionDartApi.h index 5a8586fc..18a534e8 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -99,7 +99,7 @@ extern "C" EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath); - EMSCRIPTEN_KEEPALIVE void load_ibl(TViewer *viewer, const char *iblPath, float intensity); + EMSCRIPTEN_KEEPALIVE void Viewer_loadIbl(TViewer *viewer, const char *iblPath, float intensity); EMSCRIPTEN_KEEPALIVE void create_ibl(TViewer *viewer, float r, float g, float b, float intensity); EMSCRIPTEN_KEEPALIVE void rotate_ibl(TViewer *viewer, float *rotationMatrix); EMSCRIPTEN_KEEPALIVE void remove_skybox(TViewer *viewer); diff --git a/thermion_dart/native/include/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/ThermionDartRenderThreadApi.h index 4ae034b0..4b7979b3 100644 --- a/thermion_dart/native/include/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/ThermionDartRenderThreadApi.h @@ -34,7 +34,7 @@ extern "C" EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, uint8_t* out, void (*onComplete)()); EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)()); EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)()); - + EMSCRIPTEN_KEEPALIVE void Viewer_loadIblRenderThread(TViewer *viewer, const char *iblPath, float intensity, void(*onComplete)()); EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping); EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, double bloom); diff --git a/thermion_dart/native/src/ThermionDartApi.cpp b/thermion_dart/native/src/ThermionDartApi.cpp index 5232b1d3..17f8697f 100644 --- a/thermion_dart/native/src/ThermionDartApi.cpp +++ b/thermion_dart/native/src/ThermionDartApi.cpp @@ -92,7 +92,7 @@ extern "C" ((FilamentViewer *)viewer)->createIbl(r, g, b, intensity); } - EMSCRIPTEN_KEEPALIVE void load_ibl(TViewer *viewer, const char *iblPath, float intensity) + EMSCRIPTEN_KEEPALIVE void Viewer_loadIbl(TViewer *viewer, const char *iblPath, float intensity) { ((FilamentViewer *)viewer)->loadIbl(iblPath, intensity); } diff --git a/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp index 0b9ef701..227e629d 100644 --- a/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/ThermionDartRenderThreadApi.cpp @@ -258,6 +258,16 @@ extern "C" } } + EMSCRIPTEN_KEEPALIVE void Viewer_loadIblRenderThread(TViewer *viewer, const char *iblPath, float intensity, void(*onComplete)()) { + std::packaged_task lambda( + [=]() mutable + { + Viewer_loadIbl(viewer, iblPath, intensity); + onComplete(); + }); + auto fut = _rl->add_task(lambda); + } + EMSCRIPTEN_KEEPALIVE void set_frame_interval_render_thread(TViewer *viewer, float frameIntervalInMilliseconds) { @@ -391,15 +401,6 @@ extern "C" }); auto fut = _rl->add_task(lambda); } - - EMSCRIPTEN_KEEPALIVE void load_ibl_render_thread(TViewer *viewer, const char *iblPath, - float intensity) - { - std::packaged_task lambda( - [=] - { load_ibl(viewer, iblPath, intensity); }); - auto fut = _rl->add_task(lambda); - } EMSCRIPTEN_KEEPALIVE void remove_skybox_render_thread(TViewer *viewer) { diff --git a/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget_windows.dart b/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget_windows.dart index 211ceede..eea2cb12 100644 --- a/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget_windows.dart +++ b/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget_windows.dart @@ -43,11 +43,16 @@ class _ThermionWidgetWindowsState extends State { var dpr = MediaQuery.of(context).devicePixelRatio; - var size = ((context.findRenderObject()) as RenderBox).size; + final renderBox = ((context.findRenderObject()) as RenderBox); + var size = renderBox.size; var width = (size.width * dpr).ceil(); var height = (size.height * dpr).ceil(); - _window = await t.ThermionFlutterPlatform.instance.createWindow(width, height, 0, 0); + final offset = renderBox.localToGlobal(Offset.zero); + final offsetLeft = (offset.dx * dpr).toInt(); + final offsetTop = (offset.dy * dpr).toInt(); + + _window = await t.ThermionFlutterPlatform.instance.createWindow(width, height, offsetLeft, offsetTop); await widget.view.updateViewport(_window!.width, _window!.height); @@ -121,11 +126,16 @@ class _ThermionWidgetWindowsState extends State { var newWidth = newSize.width.ceil(); var newHeight = newSize.height.ceil(); + final renderBox = context.findRenderObject() as RenderBox; + final offset = renderBox.localToGlobal(Offset.zero); + final offsetLeft = (offset.dx * dpr).toInt(); + final offsetTop = (offset.dy * dpr).toInt(); + await _window?.resize( newWidth, newHeight, - 0, - 0, + offsetLeft, + offsetTop, ); await widget.view.updateViewport(_window!.width, _window!.height); diff --git a/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp b/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp index afb248a3..edc57452 100644 --- a/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp +++ b/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp @@ -210,7 +210,7 @@ void ThermionFlutterPlugin::DestroyTexture( void ThermionFlutterPlugin::HandleMethodCall( const flutter::MethodCall &methodCall, std::unique_ptr> result) { - std::cout << methodCall.method_name().c_str() << std::endl; + // std::cout << methodCall.method_name().c_str() << std::endl; if (methodCall.method_name() == "usesBackingWindow") { result->Success(flutter::EncodableValue( #ifdef WGL_USE_BACKING_WINDOW @@ -239,13 +239,12 @@ void ThermionFlutterPlugin::HandleMethodCall( int dHeight = *(std::get_if(&(args->at(1)))); int dLeft = *(std::get_if(&(args->at(2)))); int dTop = *(std::get_if(&(args->at(3)))); - auto width = (uint32_t)round(dWidth ); - auto height = (uint32_t)round(dHeight ); - auto left = (uint32_t)round(dLeft ); - auto top = (uint32_t)round(dTop ); + auto width = static_cast(dWidth); + auto height = static_cast(dHeight); + auto left = static_cast(dLeft); + auto top = static_cast(dTop ); _context->ResizeRenderingSurface(width, height, left, top); - std::cout << "resized window to " << width << "x" << height << " at " << left << "," << top << std::endl; result->Success(); #else result->Error("ERROR", "resizeWindow is only available when using a backing window"); diff --git a/thermion_flutter/thermion_flutter/windows/wgl_context.cpp b/thermion_flutter/thermion_flutter/windows/wgl_context.cpp index 7cb5d9c6..28dedbc0 100644 --- a/thermion_flutter/thermion_flutter/windows/wgl_context.cpp +++ b/thermion_flutter/thermion_flutter/windows/wgl_context.cpp @@ -118,7 +118,7 @@ void WGLContext::CreateRenderingSurface( ResizeRenderingSurface(width, height, left, top); } - std::cout << "created window size " << width << "x" << height << " at " << left << "," << top << " with backing handle" << _backingWindow->GetHandle() << std::endl; + // std::cout << "created window size " << width << "x" << height << " at " << left << "," << top << " with backing handle" << _backingWindow->GetHandle() << std::endl; std::vector resultList; resultList.push_back(flutter::EncodableValue()); // return null for Flutter texture ID resultList.push_back(flutter::EncodableValue()); // return null for hardware texture ID diff --git a/thermion_flutter/thermion_flutter_ffi/lib/thermion_flutter_windows.dart b/thermion_flutter/thermion_flutter_ffi/lib/thermion_flutter_windows.dart index 51425db3..5e7269d4 100644 --- a/thermion_flutter/thermion_flutter_ffi/lib/thermion_flutter_windows.dart +++ b/thermion_flutter/thermion_flutter_ffi/lib/thermion_flutter_windows.dart @@ -91,7 +91,7 @@ class ThermionFlutterWindowImpl extends ThermionFlutterWindow { @override Future destroy() async { await _channel - .invokeMethod("destroyWindow", [width, height, offsetLeft, offsetLeft]); + .invokeMethod("destroyWindow", this.handle); } @override @@ -112,7 +112,7 @@ class ThermionFlutterWindowImpl extends ThermionFlutterWindow { throw Exception("Resize underway"); } - if (width == this.width && height == this.height) { + if (width == this.width && height == this.height && this.offsetLeft == offsetLeft && this.offsetTop == offsetTop) { return; } @@ -124,7 +124,7 @@ class ThermionFlutterWindowImpl extends ThermionFlutterWindow { _resizing = true; await _channel - .invokeMethod("resizeWindow", [width, height, offsetLeft, offsetLeft]); + .invokeMethod("resizeWindow", [width, height, offsetLeft, offsetTop]); _resizing = false; }