Skip to content

Commit

Permalink
fix: [windows] Fix TextureRender crash (#1999)
Browse files Browse the repository at this point in the history
We can't delete the `TextureRender` in the
`VideoViewController::DestroyTextureRender`, because the
`flutter::TextureRegistrar::UnregisterTexture` is called in the Flutter
rasterizer thread, it's not thread-safe.

We change the `VideoViewController::renderers_` to `std::map<int64_t,
TextureRender *>`, which holds the raw pointer `TextureRender *`, and
delete the `TextureRender ` in the
`flutter::TextureRegistrar::UnregisterTexture` callback which introduces
from Flutter SDK 3.7.0.
  • Loading branch information
littleGnAl authored Sep 6, 2024
1 parent 3cc945b commit 0edbfe5
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 15 deletions.
7 changes: 6 additions & 1 deletion example/windows/flutter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
# https://github.com/flutter/flutter/issues/57146.
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")

# Set fallback configurations for older versions of the flutter tool.
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
set(FLUTTER_TARGET_PLATFORM "windows-x64")
endif()

# === Flutter Library ===
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")

Expand Down Expand Up @@ -92,7 +97,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
windows-x64 $<CONFIG>
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
Expand Down
10 changes: 5 additions & 5 deletions example/windows/runner/Runner.rc
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico"
// Version
//

#ifdef FLUTTER_BUILD_NUMBER
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
#else
#define VERSION_AS_NUMBER 1,0,0
#define VERSION_AS_NUMBER 1,0,0,0
#endif

#ifdef FLUTTER_BUILD_NAME
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
#if defined(FLUTTER_VERSION)
#define VERSION_AS_STRING FLUTTER_VERSION
#else
#define VERSION_AS_STRING "1.0.0"
#endif
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ version: 6.3.2
homepage: https://www.agora.io
repository: https://github.com/AgoraIO-Extensions/Agora-Flutter-SDK/tree/main
environment:
sdk: '>=2.14.0 <3.0.0'
flutter: '>=2.5.0'
sdk: '>=2.17.0 <4.0.0'
flutter: '>=3.0.0'
dependencies:
flutter:
sdk: flutter
Expand Down
4 changes: 2 additions & 2 deletions windows/include/agora_rtc_engine/video_view_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class VideoViewController
private:
flutter::BinaryMessenger *messenger_;
flutter::TextureRegistrar *texture_registrar_;
std::map<int64_t, std::unique_ptr<TextureRender>> renderers_;
std::map<int64_t, TextureRender *> renderers_;

void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue> &method_call,
Expand All @@ -29,7 +29,7 @@ class VideoViewController
const intptr_t &irisRtcRenderingHandle,
unsigned int uid,
const std::string &channelId,
unsigned int videoSourceType,
unsigned int videoSourceType,
unsigned int videoViewSetupMode);

bool DestroyTextureRender(int64_t textureId);
Expand Down
5 changes: 3 additions & 2 deletions windows/texture_render.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ TextureRender::TextureRender(flutter::BinaryMessenger *messenger,

TextureRender::~TextureRender()
{
Dispose();
}

int64_t TextureRender::texture_id() { return texture_id_; }
Expand Down Expand Up @@ -150,7 +149,9 @@ void TextureRender::Dispose()

if (registrar_ && texture_id_ != -1)
{
registrar_->UnregisterTexture(texture_id_);
auto self = this;
registrar_->UnregisterTexture(texture_id_, [self]()
{ delete self; });

registrar_ = nullptr;
texture_id_ = -1;
Expand Down
8 changes: 5 additions & 3 deletions windows/video_view_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ VideoViewController::VideoViewController(

VideoViewController::~VideoViewController()
{
Dispose();
}

void VideoViewController::HandleMethodCall(
Expand Down Expand Up @@ -154,15 +155,16 @@ int64_t VideoViewController::CreateTextureRender(
unsigned int videoViewSetupMode)
{
agora::iris::IrisRtcRendering *iris_rtc_rendering = reinterpret_cast<agora::iris::IrisRtcRendering *>(irisRtcRenderingHandle);
std::unique_ptr<TextureRender> textureRender = std::make_unique<TextureRender>(
auto textureRender = new TextureRender(
messenger_,
texture_registrar_,
iris_rtc_rendering);

int64_t texture_id = textureRender->texture_id();

textureRender.get()->UpdateData(uid, channelId, videoSourceType, videoViewSetupMode);
textureRender->UpdateData(uid, channelId, videoSourceType, videoViewSetupMode);

renderers_[texture_id] = std::move(textureRender);
renderers_[texture_id] = textureRender;
return texture_id;
}

Expand Down

0 comments on commit 0edbfe5

Please sign in to comment.