Skip to content

Commit

Permalink
RN Windows/extra rendering frame bug (#494)
Browse files Browse the repository at this point in the history
* RN Windows/extra rendering frame

* rendering revoker

* Initialize method

Co-authored-by: Cedric Guillemet <[email protected]>
  • Loading branch information
CedricGuillemet and CedricGuillemetMS authored Nov 4, 2022
1 parent 9651c11 commit 0845430
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,24 @@ namespace winrt::BabylonReactNative::implementation {
// TODO: move to std::thread compared to consuming ThreadPool resources once engine lifecycle bugs are addressed and EngineView's destructor can be successfully invoked.
_inputLoopWorker = ThreadPool::RunAsync(workItemHandler, WorkItemPriority::High, WorkItemOptions::TimeSliced);

_revokerData.RenderingRevoker = CompositionTarget::Rendering(winrt::auto_revoke, [weakThis{ this->get_weak() }](auto const&, auto const&)
{
if (auto trueThis = weakThis.get())
{
trueThis->OnRendering();
_revokerData.LoadedEventToken = Loaded(winrt::auto_revoke, [this, ref = get_weak()](auto const&, auto const&) {
if (auto self = ref.get())
{
self->_revokerData.RenderingRevoker = CompositionTarget::Rendering(
winrt::auto_revoke,
[weakThis{self->get_weak()}](auto const&, auto const&)
{
if (auto trueThis = weakThis.get())
{
trueThis->OnRendering();
}
});
}
});

_revokerData.UnloadedEventToken = Unloaded(winrt::auto_revoke, [ref = get_weak()](auto const&, auto const&) {
if (auto self = ref.get()) {
self->_revokerData.RenderingRevoker.revoke();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ namespace winrt::BabylonReactNative::implementation {
struct RevokerData
{
winrt::Windows::UI::Xaml::FrameworkElement::SizeChanged_revoker SizeChangedRevoker{};
winrt::Windows::UI::Xaml::FrameworkElement::Unloaded_revoker UnloadedEventToken{};
winrt::Windows::UI::Xaml::FrameworkElement::Loaded_revoker LoadedEventToken{};
winrt::Windows::UI::Core::CoreIndependentInputSource::PointerPressed_revoker PointerPressedRevoker{};
winrt::Windows::UI::Core::CoreIndependentInputSource::PointerMoved_revoker PointerMovedRevoker{};
winrt::Windows::UI::Core::CoreIndependentInputSource::PointerReleased_revoker PointerReleasedRevoker{};
Expand Down
21 changes: 12 additions & 9 deletions Modules/@babylonjs/react-native/shared/BabylonNative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ namespace BabylonNative
});
}
m_isRenderingEnabled = true;
m_pendingReset = false;
m_newEngine = false;
}

void UpdateMSAA(uint8_t value)
Expand All @@ -138,12 +138,7 @@ namespace BabylonNative

void RenderView()
{
// m_pendingReset becomes true when a resetView call has been performed and no UpdateView has been performed.
// This happens with a fast refresh when the view is not unmounted and it's still available for rendering.
// UpdateView will set back m_pendingReset to false in case the view is unmounted/mounted with Engine.Dispose for example.
// With fast refresh, we have to do that work on the UI/render thread, and UpdateView is not called in that case,
// 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.
if (m_pendingReset)
if (m_newEngine)
{
UpdateGraphicsConfiguration();
}
Expand All @@ -158,13 +153,17 @@ namespace BabylonNative
}
}

void Initialize()
{
m_newEngine = true;
}

void ResetView()
{
if (g_graphics)
{
g_nativeCanvas->FlushGraphicResources();
g_graphics->DisableRendering();
m_pendingReset = true;
}

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

Babylon::Graphics::WindowConfiguration m_windowConfig{};
bool m_pendingReset{};

std::shared_ptr<bool> m_isXRActive{};
uint8_t mMSAAValue{};
bool mAlphaPremultiplied{};
bool m_newEngine{};
};

namespace
Expand All @@ -287,6 +286,10 @@ namespace BabylonNative
jsiRuntime.global().setProperty(jsiRuntime, JS_INSTANCE_NAME, jsi::Object::createFromHostObject(jsiRuntime, nativeModule));
g_nativeModule = nativeModule;
}
if (auto nativeModule{ g_nativeModule.lock() })
{
nativeModule->Initialize();
}
}

void Deinitialize()
Expand Down

0 comments on commit 0845430

Please sign in to comment.