Bug 1191971 part 1 - Create child window in gpu process r=bas

This commit is contained in:
sotaro 2018-03-29 11:21:47 +09:00
Родитель f627214d56
Коммит 537c379106
8 изменённых файлов: 323 добавлений и 3 удалений

Просмотреть файл

@ -79,6 +79,7 @@
#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop
#ifdef XP_WIN
#include "mozilla/layers/CompositorD3D11.h"
#include "mozilla/widget/WinCompositorWidget.h"
#endif
#include "GeckoProfiler.h"
#include "mozilla/ipc/ProtocolTypes.h"
@ -1749,9 +1750,14 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
MOZ_ASSERT(!mWrBridge);
MOZ_ASSERT(!mCompositor);
MOZ_ASSERT(!mCompositorScheduler);
MOZ_ASSERT(mWidget);
#ifdef XP_WIN
if (XRE_IsGPUProcess() && gfx::gfxVars::UseWebRenderANGLE() && mWidget) {
mWidget->AsWindows()->EnsureCompositorWindow();
}
#endif
RefPtr<widget::CompositorWidget> widget = mWidget;
RefPtr<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(this, Move(widget), aSize);
if (!api) {
@ -1796,6 +1802,11 @@ CompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aA
it->second.mWrBridge = nullptr;
}
}
#ifdef XP_WIN
if (XRE_IsGPUProcess() && gfx::gfxVars::UseWebRenderANGLE() && mWidget) {
mWidget->AsWindows()->DestroyCompositorWindow();
}
#endif
parent->Release(); // IPDL reference
return true;
}

Просмотреть файл

@ -196,6 +196,8 @@ RenderCompositorANGLE::Initialize()
bool
RenderCompositorANGLE::BeginFrame()
{
mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
if (!ResizeBufferIfNeeded()) {
return false;
}

Просмотреть файл

@ -16,6 +16,10 @@
#include "mozilla/webrender/RenderTextureHost.h"
#include "mozilla/widget/CompositorWidget.h"
#ifdef XP_WIN
#include "mozilla/widget/WinCompositorWindowThread.h"
#endif
namespace mozilla {
namespace wr {
@ -60,6 +64,9 @@ RenderThread::Start()
}
sRenderThread = new RenderThread(thread);
#ifdef XP_WIN
widget::WinCompositorWindowThread::Start();
#endif
}
// static
@ -83,6 +90,9 @@ RenderThread::ShutDown()
task.Wait();
sRenderThread = nullptr;
#ifdef XP_WIN
widget::WinCompositorWindowThread::ShutDown();
#endif
}
void

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/widget/PlatformWidgetTypes.h"
#include "nsWindow.h"
#include "VsyncDispatcher.h"
#include "WinCompositorWindowThread.h"
#include <ddraw.h>
@ -24,6 +25,7 @@ WinCompositorWidget::WinCompositorWidget(const WinCompositorWidgetInitData& aIni
: CompositorWidget(aOptions)
, mWidgetKey(aInitData.widgetKey()),
mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
mCompositorWnd(nullptr),
mTransparencyMode(static_cast<nsTransparencyMode>(aInitData.transparencyMode())),
mMemoryDC(nullptr),
mCompositeDC(nullptr),
@ -38,6 +40,11 @@ WinCompositorWidget::WinCompositorWidget(const WinCompositorWidgetInitData& aIni
gfxPlatform::ForceSoftwareVsync();
}
WinCompositorWidget::~WinCompositorWidget()
{
DestroyCompositorWindow();
}
void
WinCompositorWidget::OnDestroyWindow()
{
@ -339,5 +346,48 @@ WinCompositorWidget::IsHidden() const
return ::IsIconic(mWnd);
}
void
WinCompositorWidget::EnsureCompositorWindow()
{
if (mCompositorWnd) {
return;
}
mCompositorWnd = WinCompositorWindowThread::CreateCompositorWindow(mWnd);
MOZ_ASSERT(mCompositorWnd);
}
void
WinCompositorWidget::DestroyCompositorWindow()
{
if (!mCompositorWnd) {
return;
}
WinCompositorWindowThread::DestroyCompositorWindow(mCompositorWnd);
mCompositorWnd = nullptr;
}
void
WinCompositorWidget::UpdateCompositorWndSizeIfNecessary()
{
MOZ_ASSERT(mCompositorWnd);
if (!mCompositorWnd) {
return;
}
LayoutDeviceIntSize size = GetClientSize();
if (mLastCompositorWndSize == size) {
return;
}
// Force a resize and redraw (but not a move, activate, etc.).
if (!::SetWindowPos(mCompositorWnd, nullptr, 0, 0, size.width, size.height,
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS |
SWP_NOOWNERZORDER | SWP_NOZORDER)) {
return;
}
mLastCompositorWndSize = size;
}
} // namespace widget
} // namespace mozilla

Просмотреть файл

@ -54,6 +54,7 @@ class WinCompositorWidget
public:
WinCompositorWidget(const WinCompositorWidgetInitData& aInitData,
const layers::CompositorOptions& aOptions);
~WinCompositorWidget() override;
// CompositorWidget Overrides
@ -94,9 +95,19 @@ public:
return mMemoryDC;
}
HWND GetHwnd() const {
return mWnd;
return mCompositorWnd ? mCompositorWnd : mWnd;
}
HWND GetCompositorHwnd() const {
return mCompositorWnd;
}
void EnsureCompositorWindow();
void DestroyCompositorWindow();
void UpdateCompositorWndSizeIfNecessary();
protected:
private:
HDC GetWindowSurface();
void FreeWindowSurface(HDC dc);
@ -106,6 +117,10 @@ private:
private:
uintptr_t mWidgetKey;
HWND mWnd;
HWND mCompositorWnd;
LayoutDeviceIntSize mLastCompositorWndSize;
gfx::CriticalSection mPresentLock;
// Transparency handling.

Просмотреть файл

@ -0,0 +1,170 @@
/* -*- 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

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- 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/. */
#ifndef widget_windows_WinCompositorWindowThread_h
#define widget_windows_WinCompositorWindowThread_h
#include "base/thread.h"
#include "base/message_loop.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
namespace mozilla {
namespace layers {
class SynchronousTask;
}
namespace widget {
class WinCompositorWindowThread final
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(WinCompositorWindowThread)
public:
/// Can be called from any thread.
static WinCompositorWindowThread* Get();
/// Can only be called from the main thread.
static void Start();
/// Can only be called from the main thread.
static void ShutDown();
/// Can be called from any thread.
static MessageLoop* Loop();
/// Can be called from any thread.
static bool IsInCompositorWindowThread();
/// Can be called from any thread.
static HWND CreateCompositorWindow(HWND aParentWnd);
/// Can be called from any thread.
static void DestroyCompositorWindow(HWND aWnd);
private:
explicit WinCompositorWindowThread(base::Thread* aThread);
~WinCompositorWindowThread();
void ShutDownTask(layers::SynchronousTask* aTask);
base::Thread* const mThread;
};
} // namespace widget
} // namespace mozilla
#endif // widget_windows_WinCompositorWindowThread_h

Просмотреть файл

@ -30,6 +30,7 @@ EXPORTS.mozilla.widget += [
'PDFiumProcessParent.h',
'PDFViaEMFPrintHelper.h',
'WinCompositorWidget.h',
'WinCompositorWindowThread.h',
'WindowsEMF.h',
'WinMessages.h',
'WinModifierKeyState.h',
@ -74,6 +75,7 @@ UNIFIED_SOURCES += [
'TaskbarTabPreview.cpp',
'TaskbarWindowPreview.cpp',
'WidgetTraceEvent.cpp',
'WinCompositorWindowThread.cpp',
'WindowHook.cpp',
'WinIMEHandler.cpp',
'WinPointerEvents.cpp',