From 31c5ef41eb952bf05cc87f6875c9978a49b7aadb Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Mon, 4 Nov 2024 08:33:54 +0800 Subject: [PATCH] use texture backed platform on Windows --- .../lib/src/widgets/src/thermion_widget.dart | 4 - .../windows/opengl_texture_buffer.cpp | 3 +- .../windows/thermion_flutter_plugin.cpp | 83 ++++++------------- ...rmion_flutter_texture_backed_platform.dart | 4 +- .../lib/src/thermion_flutter_windows.dart | 8 +- .../thermion_flutter_ffi/pubspec.yaml | 2 +- 6 files changed, 36 insertions(+), 68 deletions(-) diff --git a/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget.dart b/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget.dart index b3246d30..974faa06 100644 --- a/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget.dart +++ b/thermion_flutter/thermion_flutter/lib/src/widgets/src/thermion_widget.dart @@ -94,10 +94,6 @@ class _ThermionWidgetState extends State { options: ThermionFlutterPlugin.options as ThermionFlutterWebOptions?); } - if (Platform.isWindows) { - return ThermionWidgetWindows(viewer: widget.viewer, view: view!, initial: widget.initial, onResize: widget.onResize); - } - return ThermionTextureWidget( key: ObjectKey(view!), initial: widget.initial, diff --git a/thermion_flutter/thermion_flutter/windows/opengl_texture_buffer.cpp b/thermion_flutter/thermion_flutter/windows/opengl_texture_buffer.cpp index 7142846e..1d4fb099 100644 --- a/thermion_flutter/thermion_flutter/windows/opengl_texture_buffer.cpp +++ b/thermion_flutter/thermion_flutter/windows/opengl_texture_buffer.cpp @@ -121,9 +121,8 @@ OpenGLTextureBuffer::OpenGLTextureBuffer( if (flutterTextureId != -1) { std::vector resultList; resultList.push_back(flutter::EncodableValue(flutterTextureId)); - resultList.push_back(flutter::EncodableValue((int64_t) nullptr)); resultList.push_back(flutter::EncodableValue(glTextureId)); - resultList.push_back(flutter::EncodableValue((int64_t)_context)); + resultList.push_back(flutter::EncodableValue((int64_t)nullptr)); result->Success(resultList); } } diff --git a/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp b/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp index 1f6e5cbd..f4b326f3 100644 --- a/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp +++ b/thermion_flutter/thermion_flutter/windows/thermion_flutter_plugin.cpp @@ -133,32 +133,6 @@ static void _freeResource(ResourceBuffer rbf, void *const plugin) { ((ThermionFlutterPlugin *)plugin)->freeResource(rbf); } -// this is the C-style function that will be returned via getRenderCallback -// called on every frame by the FFI API -// this is just a convenient wrapper to call RenderCallback on the actual plugin -// instance -void render_callback(void *owner) { - ((ThermionFlutterPlugin *)owner)->RenderCallback(); -} - -// this is the method on ThermionFlutterPlugin that will copy between D3D -// textures -void ThermionFlutterPlugin::RenderCallback() { - if (_context) { - auto flutterTextureId = _context->GetFlutterTextureId(); - if(flutterTextureId == -1) { - std::cout << "Bad texture" << std::endl; - return; - } -#ifdef USE_ANGLE - _context->RenderCallback(); -#endif -#if !WGL_USE_BACKING_WINDOW - _textureRegistrar->MarkTextureFrameAvailable(flutterTextureId); -#endif - } -} - void ThermionFlutterPlugin::CreateTexture( const flutter::MethodCall &methodCall, std::unique_ptr> result) { @@ -174,18 +148,7 @@ void ThermionFlutterPlugin::CreateTexture( auto height = (uint32_t)round(dHeight ); auto left = (uint32_t)round(dLeft ); auto top = (uint32_t)round(dTop ); - - // create a single shared context for the life of the application - // this will be used to create a backing texture and passed to Filament - if (!_context) { -#ifdef USE_ANGLE - _context = std::make_unique(_pluginRegistrar, _textureRegistrar); -#else - _context = std::make_unique(_pluginRegistrar, _textureRegistrar); - std::cout << "Created WGL context" << std::endl; -#endif - } - + _context->CreateRenderingSurface(width, height, std::move(result), left, top); } @@ -206,15 +169,7 @@ void ThermionFlutterPlugin::HandleMethodCall( const flutter::MethodCall &methodCall, std::unique_ptr> result) { // std::cout << methodCall.method_name().c_str() << std::endl; - if (methodCall.method_name() == "usesBackingWindow") { - result->Success(flutter::EncodableValue( - #ifdef WGL_USE_BACKING_WINDOW - true - #else - false - #endif - )); - } else if (methodCall.method_name() == "getResourceLoaderWrapper") { + if (methodCall.method_name() == "getResourceLoaderWrapper") { auto wrapper = (ResourceLoaderWrapper*)malloc(sizeof(ResourceLoaderWrapper)); wrapper->loadFromOwner = _loadResource; wrapper->freeFromOwner = _freeResource, @@ -224,7 +179,14 @@ void ThermionFlutterPlugin::HandleMethodCall( wrapper->freeResource = nullptr; result->Success(flutter::EncodableValue((int64_t)wrapper)); } else if(methodCall.method_name() == "getSharedContext") { - result->Success(NULL); + if (!_context) { + #ifdef USE_ANGLE + _context = std::make_unique(_pluginRegistrar, _textureRegistrar); + #else + _context = std::make_unique(_pluginRegistrar, _textureRegistrar); + #endif + } + result->Success(flutter::EncodableValue((int64_t)_context->GetSharedContext())); } else if (methodCall.method_name() == "resizeWindow") { #if WGL_USE_BACKING_WINDOW const auto *args = @@ -244,20 +206,27 @@ void ThermionFlutterPlugin::HandleMethodCall( #else result->Error("ERROR", "resizeWindow is only available when using a backing window"); #endif + } else if (methodCall.method_name() == "createTexture") { + CreateTexture(methodCall, std::move(result)); } else if (methodCall.method_name() == "createWindow") { CreateTexture(methodCall, std::move(result)); } else if (methodCall.method_name() == "destroyWindow") { DestroyTexture(methodCall, std::move(result)); - } else if (methodCall.method_name() == "getRenderCallback") { - flutter::EncodableList resultList; - #if !ANGLE && WGL_USE_BACKING_WINDOW - resultList.push_back(flutter::EncodableValue((int64_t)nullptr)); - resultList.push_back(flutter::EncodableValue((int64_t)nullptr)); - #else - resultList.push_back(flutter::EncodableValue((int64_t)&render_callback)); - resultList.push_back(flutter::EncodableValue((int64_t)this)); + } else if (methodCall.method_name() == "markTextureFrameAvailable") { + if (_context) { + auto flutterTextureId = _context->GetFlutterTextureId(); + if(flutterTextureId == -1) { + std::cout << "Bad texture" << std::endl; + return; + } + #ifdef USE_ANGLE + _context->RenderCallback(); #endif - result->Success(resultList); + #if !WGL_USE_BACKING_WINDOW + _textureRegistrar->MarkTextureFrameAvailable(flutterTextureId); + #endif + } + result->Success(flutter::EncodableValue((int64_t)nullptr)); } else if (methodCall.method_name() == "getDriverPlatform") { #ifdef USE_ANGLE result->Success(flutter::EncodableValue((int64_t)_context->GetPlatform())); diff --git a/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_texture_backed_platform.dart b/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_texture_backed_platform.dart index d261458d..4c066e36 100644 --- a/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_texture_backed_platform.dart +++ b/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_texture_backed_platform.dart @@ -42,7 +42,7 @@ class ThermionFlutterTextureBackedPlatform // this implementation renders directly into a texture/render target // we still need to create a (headless) swapchain, but the actual dimensions // don't matter - if (Platform.isMacOS || Platform.isIOS) { + if (Platform.isMacOS || Platform.isIOS || Platform.isWindows) { _swapChain = await viewer.createHeadlessSwapChain(1, 1); } @@ -57,7 +57,7 @@ class ThermionFlutterTextureBackedPlatform Future createTexture( t.View view, int width, int height) async { var texture = FlutterPlatformTexture(channel, viewer!, view, - (Platform.isMacOS || Platform.isIOS) ? _swapChain : null); + (Platform.isMacOS || Platform.isIOS || Platform.isWindows) ? _swapChain : null); await texture.resize(width, height, 0, 0); return texture; } diff --git a/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_windows.dart b/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_windows.dart index 51da65d4..306f7764 100644 --- a/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_windows.dart +++ b/thermion_flutter/thermion_flutter_ffi/lib/src/thermion_flutter_windows.dart @@ -7,6 +7,8 @@ import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dar import 'package:logging/logging.dart'; import 'package:thermion_flutter_platform_interface/thermion_flutter_window.dart'; +import 'platform_texture.dart'; + /// /// A Windows-only implementation of [ThermionFlutterPlatform] that uses /// a Flutter platform channel to create a rendering context, @@ -46,8 +48,10 @@ class ThermionFlutterWindows /// Not supported on Windows. Throws an exception. /// @override - Future createTexture(View view, int width, int height) { - throw UnimplementedError(); + Future createTexture(View view, int width, int height) async { + var texture = FlutterPlatformTexture(channel, viewer!, view, null); + await texture.resize(width, height, 0, 0); + return texture; } diff --git a/thermion_flutter/thermion_flutter_ffi/pubspec.yaml b/thermion_flutter/thermion_flutter_ffi/pubspec.yaml index 386f3f18..4aba6e5b 100644 --- a/thermion_flutter/thermion_flutter_ffi/pubspec.yaml +++ b/thermion_flutter/thermion_flutter_ffi/pubspec.yaml @@ -17,7 +17,7 @@ flutter: macos: dartPluginClass: ThermionFlutterTextureBackedPlatform windows: - dartPluginClass: ThermionFlutterWindows + dartPluginClass: ThermionFlutterTextureBackedPlatform dependencies: flutter: