Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fabric] Move playground compositor to a background thread #12073

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,6 @@ struct CompReactPackageProvider
}
};

winrt::Windows::System::DispatcherQueueController g_dispatcherQueueController{nullptr};
winrt::Windows::UI::Composition::Compositor g_compositor{nullptr};

constexpr auto WindowDataProperty = L"WindowData";

int RunPlayground(int showCmd, bool useWebDebugger);
Expand All @@ -197,6 +194,7 @@ struct WindowData {
winrt::Microsoft::ReactNative::CompositionHwndHost m_CompositionHwndHost{nullptr};
winrt::Microsoft::ReactNative::ReactNativeHost m_host{nullptr};
winrt::Microsoft::ReactNative::ReactInstanceSettings m_instanceSettings{nullptr};
winrt::Windows::System::DispatcherQueueController m_dispatcherQueueController{nullptr};

bool m_useWebDebugger{false};
bool m_fastRefreshEnabled{true};
Expand All @@ -205,11 +203,7 @@ struct WindowData {
uint16_t m_debuggerPort{defaultDebuggerPort};
xaml::ElementTheme m_theme{xaml::ElementTheme::Default};

WindowData(const winrt::Microsoft::ReactNative::CompositionHwndHost &compHost) : m_CompositionHwndHost(compHost) {
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext(
InstanceSettings().Properties(),
winrt::Microsoft::ReactNative::Composition::CompositionContextHelper::CreateContext(g_compositor));
}
WindowData(const winrt::Microsoft::ReactNative::CompositionHwndHost &compHost) : m_CompositionHwndHost(compHost) {}

static WindowData *GetFromWindow(HWND hwnd) {
auto data = reinterpret_cast<WindowData *>(GetProp(hwnd, WindowDataProperty));
Expand Down Expand Up @@ -471,7 +465,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
hwnd, LOWORD(wparam), reinterpret_cast<HWND>(lparam), HIWORD(wparam));
}
case WM_DESTROY: {
delete WindowData::GetFromWindow(hwnd);
windowData->m_dispatcherQueueController.ShutdownQueueAsync();
delete windowData;
SetProp(hwnd, WindowDataProperty, 0);
PostQuitMessage(0);
return 0;
Expand Down Expand Up @@ -505,10 +500,43 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)

constexpr PCWSTR c_windowClassName = L"MS_REACTNATIVE_PLAYGROUND_COMPOSITION";

// The compositor could be running on a background or foreground thread.
// Office runs it on a background thread, so its useful to be able to test that case
void CreateCompositor(bool background, WindowData *windowData) {
DispatcherQueueOptions options{
sizeof(DispatcherQueueOptions), /* dwSize */
background ? DQTYPE_THREAD_DEDICATED : DQTYPE_THREAD_CURRENT, /* threadType */
DQTAT_COM_STA /* apartmentType */
acoates-ms marked this conversation as resolved.
Show resolved Hide resolved
};

// Need to have a Dispatcher on the current thread to be able to create a Compositor
winrt::check_hresult(CreateDispatcherQueueController(
options,
reinterpret_cast<ABI::Windows::System::IDispatcherQueueController **>(
winrt::put_abi(windowData->m_dispatcherQueueController))));

if (background) {
windowData->m_dispatcherQueueController.DispatcherQueue().TryEnqueue([windowData]() {
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext(
windowData->InstanceSettings().Properties(),
winrt::Microsoft::ReactNative::Composition::CompositionContextHelper::CreateContext(
winrt::Windows::UI::Composition::Compositor()));
});
} else {
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext(
windowData->InstanceSettings().Properties(),
winrt::Microsoft::ReactNative::Composition::CompositionContextHelper::CreateContext(
winrt::Windows::UI::Composition::Compositor()));
}
}

int RunPlayground(int showCmd, bool useWebDebugger) {
constexpr PCWSTR appName = L"React Native Playground (Composition)";

auto windowData = std::make_unique<WindowData>(winrt::Microsoft::ReactNative::CompositionHwndHost());

CreateCompositor(true /*background compositor*/, windowData.get());

HWND hwnd = CreateWindow(
c_windowClassName,
appName,
Expand Down Expand Up @@ -560,18 +588,5 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR
WINRT_VERIFY(classId);
winrt::check_win32(!classId);

DispatcherQueueOptions options{
sizeof(DispatcherQueueOptions), /* dwSize */
DQTYPE_THREAD_CURRENT, /* threadType */
DQTAT_COM_ASTA /* apartmentType */
};

// Need to have a Dispatcher on the current thread to be able to create a Compositor
winrt::check_hresult(CreateDispatcherQueueController(
options,
reinterpret_cast<ABI::Windows::System::IDispatcherQueueController **>(
winrt::put_abi(g_dispatcherQueueController))));

g_compositor = winrt::Windows::UI::Composition::Compositor();
return RunPlayground(showCmd, false);
}