use texture backed platform on Windows

This commit is contained in:
Nick Fisher
2024-11-04 08:33:54 +08:00
parent 73470fa504
commit 31c5ef41eb
6 changed files with 36 additions and 68 deletions

View File

@@ -94,10 +94,6 @@ class _ThermionWidgetState extends State<ThermionWidget> {
options: ThermionFlutterPlugin.options as ThermionFlutterWebOptions?); options: ThermionFlutterPlugin.options as ThermionFlutterWebOptions?);
} }
if (Platform.isWindows) {
return ThermionWidgetWindows(viewer: widget.viewer, view: view!, initial: widget.initial, onResize: widget.onResize);
}
return ThermionTextureWidget( return ThermionTextureWidget(
key: ObjectKey(view!), key: ObjectKey(view!),
initial: widget.initial, initial: widget.initial,

View File

@@ -121,9 +121,8 @@ OpenGLTextureBuffer::OpenGLTextureBuffer(
if (flutterTextureId != -1) { if (flutterTextureId != -1) {
std::vector<flutter::EncodableValue> resultList; std::vector<flutter::EncodableValue> resultList;
resultList.push_back(flutter::EncodableValue(flutterTextureId)); 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(glTextureId));
resultList.push_back(flutter::EncodableValue((int64_t)_context)); resultList.push_back(flutter::EncodableValue((int64_t)nullptr));
result->Success(resultList); result->Success(resultList);
} }
} }

View File

@@ -133,32 +133,6 @@ static void _freeResource(ResourceBuffer rbf, void *const plugin) {
((ThermionFlutterPlugin *)plugin)->freeResource(rbf); ((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( void ThermionFlutterPlugin::CreateTexture(
const flutter::MethodCall<flutter::EncodableValue> &methodCall, const flutter::MethodCall<flutter::EncodableValue> &methodCall,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
@@ -174,18 +148,7 @@ void ThermionFlutterPlugin::CreateTexture(
auto height = (uint32_t)round(dHeight ); auto height = (uint32_t)round(dHeight );
auto left = (uint32_t)round(dLeft ); auto left = (uint32_t)round(dLeft );
auto top = (uint32_t)round(dTop ); 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<FlutterEGLContext>(_pluginRegistrar, _textureRegistrar);
#else
_context = std::make_unique<WGLContext>(_pluginRegistrar, _textureRegistrar);
std::cout << "Created WGL context" << std::endl;
#endif
}
_context->CreateRenderingSurface(width, height, std::move(result), left, top); _context->CreateRenderingSurface(width, height, std::move(result), left, top);
} }
@@ -206,15 +169,7 @@ void ThermionFlutterPlugin::HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue> &methodCall, const flutter::MethodCall<flutter::EncodableValue> &methodCall,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
// std::cout << methodCall.method_name().c_str() << std::endl; // std::cout << methodCall.method_name().c_str() << std::endl;
if (methodCall.method_name() == "usesBackingWindow") { if (methodCall.method_name() == "getResourceLoaderWrapper") {
result->Success(flutter::EncodableValue(
#ifdef WGL_USE_BACKING_WINDOW
true
#else
false
#endif
));
} else if (methodCall.method_name() == "getResourceLoaderWrapper") {
auto wrapper = (ResourceLoaderWrapper*)malloc(sizeof(ResourceLoaderWrapper)); auto wrapper = (ResourceLoaderWrapper*)malloc(sizeof(ResourceLoaderWrapper));
wrapper->loadFromOwner = _loadResource; wrapper->loadFromOwner = _loadResource;
wrapper->freeFromOwner = _freeResource, wrapper->freeFromOwner = _freeResource,
@@ -224,7 +179,14 @@ void ThermionFlutterPlugin::HandleMethodCall(
wrapper->freeResource = nullptr; wrapper->freeResource = nullptr;
result->Success(flutter::EncodableValue((int64_t)wrapper)); result->Success(flutter::EncodableValue((int64_t)wrapper));
} else if(methodCall.method_name() == "getSharedContext") { } else if(methodCall.method_name() == "getSharedContext") {
result->Success(NULL); if (!_context) {
#ifdef USE_ANGLE
_context = std::make_unique<FlutterEGLContext>(_pluginRegistrar, _textureRegistrar);
#else
_context = std::make_unique<WGLContext>(_pluginRegistrar, _textureRegistrar);
#endif
}
result->Success(flutter::EncodableValue((int64_t)_context->GetSharedContext()));
} else if (methodCall.method_name() == "resizeWindow") { } else if (methodCall.method_name() == "resizeWindow") {
#if WGL_USE_BACKING_WINDOW #if WGL_USE_BACKING_WINDOW
const auto *args = const auto *args =
@@ -244,20 +206,27 @@ void ThermionFlutterPlugin::HandleMethodCall(
#else #else
result->Error("ERROR", "resizeWindow is only available when using a backing window"); result->Error("ERROR", "resizeWindow is only available when using a backing window");
#endif #endif
} else if (methodCall.method_name() == "createTexture") {
CreateTexture(methodCall, std::move(result));
} else if (methodCall.method_name() == "createWindow") { } else if (methodCall.method_name() == "createWindow") {
CreateTexture(methodCall, std::move(result)); CreateTexture(methodCall, std::move(result));
} else if (methodCall.method_name() == "destroyWindow") { } else if (methodCall.method_name() == "destroyWindow") {
DestroyTexture(methodCall, std::move(result)); DestroyTexture(methodCall, std::move(result));
} else if (methodCall.method_name() == "getRenderCallback") { } else if (methodCall.method_name() == "markTextureFrameAvailable") {
flutter::EncodableList resultList; if (_context) {
#if !ANGLE && WGL_USE_BACKING_WINDOW auto flutterTextureId = _context->GetFlutterTextureId();
resultList.push_back(flutter::EncodableValue((int64_t)nullptr)); if(flutterTextureId == -1) {
resultList.push_back(flutter::EncodableValue((int64_t)nullptr)); std::cout << "Bad texture" << std::endl;
#else return;
resultList.push_back(flutter::EncodableValue((int64_t)&render_callback)); }
resultList.push_back(flutter::EncodableValue((int64_t)this)); #ifdef USE_ANGLE
_context->RenderCallback();
#endif #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") { } else if (methodCall.method_name() == "getDriverPlatform") {
#ifdef USE_ANGLE #ifdef USE_ANGLE
result->Success(flutter::EncodableValue((int64_t)_context->GetPlatform())); result->Success(flutter::EncodableValue((int64_t)_context->GetPlatform()));

View File

@@ -42,7 +42,7 @@ class ThermionFlutterTextureBackedPlatform
// this implementation renders directly into a texture/render target // this implementation renders directly into a texture/render target
// we still need to create a (headless) swapchain, but the actual dimensions // we still need to create a (headless) swapchain, but the actual dimensions
// don't matter // don't matter
if (Platform.isMacOS || Platform.isIOS) { if (Platform.isMacOS || Platform.isIOS || Platform.isWindows) {
_swapChain = await viewer.createHeadlessSwapChain(1, 1); _swapChain = await viewer.createHeadlessSwapChain(1, 1);
} }
@@ -57,7 +57,7 @@ class ThermionFlutterTextureBackedPlatform
Future<ThermionFlutterTexture?> createTexture( Future<ThermionFlutterTexture?> createTexture(
t.View view, int width, int height) async { t.View view, int width, int height) async {
var texture = FlutterPlatformTexture(channel, viewer!, view, 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); await texture.resize(width, height, 0, 0);
return texture; return texture;
} }

View File

@@ -7,6 +7,8 @@ import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dar
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:thermion_flutter_platform_interface/thermion_flutter_window.dart'; import 'package:thermion_flutter_platform_interface/thermion_flutter_window.dart';
import 'platform_texture.dart';
/// ///
/// A Windows-only implementation of [ThermionFlutterPlatform] that uses /// A Windows-only implementation of [ThermionFlutterPlatform] that uses
/// a Flutter platform channel to create a rendering context, /// a Flutter platform channel to create a rendering context,
@@ -46,8 +48,10 @@ class ThermionFlutterWindows
/// Not supported on Windows. Throws an exception. /// Not supported on Windows. Throws an exception.
/// ///
@override @override
Future<ThermionFlutterTexture?> createTexture(View view, int width, int height) { Future<ThermionFlutterTexture?> createTexture(View view, int width, int height) async {
throw UnimplementedError(); var texture = FlutterPlatformTexture(channel, viewer!, view, null);
await texture.resize(width, height, 0, 0);
return texture;
} }

View File

@@ -17,7 +17,7 @@ flutter:
macos: macos:
dartPluginClass: ThermionFlutterTextureBackedPlatform dartPluginClass: ThermionFlutterTextureBackedPlatform
windows: windows:
dartPluginClass: ThermionFlutterWindows dartPluginClass: ThermionFlutterTextureBackedPlatform
dependencies: dependencies:
flutter: flutter: