Skip to content

Commit 0845430

Browse files
RN Windows/extra rendering frame bug (#494)
* RN Windows/extra rendering frame * rendering revoker * Initialize method Co-authored-by: Cedric Guillemet <[email protected]>
1 parent 9651c11 commit 0845430

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

Modules/@babylonjs/react-native-windows/windows/BabylonReactNative/EngineView.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,24 @@ namespace winrt::BabylonReactNative::implementation {
4040
// TODO: move to std::thread compared to consuming ThreadPool resources once engine lifecycle bugs are addressed and EngineView's destructor can be successfully invoked.
4141
_inputLoopWorker = ThreadPool::RunAsync(workItemHandler, WorkItemPriority::High, WorkItemOptions::TimeSliced);
4242

43-
_revokerData.RenderingRevoker = CompositionTarget::Rendering(winrt::auto_revoke, [weakThis{ this->get_weak() }](auto const&, auto const&)
44-
{
45-
if (auto trueThis = weakThis.get())
46-
{
47-
trueThis->OnRendering();
43+
_revokerData.LoadedEventToken = Loaded(winrt::auto_revoke, [this, ref = get_weak()](auto const&, auto const&) {
44+
if (auto self = ref.get())
45+
{
46+
self->_revokerData.RenderingRevoker = CompositionTarget::Rendering(
47+
winrt::auto_revoke,
48+
[weakThis{self->get_weak()}](auto const&, auto const&)
49+
{
50+
if (auto trueThis = weakThis.get())
51+
{
52+
trueThis->OnRendering();
53+
}
54+
});
55+
}
56+
});
57+
58+
_revokerData.UnloadedEventToken = Unloaded(winrt::auto_revoke, [ref = get_weak()](auto const&, auto const&) {
59+
if (auto self = ref.get()) {
60+
self->_revokerData.RenderingRevoker.revoke();
4861
}
4962
});
5063
}

Modules/@babylonjs/react-native-windows/windows/BabylonReactNative/EngineView.h

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace winrt::BabylonReactNative::implementation {
2727
struct RevokerData
2828
{
2929
winrt::Windows::UI::Xaml::FrameworkElement::SizeChanged_revoker SizeChangedRevoker{};
30+
winrt::Windows::UI::Xaml::FrameworkElement::Unloaded_revoker UnloadedEventToken{};
31+
winrt::Windows::UI::Xaml::FrameworkElement::Loaded_revoker LoadedEventToken{};
3032
winrt::Windows::UI::Core::CoreIndependentInputSource::PointerPressed_revoker PointerPressedRevoker{};
3133
winrt::Windows::UI::Core::CoreIndependentInputSource::PointerMoved_revoker PointerMovedRevoker{};
3234
winrt::Windows::UI::Core::CoreIndependentInputSource::PointerReleased_revoker PointerReleasedRevoker{};

Modules/@babylonjs/react-native/shared/BabylonNative.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ namespace BabylonNative
115115
});
116116
}
117117
m_isRenderingEnabled = true;
118-
m_pendingReset = false;
118+
m_newEngine = false;
119119
}
120120

121121
void UpdateMSAA(uint8_t value)
@@ -138,12 +138,7 @@ namespace BabylonNative
138138

139139
void RenderView()
140140
{
141-
// m_pendingReset becomes true when a resetView call has been performed and no UpdateView has been performed.
142-
// This happens with a fast refresh when the view is not unmounted and it's still available for rendering.
143-
// UpdateView will set back m_pendingReset to false in case the view is unmounted/mounted with Engine.Dispose for example.
144-
// With fast refresh, we have to do that work on the UI/render thread, and UpdateView is not called in that case,
145-
// so RenderView is pretty much the only option. Specifically, it must be done on the UI/render thread and so RenderView is the only hook we have.
146-
if (m_pendingReset)
141+
if (m_newEngine)
147142
{
148143
UpdateGraphicsConfiguration();
149144
}
@@ -158,13 +153,17 @@ namespace BabylonNative
158153
}
159154
}
160155

156+
void Initialize()
157+
{
158+
m_newEngine = true;
159+
}
160+
161161
void ResetView()
162162
{
163163
if (g_graphics)
164164
{
165165
g_nativeCanvas->FlushGraphicResources();
166166
g_graphics->DisableRendering();
167-
m_pendingReset = true;
168167
}
169168

170169
m_isRenderingEnabled = false;
@@ -266,11 +265,11 @@ namespace BabylonNative
266265
std::optional<Babylon::Plugins::NativeXr> m_nativeXr{};
267266

268267
Babylon::Graphics::WindowConfiguration m_windowConfig{};
269-
bool m_pendingReset{};
270268

271269
std::shared_ptr<bool> m_isXRActive{};
272270
uint8_t mMSAAValue{};
273271
bool mAlphaPremultiplied{};
272+
bool m_newEngine{};
274273
};
275274

276275
namespace
@@ -287,6 +286,10 @@ namespace BabylonNative
287286
jsiRuntime.global().setProperty(jsiRuntime, JS_INSTANCE_NAME, jsi::Object::createFromHostObject(jsiRuntime, nativeModule));
288287
g_nativeModule = nativeModule;
289288
}
289+
if (auto nativeModule{ g_nativeModule.lock() })
290+
{
291+
nativeModule->Initialize();
292+
}
290293
}
291294

292295
void Deinitialize()

0 commit comments

Comments
 (0)