mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
f3d76a51df
The in-process compositor assumes that no compositor window was present. This is not guaranteed to be true if, for example, the preference `gfx.webrender.flip-sequential` is set. Make the in-process compositor more closely mirror the out-of-process compositor. (At present this effectively just means calling ::SetParent on the compositor window.) Differential Revision: https://phabricator.services.mozilla.com/D172733
106 lines
3.3 KiB
C++
106 lines
3.3 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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 "WinCompositorWidget.h"
|
|
|
|
#include "mozilla/StaticPrefs_layers.h"
|
|
#include "mozilla/gfx/DeviceManagerDx.h"
|
|
#include "mozilla/gfx/Point.h"
|
|
#include "mozilla/layers/Compositor.h"
|
|
#include "mozilla/layers/CompositorThread.h"
|
|
#include "mozilla/webrender/RenderThread.h"
|
|
#include "mozilla/widget/PlatformWidgetTypes.h"
|
|
#include "nsWindow.h"
|
|
#include "VsyncDispatcher.h"
|
|
#include "WinCompositorWindowThread.h"
|
|
#include "VRShMem.h"
|
|
|
|
#include <ddraw.h>
|
|
|
|
namespace mozilla {
|
|
namespace widget {
|
|
|
|
using namespace mozilla::gfx;
|
|
using namespace mozilla;
|
|
|
|
WinCompositorWidget::WinCompositorWidget(
|
|
const WinCompositorWidgetInitData& aInitData,
|
|
const layers::CompositorOptions& aOptions)
|
|
: CompositorWidget(aOptions),
|
|
mSetParentCompleted(false),
|
|
mWidgetKey(aInitData.widgetKey()),
|
|
mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
|
|
mCompositorWnds(nullptr, nullptr) {
|
|
MOZ_ASSERT(mWnd && ::IsWindow(mWnd));
|
|
}
|
|
|
|
WinCompositorWidget::~WinCompositorWidget() { DestroyCompositorWindow(); }
|
|
|
|
uintptr_t WinCompositorWidget::GetWidgetKey() { return mWidgetKey; }
|
|
|
|
void WinCompositorWidget::EnsureCompositorWindow() {
|
|
if (mCompositorWnds.mCompositorWnd || mCompositorWnds.mInitialParentWnd) {
|
|
return;
|
|
}
|
|
|
|
mCompositorWnds = WinCompositorWindowThread::CreateCompositorWindow();
|
|
UpdateCompositorWnd(mCompositorWnds.mCompositorWnd, mWnd);
|
|
|
|
MOZ_ASSERT(mCompositorWnds.mCompositorWnd);
|
|
MOZ_ASSERT(mCompositorWnds.mInitialParentWnd);
|
|
}
|
|
|
|
void WinCompositorWidget::DestroyCompositorWindow() {
|
|
if (!mCompositorWnds.mCompositorWnd && !mCompositorWnds.mInitialParentWnd) {
|
|
return;
|
|
}
|
|
WinCompositorWindowThread::DestroyCompositorWindow(mCompositorWnds);
|
|
mCompositorWnds = WinCompositorWnds(nullptr, nullptr);
|
|
}
|
|
|
|
void WinCompositorWidget::UpdateCompositorWndSizeIfNecessary() {
|
|
if (!mCompositorWnds.mCompositorWnd) {
|
|
return;
|
|
}
|
|
|
|
LayoutDeviceIntSize size = GetClientSize();
|
|
if (mLastCompositorWndSize == size) {
|
|
return;
|
|
}
|
|
|
|
// This code is racing with the compositor, which needs to reparent the
|
|
// compositor surface to the actual window (mWnd). To avoid racing mutations,
|
|
// we refuse to proceed until ::SetParent() is called in the parent process.
|
|
// After the ::SetParent() call, composition is scheduled in
|
|
// CompositorWidgetParent::UpdateCompositorWnd().
|
|
if (!mSetParentCompleted) {
|
|
// ::SetParent() is not completed yet.
|
|
return;
|
|
}
|
|
|
|
MOZ_ASSERT(mWnd == ::GetParent(mCompositorWnds.mCompositorWnd));
|
|
|
|
// Force a resize and redraw (but not a move, activate, etc.).
|
|
if (!::SetWindowPos(
|
|
mCompositorWnds.mCompositorWnd, nullptr, 0, 0, size.width,
|
|
size.height,
|
|
SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOZORDER)) {
|
|
return;
|
|
}
|
|
|
|
mLastCompositorWndSize = size;
|
|
}
|
|
|
|
// Creates a new instance of FxROutputHandler so that this compositor widget
|
|
// can send its output to Firefox Reality for Desktop.
|
|
void WinCompositorWidget::RequestFxrOutput() {
|
|
MOZ_ASSERT(mFxrHandler == nullptr);
|
|
|
|
mFxrHandler.reset(new FxROutputHandler());
|
|
}
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|