From 14d71891d3b3eb06619e6ac34dc823030e4ef4fd Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 14 Dec 2022 14:48:45 +0800 Subject: [PATCH] add resize implementation on Linux and texture/render target destruction etc --- ios/src/FilamentViewer.cpp | 9 ++++ linux/filament_texture.cc | 27 +++++++---- .../polyvox_filament/filament_texture.h | 3 +- linux/polyvox_filament_plugin.cc | 47 +++++++++++++++---- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 0d51f440..92349ae3 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -573,6 +573,15 @@ void FilamentViewer::createRenderTarget(uint32_t glTextureId, uint32_t width, ui } void FilamentViewer::destroySwapChain() { + if(_rt) { + _view->setRenderTarget(nullptr); + _engine->destroy(_rtDepth); + _engine->destroy(_rtColor); + _engine->destroy(_rt); + _rt = nullptr; + _rtDepth = nullptr; + _rtColor = nullptr; + } if (_swapChain) { _engine->destroy(_swapChain); _swapChain = nullptr; diff --git a/linux/filament_texture.cc b/linux/filament_texture.cc index ead32eaf..b9efdadc 100644 --- a/linux/filament_texture.cc +++ b/linux/filament_texture.cc @@ -32,7 +32,9 @@ filament_texture_populate (FlTextureGL *texture, } void filament_texture_gl_dispose(GObject* object) { - G_OBJECT_CLASS(filament_texture_gl_parent_class)->dispose(object); + auto filamentTextureGL = FILAMENT_TEXTURE_GL(object); + glDeleteTextures(1, &(filamentTextureGL->texture_id)); + filamentTextureGL->texture_id = 0; } void filament_texture_gl_class_init(FilamentTextureGLClass* klass) { @@ -42,10 +44,15 @@ void filament_texture_gl_class_init(FilamentTextureGLClass* klass) { void filament_texture_gl_init(FilamentTextureGL* self) { } -FLUTTER_PLUGIN_EXPORT FlTexture* create_filament_texture(uint32_t width, uint32_t height, FlTextureRegistrar* registrar) { +void destroy_filament_texture(FlTexture* texture, FlTextureRegistrar* registrar) { + fl_texture_registrar_unregister_texture(registrar, texture); +} + +FlTexture* create_filament_texture(uint32_t width, uint32_t height, FlTextureRegistrar* registrar) { auto textureGL = FILAMENT_TEXTURE_GL(g_object_new(filament_texture_gl_get_type(), nullptr)); textureGL->width = width; textureGL->height = height; + textureGL->registrar = registrar; g_autoptr(FlTexture) texture = FL_TEXTURE(textureGL); @@ -61,13 +68,13 @@ FLUTTER_PLUGIN_EXPORT FlTexture* create_filament_texture(uint32_t width, uint32_ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, textureGL->width, textureGL->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - if(fl_texture_registrar_register_texture(registrar, texture) == TRUE) { + if(fl_texture_registrar_register_texture(registrar, texture) == TRUE) { - if(fl_texture_registrar_mark_texture_frame_available(registrar, - texture) != TRUE) { - std::cout << "FAILED" << std::endl; - return nullptr; - } - } - return texture; + if(fl_texture_registrar_mark_texture_frame_available(registrar, + texture) != TRUE) { + std::cout << "FAILED" << std::endl; + return nullptr; + } + } + return texture; } \ No newline at end of file diff --git a/linux/include/polyvox_filament/filament_texture.h b/linux/include/polyvox_filament/filament_texture.h index 6cb3f550..2db13c43 100644 --- a/linux/include/polyvox_filament/filament_texture.h +++ b/linux/include/polyvox_filament/filament_texture.h @@ -26,6 +26,7 @@ struct _FilamentTextureGL { GLuint texture_id; uint32_t width; uint32_t height; + FlTextureRegistrar* registrar; }; typedef struct _FilamentTextureGL FilamentTextureGL; @@ -37,12 +38,12 @@ typedef struct { uint32_t* width, uint32_t* height, GError** error); - GLuint texture_id; } FilamentTextureGLClass; G_END_DECLS FLUTTER_PLUGIN_EXPORT FlTexture* create_filament_texture(uint32_t width, uint32_t height, FlTextureRegistrar* registrar); +FLUTTER_PLUGIN_EXPORT void destroy_filament_texture(FlTexture* texture, FlTextureRegistrar* registrar); #endif \ No newline at end of file diff --git a/linux/polyvox_filament_plugin.cc b/linux/polyvox_filament_plugin.cc index 157fa2cd..7c0c231a 100644 --- a/linux/polyvox_filament_plugin.cc +++ b/linux/polyvox_filament_plugin.cc @@ -38,9 +38,11 @@ struct _PolyvoxFilamentPlugin { GObject parent_instance; FlTextureRegistrar* texture_registrar; FlView* fl_view; - FlTexture* texture; void* _viewer; + + double width; + double height; }; G_DEFINE_TYPE(PolyvoxFilamentPlugin, polyvox_filament_plugin, g_object_get_type()) @@ -72,7 +74,9 @@ static FlMethodResponse* _initialize(PolyvoxFilamentPlugin* self, FlMethodCall* const double width = fl_value_get_float(fl_value_get_list_value(args, 0)); const double height = fl_value_get_float(fl_value_get_list_value(args, 1)); - + self->width = width; + self->height = height; + auto texture = create_filament_texture(uint32_t(width), uint32_t(height), self->texture_registrar); //auto texture = create_filament_pb_texture(uint32_t(width), uint32_t(height), self->texture_registrar); self->texture = texture; @@ -364,6 +368,37 @@ static FlMethodResponse* _get_target_names(PolyvoxFilamentPlugin* self, FlMethod return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); } +// TODO - defer the destruction of the old texture until this call has returned +// otherwise the front-end may render using the destroyed texture ID for a single frame (hopefully no more) +static FlMethodResponse* _resize(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { + FlValue* args = fl_method_call_get_args(method_call); + + const double width = fl_value_get_float(fl_value_get_list_value(args, 0)); + const double height = fl_value_get_float(fl_value_get_list_value(args, 1)); + + if(width != self->width || height != self->height) { + + destroy_swap_chain(self->_viewer); + + destroy_filament_texture(self->texture, self->texture_registrar); + + self->texture = create_filament_texture(uint32_t(width), uint32_t(height), self->texture_registrar); + + create_swap_chain(self->_viewer, nullptr, width, height); + create_render_target(self->_viewer, ((FilamentTextureGL*)self->texture)->texture_id,width,height); + + update_viewport_and_camera_projection(self->_viewer, width, height, 1.0f); + + std::cout << "Created new texture " << self->texture << std::endl; + } + + g_autoptr(FlValue) result = + fl_value_new_int(reinterpret_cast(self->texture)); + + return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); +} + + // Called when a method call is received from Flutter. static void polyvox_filament_plugin_handle_method_call( PolyvoxFilamentPlugin* self, @@ -380,13 +415,7 @@ static void polyvox_filament_plugin_handle_method_call( } else if(strcmp(method, "removeSkybox") == 0) { response = _removeSkybox(self, method_call); } else if(strcmp(method, "resize") == 0) { - // val args = call.arguments as ArrayList - // val width = args[0] - // val height = args[1] - // val scale = if(args.size > 2) (args[2] as Double).toFloat() else 1.0f - // surfaceTexture!!.setDefaultBufferSize(width, height) - // _lib.update_viewport_and_camera_projection(_viewer!!, width, height, scale); - // result.success(null) + response = _resize(self, method_call); } else if(strcmp(method, "render") == 0) { render(self->_viewer, 0); g_autoptr(FlValue) result = fl_value_new_string("OK");