From 3f988a119cac97648cacadc46e4a8fb1037f4045 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Tue, 24 Oct 2023 12:26:07 +1100 Subject: [PATCH] FlutterAngleTexture invoke resize callback on size change, cleanup on destruction and call glFinish in RenderCallback FlutterAngleTexture invoke resize callback on size change, cleanup on destruction and call glFinish in RenderCallback move OpenGlTextureBuffer cleanup to destructor --- windows/flutter_angle_texture.cpp | 29 +++++++++++++----- windows/flutter_angle_texture.h | 5 +++- windows/opengl_texture_buffer.cpp | 13 +++++++- windows/polyvox_filament_plugin.cpp | 46 +++++++++++------------------ windows/polyvox_filament_plugin.h | 5 +++- 5 files changed, 59 insertions(+), 39 deletions(-) diff --git a/windows/flutter_angle_texture.cpp b/windows/flutter_angle_texture.cpp index 0b820098..6059ebc5 100644 --- a/windows/flutter_angle_texture.cpp +++ b/windows/flutter_angle_texture.cpp @@ -62,13 +62,23 @@ static void logEglError(const char *name) noexcept { } void FlutterAngleTexture::RenderCallback() { + glFinish(); _D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(), _internalD3DTexture2D.Get()); _D3D11DeviceContext->Flush(); } FlutterAngleTexture::~FlutterAngleTexture() { - + if (_eglDisplay != EGL_NO_DISPLAY && _eglSurface != EGL_NO_SURFACE) { + eglReleaseTexImage(_eglDisplay, _eglSurface, EGL_BACK_BUFFER); + } + auto success = eglDestroySurface(this->_eglDisplay, this->_eglSurface); + if(success != EGL_TRUE) { + std::cout << "Failed to destroy EGL Surface" << std::endl; + } + _internalD3DTexture2D->Release(); + _externalD3DTexture2D->Release(); + glDeleteTextures(1, &this->glTextureId); } FlutterAngleTexture::FlutterAngleTexture( @@ -77,11 +87,13 @@ FlutterAngleTexture::FlutterAngleTexture( std::unique_ptr> result, uint32_t width, uint32_t height, ID3D11Device *D3D11Device, ID3D11DeviceContext *D3D11DeviceContext, EGLConfig eglConfig, - EGLDisplay eglDisplay, EGLContext eglContext) + EGLDisplay eglDisplay, EGLContext eglContext, + std::function onResizeRequested + ) : _pluginRegistrar(pluginRegistrar), _textureRegistrar(textureRegistrar), _width(width), _height(height), _D3D11Device(D3D11Device), _D3D11DeviceContext(D3D11DeviceContext), _eglConfig(eglConfig), - _eglDisplay(eglDisplay), _eglContext(eglContext) { + _eglDisplay(eglDisplay), _eglContext(eglContext), _onResizeRequested(onResizeRequested) { auto d3d11_texture2D_desc = D3D11_TEXTURE2D_DESC{0}; d3d11_texture2D_desc.Width = width; @@ -157,11 +169,11 @@ FlutterAngleTexture::FlutterAngleTexture( EGL_NONE, }; - auto surface = eglCreatePbufferFromClientBuffer( + _eglSurface = eglCreatePbufferFromClientBuffer( _eglDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, _internalD3DTextureHandle, _eglConfig, pbufferAttribs); - if (!eglMakeCurrent(_eglDisplay, surface, surface, _eglContext)) { + if (!eglMakeCurrent(_eglDisplay, _eglSurface, _eglSurface, _eglContext)) { // eglMakeCurrent failed logEglError("eglMakeCurrent"); return; @@ -177,7 +189,7 @@ FlutterAngleTexture::FlutterAngleTexture( } glBindTexture(GL_TEXTURE_2D, glTextureId); - eglBindTexImage(_eglDisplay, surface, EGL_BACK_BUFFER); + eglBindTexImage(_eglDisplay, _eglSurface, EGL_BACK_BUFFER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -210,7 +222,10 @@ FlutterAngleTexture::FlutterAngleTexture( std::make_unique(flutter::GpuSurfaceTexture( kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle, [&](size_t width, size_t height) { - return _textureDescriptor.get(); + if(width != this->_width || height != this->_height) { + this->_onResizeRequested(width, height); + } + return _textureDescriptor.get(); })); flutterTextureId = _textureRegistrar->RegisterTexture(texture.get()); diff --git a/windows/flutter_angle_texture.h b/windows/flutter_angle_texture.h index 3f63bf99..c1e63523 100644 --- a/windows/flutter_angle_texture.h +++ b/windows/flutter_angle_texture.h @@ -38,7 +38,8 @@ class FlutterAngleTexture { ID3D11DeviceContext* D3D11DeviceContext, EGLConfig eglConfig, EGLDisplay eglDisplay, - EGLContext eglContext + EGLContext eglContext, + std::function onResizeRequested ); ~FlutterAngleTexture(); @@ -55,6 +56,7 @@ class FlutterAngleTexture { uint32_t _height = 0; bool logged = false; std::shared_ptr _renderMutex; + std::function _onResizeRequested; // Device ID3D11Device* _D3D11Device = nullptr; @@ -68,6 +70,7 @@ class FlutterAngleTexture { EGLDisplay _eglDisplay = EGL_NO_DISPLAY; EGLContext _eglContext = EGL_NO_CONTEXT; EGLConfig _eglConfig = EGL_NO_CONFIG_KHR; + EGLSurface _eglSurface = EGL_NO_SURFACE; std::unique_ptr _textureDescriptor = nullptr; diff --git a/windows/opengl_texture_buffer.cpp b/windows/opengl_texture_buffer.cpp index 68446311..dfb53e7c 100644 --- a/windows/opengl_texture_buffer.cpp +++ b/windows/opengl_texture_buffer.cpp @@ -126,6 +126,17 @@ OpenGLTextureBuffer::OpenGLTextureBuffer( result->Success(resultList); } -OpenGLTextureBuffer::~OpenGLTextureBuffer() {} +OpenGLTextureBuffer::~OpenGLTextureBuffer() { + HWND hwnd = _pluginRegistrar->GetView()->GetNativeWindow(); + HDC whdc = GetDC(hwnd); + + if (!wglMakeCurrent(whdc, _context)) { + std::cout << "Failed to switch OpenGL context in destructor." << std::endl; + // result->Error("CONTEXT", "Failed to switch OpenGL context.", nullptr); + return; + } + glDeleteTextures(1, &this->_inactive->glTextureId); + wglMakeCurrent(NULL, NULL); +} } // namespace polyvox_filament \ No newline at end of file diff --git a/windows/polyvox_filament_plugin.cpp b/windows/polyvox_filament_plugin.cpp index 30a2a4c5..0c931997 100644 --- a/windows/polyvox_filament_plugin.cpp +++ b/windows/polyvox_filament_plugin.cpp @@ -49,20 +49,21 @@ void PolyvoxFilamentPlugin::RegisterWithRegistrar( &flutter::StandardMethodCodec::GetInstance()); auto plugin = std::make_unique( - registrar->texture_registrar(), registrar); - - channel->SetMethodCallHandler( - [plugin_pointer = plugin.get()](const auto &call, auto result) { - plugin_pointer->HandleMethodCall(call, std::move(result)); - }); + registrar->texture_registrar(), registrar, channel); registrar->AddPlugin(std::move(plugin)); } PolyvoxFilamentPlugin::PolyvoxFilamentPlugin( flutter::TextureRegistrar *textureRegistrar, - flutter::PluginRegistrarWindows *pluginRegistrar) - : _textureRegistrar(textureRegistrar), _pluginRegistrar(pluginRegistrar) {} + flutter::PluginRegistrarWindows *pluginRegistrar, + std::unique_ptr>& channel) + : _textureRegistrar(textureRegistrar), _pluginRegistrar(pluginRegistrar), _channel(std::move(channel)) { + _channel->SetMethodCallHandler( + [=](const auto &call, auto result) { + this->HandleMethodCall(call, std::move(result)); + }); + } PolyvoxFilamentPlugin::~PolyvoxFilamentPlugin() {} @@ -299,8 +300,13 @@ bool PolyvoxFilamentPlugin::MakeD3DTexture(uint32_t width, uint32_t height,std:: _D3D11DeviceContext, _eglConfig, _eglDisplay, - _context - ); + _context, [=](size_t width, size_t height) { + std::vector list; + list.push_back((int64_t)width); + list.push_back((int64_t)height); + auto val = std::make_unique(list); + this->_channel->InvokeMethod("resize", std::move(val), nullptr); + }); return _active->flutterTextureId != -1; } @@ -446,7 +452,6 @@ void PolyvoxFilamentPlugin::DestroyTexture( const flutter::MethodCall &methodCall, std::unique_ptr> result) { - const auto *flutterTextureId = std::get_if(methodCall.arguments()); @@ -470,24 +475,7 @@ void PolyvoxFilamentPlugin::DestroyTexture( _textureRegistrar->UnregisterTexture(_active->flutterTextureId, [=, sharedResult=std::move(sh) ]() { - - #ifdef USE_ANGLE - this->_active = nullptr; - #else - if(this->_inactive) { - HWND hwnd = _pluginRegistrar->GetView()->GetNativeWindow(); - HDC whdc = GetDC(hwnd); - - if (!wglMakeCurrent(whdc, _context)) { - std::cout << "Failed to switch OpenGL context in destructor." << std::endl; - // result->Error("CONTEXT", "Failed to switch OpenGL context.", nullptr); - return; - } - glDeleteTextures(1, &this->_inactive->glTextureId); - wglMakeCurrent(NULL, NULL); - } - this->_inactive = std::move(this->_active); - #endif + this->_inactive = std::move(this->_active); auto unique = std::move(*(sharedResult.get())); unique->Success(flutter::EncodableValue(true)); std::cout << "Unregistered/destroyed texture." << std::endl; diff --git a/windows/polyvox_filament_plugin.h b/windows/polyvox_filament_plugin.h index 078ffb00..84ff9c71 100644 --- a/windows/polyvox_filament_plugin.h +++ b/windows/polyvox_filament_plugin.h @@ -30,7 +30,8 @@ public: static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar); PolyvoxFilamentPlugin(flutter::TextureRegistrar *textureRegistrar, - flutter::PluginRegistrarWindows *registrar); + flutter::PluginRegistrarWindows *registrar, + std::unique_ptr>& channel); virtual ~PolyvoxFilamentPlugin(); // Disallow copy and assign. @@ -44,6 +45,7 @@ public: flutter::PluginRegistrarWindows *_pluginRegistrar; flutter::TextureRegistrar *_textureRegistrar; + std::unique_ptr> _channel; std::map _resources; std::shared_ptr _renderMutex; @@ -66,6 +68,7 @@ public: EGLConfig _eglConfig = NULL; EGLDisplay _eglDisplay = NULL; std::unique_ptr _active = nullptr; + std::unique_ptr _inactive = nullptr; ID3D11Device* _D3D11Device = nullptr; ID3D11DeviceContext* _D3D11DeviceContext = nullptr; filament::backend::Platform* _platform = nullptr;