зеркало из https://github.com/mozilla/gecko-dev.git
171 строка
4.2 KiB
C++
171 строка
4.2 KiB
C++
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||
|
|
||
|
#include "base/platform_thread.h"
|
||
|
#include "WinCompositorWindowThread.h"
|
||
|
#include "mozilla/layers/SynchronousTask.h"
|
||
|
#include "mozilla/StaticPtr.h"
|
||
|
#include "mtransport/runnable_utils.h"
|
||
|
|
||
|
namespace mozilla {
|
||
|
namespace widget {
|
||
|
|
||
|
static StaticRefPtr<WinCompositorWindowThread> sWinCompositorWindowThread;
|
||
|
|
||
|
WinCompositorWindowThread::WinCompositorWindowThread(base::Thread* aThread)
|
||
|
: mThread(aThread)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
WinCompositorWindowThread::~WinCompositorWindowThread()
|
||
|
{
|
||
|
delete mThread;
|
||
|
}
|
||
|
|
||
|
/* static */ WinCompositorWindowThread*
|
||
|
WinCompositorWindowThread::Get()
|
||
|
{
|
||
|
return sWinCompositorWindowThread;
|
||
|
}
|
||
|
|
||
|
/* static */ void
|
||
|
WinCompositorWindowThread::Start()
|
||
|
{
|
||
|
MOZ_ASSERT(NS_IsMainThread());
|
||
|
MOZ_ASSERT(!sWinCompositorWindowThread);
|
||
|
|
||
|
base::Thread* thread = new base::Thread("Renderer");
|
||
|
|
||
|
base::Thread::Options options;
|
||
|
// HWND requests ui thread.
|
||
|
options.message_loop_type = MessageLoop::TYPE_UI;
|
||
|
|
||
|
if (!thread->StartWithOptions(options)) {
|
||
|
delete thread;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
sWinCompositorWindowThread = new WinCompositorWindowThread(thread);
|
||
|
}
|
||
|
|
||
|
/* static */ void
|
||
|
WinCompositorWindowThread::ShutDown()
|
||
|
{
|
||
|
MOZ_ASSERT(NS_IsMainThread());
|
||
|
MOZ_ASSERT(sWinCompositorWindowThread);
|
||
|
|
||
|
layers::SynchronousTask task("WinCompositorWindowThread");
|
||
|
RefPtr<Runnable> runnable = WrapRunnable(
|
||
|
RefPtr<WinCompositorWindowThread>(sWinCompositorWindowThread.get()),
|
||
|
&WinCompositorWindowThread::ShutDownTask,
|
||
|
&task);
|
||
|
sWinCompositorWindowThread->Loop()->PostTask(runnable.forget());
|
||
|
task.Wait();
|
||
|
|
||
|
sWinCompositorWindowThread = nullptr;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
WinCompositorWindowThread::ShutDownTask(layers::SynchronousTask* aTask)
|
||
|
{
|
||
|
layers::AutoCompleteTask complete(aTask);
|
||
|
MOZ_ASSERT(IsInCompositorWindowThread());
|
||
|
}
|
||
|
|
||
|
/* static */ MessageLoop*
|
||
|
WinCompositorWindowThread::Loop()
|
||
|
{
|
||
|
return sWinCompositorWindowThread ? sWinCompositorWindowThread->mThread->message_loop() : nullptr;
|
||
|
}
|
||
|
|
||
|
/* static */ bool
|
||
|
WinCompositorWindowThread::IsInCompositorWindowThread()
|
||
|
{
|
||
|
return sWinCompositorWindowThread && sWinCompositorWindowThread->mThread->thread_id() == PlatformThread::CurrentId();
|
||
|
}
|
||
|
|
||
|
const wchar_t kClassNameCompositor[] = L"MozillaCompositorWindowClass";
|
||
|
|
||
|
ATOM g_compositor_window_class;
|
||
|
|
||
|
// This runs on the window owner thread.
|
||
|
void InitializeWindowClass() {
|
||
|
|
||
|
if (g_compositor_window_class) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
WNDCLASSW wc;
|
||
|
wc.style = CS_OWNDC;
|
||
|
wc.lpfnWndProc = ::DefWindowProcW;
|
||
|
wc.cbClsExtra = 0;
|
||
|
wc.cbWndExtra = 0;
|
||
|
wc.hInstance = GetModuleHandle(nullptr);
|
||
|
wc.hIcon = nullptr;
|
||
|
wc.hCursor = nullptr;
|
||
|
wc.hbrBackground = nullptr;
|
||
|
wc.lpszMenuName = nullptr;
|
||
|
wc.lpszClassName = kClassNameCompositor;
|
||
|
g_compositor_window_class = ::RegisterClassW(&wc);
|
||
|
}
|
||
|
|
||
|
/* static */ HWND
|
||
|
WinCompositorWindowThread::CreateCompositorWindow(HWND aParentWnd)
|
||
|
{
|
||
|
MOZ_ASSERT(Loop());
|
||
|
MOZ_ASSERT(aParentWnd);
|
||
|
|
||
|
if (!Loop()) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
layers::SynchronousTask task("Create compositor window");
|
||
|
|
||
|
HWND compositorWnd = nullptr;
|
||
|
|
||
|
RefPtr<Runnable> runnable =
|
||
|
NS_NewRunnableFunction("WinCompositorWindowThread::CreateCompositorWindow::Runnable", [&]() {
|
||
|
layers::AutoCompleteTask complete(&task);
|
||
|
|
||
|
InitializeWindowClass();
|
||
|
|
||
|
compositorWnd =
|
||
|
::CreateWindowEx(WS_EX_NOPARENTNOTIFY,
|
||
|
kClassNameCompositor,
|
||
|
nullptr,
|
||
|
WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE,
|
||
|
0, 0, 1, 1,
|
||
|
aParentWnd, 0, GetModuleHandle(nullptr), 0);
|
||
|
});
|
||
|
|
||
|
Loop()->PostTask(runnable.forget());
|
||
|
|
||
|
task.Wait();
|
||
|
|
||
|
return compositorWnd;
|
||
|
}
|
||
|
|
||
|
/* static */ void
|
||
|
WinCompositorWindowThread::DestroyCompositorWindow(HWND aWnd)
|
||
|
{
|
||
|
MOZ_ASSERT(aWnd);
|
||
|
MOZ_ASSERT(Loop());
|
||
|
|
||
|
if (!Loop()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RefPtr<Runnable> runnable =
|
||
|
NS_NewRunnableFunction("WinCompositorWidget::CreateNativeWindow::Runnable", [aWnd]() {
|
||
|
::DestroyWindow(aWnd);
|
||
|
});
|
||
|
|
||
|
Loop()->PostTask(runnable.forget());
|
||
|
}
|
||
|
|
||
|
} // namespace widget
|
||
|
} // namespace mozilla
|