зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1191971 part 1 - Create child window in gpu process r=bas
This commit is contained in:
Родитель
f627214d56
Коммит
537c379106
|
@ -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',
|
||||
|
|
Загрузка…
Ссылка в новой задаче