mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1573710 - Trigger composite after SetParent() r=Gankro
The patch permits to resize compositor window's size after ::SetParent() call to prevent a conflict between ::SetParent() and ::SetWindowPos(). Then it triggers a composite after SetParent() call to resize compositor window correctly. Differential Revision: https://phabricator.services.mozilla.com/D49884 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
9df2ccc256
commit
16784c5201
@ -1451,8 +1451,6 @@ void CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
|
|||||||
void CompositorD3D11::EnsureSize() { mSize = mWidget->GetClientSize(); }
|
void CompositorD3D11::EnsureSize() { mSize = mWidget->GetClientSize(); }
|
||||||
|
|
||||||
bool CompositorD3D11::VerifyBufferSize() {
|
bool CompositorD3D11::VerifyBufferSize() {
|
||||||
mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
|
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -380,8 +380,6 @@ void MLGSwapChainD3D11::UpdateBackBufferContents(ID3D11Texture2D* aBack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MLGSwapChainD3D11::ResizeBuffers(const IntSize& aSize) {
|
bool MLGSwapChainD3D11::ResizeBuffers(const IntSize& aSize) {
|
||||||
mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
|
|
||||||
|
|
||||||
// We have to clear all references to the old backbuffer before resizing.
|
// We have to clear all references to the old backbuffer before resizing.
|
||||||
mRT = nullptr;
|
mRT = nullptr;
|
||||||
|
|
||||||
|
@ -360,6 +360,11 @@ mozilla::ipc::IPCResult CompositorBridgeParent::RecvInitialize(
|
|||||||
MOZ_ASSERT(XRE_IsGPUProcess());
|
MOZ_ASSERT(XRE_IsGPUProcess());
|
||||||
|
|
||||||
mRootLayerTreeID = aRootLayerTreeId;
|
mRootLayerTreeID = aRootLayerTreeId;
|
||||||
|
#ifdef XP_WIN
|
||||||
|
if (XRE_IsGPUProcess()) {
|
||||||
|
mWidget->AsWindows()->SetRootLayerTreeID(mRootLayerTreeID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
@ -949,6 +954,13 @@ void CompositorBridgeParent::CompositeToTarget(VsyncId aId, DrawTarget* aTarget,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
// Update compositor window's size if it exists.
|
||||||
|
// It needs to be called here, since OS might update compositor
|
||||||
|
// window's size at unexpected timing.
|
||||||
|
mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AutoResolveRefLayers handles two tasks related to Windows and Linux
|
* AutoResolveRefLayers handles two tasks related to Windows and Linux
|
||||||
* plugin window management:
|
* plugin window management:
|
||||||
@ -1661,6 +1673,30 @@ void CompositorBridgeParent::NotifyVsync(const VsyncEvent& aVsync,
|
|||||||
obs->NotifyVsync(aVsync);
|
obs->NotifyVsync(aVsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void CompositorBridgeParent::ScheduleForcedComposition(
|
||||||
|
const LayersId& aLayersId) {
|
||||||
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
|
||||||
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||||
|
|
||||||
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||||
|
auto it = sIndirectLayerTrees.find(aLayersId);
|
||||||
|
if (it == sIndirectLayerTrees.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositorBridgeParent* cbp = it->second.mParent;
|
||||||
|
if (!cbp || !cbp->mWidget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbp->mWrBridge) {
|
||||||
|
cbp->mWrBridge->ScheduleForcedGenerateFrame();
|
||||||
|
} else if (cbp->CanComposite()) {
|
||||||
|
cbp->mCompositorScheduler->ScheduleComposition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult CompositorBridgeParent::RecvNotifyChildCreated(
|
mozilla::ipc::IPCResult CompositorBridgeParent::RecvNotifyChildCreated(
|
||||||
const LayersId& child, CompositorOptions* aOptions) {
|
const LayersId& child, CompositorOptions* aOptions) {
|
||||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||||
|
@ -477,6 +477,8 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
|
|||||||
void ScheduleRotationOnCompositorThread(const TargetConfig& aTargetConfig,
|
void ScheduleRotationOnCompositorThread(const TargetConfig& aTargetConfig,
|
||||||
bool aIsFirstPaint);
|
bool aIsFirstPaint);
|
||||||
|
|
||||||
|
static void ScheduleForcedComposition(const LayersId& aLayersId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the unique layer tree identifier that corresponds to the root
|
* Returns the unique layer tree identifier that corresponds to the root
|
||||||
* tree of this compositor.
|
* tree of this compositor.
|
||||||
|
@ -44,6 +44,8 @@ class RenderCompositor {
|
|||||||
virtual bool WaitForGPU() { return true; }
|
virtual bool WaitForGPU() { return true; }
|
||||||
virtual void Pause() = 0;
|
virtual void Pause() = 0;
|
||||||
virtual bool Resume() = 0;
|
virtual bool Resume() = 0;
|
||||||
|
// Called when WR rendering is skipped
|
||||||
|
virtual void Update() {}
|
||||||
|
|
||||||
virtual gl::GLContext* gl() const { return nullptr; }
|
virtual gl::GLContext* gl() const { return nullptr; }
|
||||||
|
|
||||||
|
@ -543,6 +543,13 @@ void RenderCompositorANGLE::Pause() {}
|
|||||||
|
|
||||||
bool RenderCompositorANGLE::Resume() { return true; }
|
bool RenderCompositorANGLE::Resume() { return true; }
|
||||||
|
|
||||||
|
void RenderCompositorANGLE::Update() {
|
||||||
|
// Update compositor window's size if it exists.
|
||||||
|
// It needs to be called here, since OS might update compositor
|
||||||
|
// window's size at unexpected timing.
|
||||||
|
mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
bool RenderCompositorANGLE::MakeCurrent() {
|
bool RenderCompositorANGLE::MakeCurrent() {
|
||||||
gl::GLContextEGL::Cast(gl())->SetEGLSurfaceOverride(mEGLSurface);
|
gl::GLContextEGL::Cast(gl())->SetEGLSurfaceOverride(mEGLSurface);
|
||||||
return gl()->MakeCurrent();
|
return gl()->MakeCurrent();
|
||||||
|
@ -44,6 +44,7 @@ class RenderCompositorANGLE : public RenderCompositor {
|
|||||||
bool WaitForGPU() override;
|
bool WaitForGPU() override;
|
||||||
void Pause() override;
|
void Pause() override;
|
||||||
bool Resume() override;
|
bool Resume() override;
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
gl::GLContext* gl() const override { return RenderThread::Get()->SharedGL(); }
|
gl::GLContext* gl() const override { return RenderThread::Get()->SharedGL(); }
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ wr::WrExternalImageHandler RendererOGL::GetExternalImageHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RendererOGL::Update() {
|
void RendererOGL::Update() {
|
||||||
|
mCompositor->Update();
|
||||||
if (mCompositor->MakeCurrent()) {
|
if (mCompositor->MakeCurrent()) {
|
||||||
wr_renderer_update(mRenderer);
|
wr_renderer_update(mRenderer);
|
||||||
}
|
}
|
||||||
|
@ -64,14 +64,17 @@ mozilla::ipc::IPCResult CompositorWidgetChild::RecvUnobserveVsync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult CompositorWidgetChild::RecvUpdateCompositorWnd(
|
mozilla::ipc::IPCResult CompositorWidgetChild::RecvUpdateCompositorWnd(
|
||||||
const WindowsHandle& aCompositorWnd, const WindowsHandle& aParentWnd) {
|
const WindowsHandle& aCompositorWnd, const WindowsHandle& aParentWnd,
|
||||||
|
UpdateCompositorWndResolver&& aResolve) {
|
||||||
MOZ_ASSERT(mParentWnd);
|
MOZ_ASSERT(mParentWnd);
|
||||||
|
|
||||||
HWND parentWnd = reinterpret_cast<HWND>(aParentWnd);
|
HWND parentWnd = reinterpret_cast<HWND>(aParentWnd);
|
||||||
if (mParentWnd == parentWnd) {
|
if (mParentWnd == parentWnd) {
|
||||||
mCompositorWnd = reinterpret_cast<HWND>(aCompositorWnd);
|
mCompositorWnd = reinterpret_cast<HWND>(aCompositorWnd);
|
||||||
::SetParent(mCompositorWnd, mParentWnd);
|
::SetParent(mCompositorWnd, mParentWnd);
|
||||||
|
aResolve(true);
|
||||||
} else {
|
} else {
|
||||||
|
aResolve(false);
|
||||||
gfxCriticalNote << "Parent winow does not match";
|
gfxCriticalNote << "Parent winow does not match";
|
||||||
MOZ_ASSERT_UNREACHABLE("unexpected to happen");
|
MOZ_ASSERT_UNREACHABLE("unexpected to happen");
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
|
|||||||
mozilla::ipc::IPCResult RecvObserveVsync() override;
|
mozilla::ipc::IPCResult RecvObserveVsync() override;
|
||||||
mozilla::ipc::IPCResult RecvUnobserveVsync() override;
|
mozilla::ipc::IPCResult RecvUnobserveVsync() override;
|
||||||
mozilla::ipc::IPCResult RecvUpdateCompositorWnd(
|
mozilla::ipc::IPCResult RecvUpdateCompositorWnd(
|
||||||
const WindowsHandle& aCompositorWnd,
|
const WindowsHandle& aCompositorWnd, const WindowsHandle& aParentWnd,
|
||||||
const WindowsHandle& aParentWnd) override;
|
UpdateCompositorWndResolver&& aResolve) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<CompositorVsyncDispatcher> mVsyncDispatcher;
|
RefPtr<CompositorVsyncDispatcher> mVsyncDispatcher;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "CompositorWidgetParent.h"
|
#include "CompositorWidgetParent.h"
|
||||||
|
|
||||||
|
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||||
|
#include "mozilla/layers/CompositorThread.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||||
|
|
||||||
@ -60,9 +62,29 @@ RefPtr<VsyncObserver> CompositorWidgetParent::GetVsyncObserver() const {
|
|||||||
|
|
||||||
void CompositorWidgetParent::UpdateCompositorWnd(const HWND aCompositorWnd,
|
void CompositorWidgetParent::UpdateCompositorWnd(const HWND aCompositorWnd,
|
||||||
const HWND aParentWnd) {
|
const HWND aParentWnd) {
|
||||||
Unused << SendUpdateCompositorWnd(
|
MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread());
|
||||||
reinterpret_cast<WindowsHandle>(aCompositorWnd),
|
MOZ_ASSERT(mRootLayerTreeID.isSome());
|
||||||
reinterpret_cast<WindowsHandle>(aParentWnd));
|
|
||||||
|
RefPtr<CompositorWidgetParent> self = this;
|
||||||
|
SendUpdateCompositorWnd(reinterpret_cast<WindowsHandle>(aCompositorWnd),
|
||||||
|
reinterpret_cast<WindowsHandle>(aParentWnd))
|
||||||
|
->Then(
|
||||||
|
layers::CompositorThreadHolder::Loop()->SerialEventTarget(), __func__,
|
||||||
|
[self](const bool& aSuccess) {
|
||||||
|
if (aSuccess && self->mRootLayerTreeID.isSome()) {
|
||||||
|
self->mSetParentCompleted = true;
|
||||||
|
// Schedule composition after ::SetParent() call in parent
|
||||||
|
// process.
|
||||||
|
layers::CompositorBridgeParent::ScheduleForcedComposition(
|
||||||
|
self->mRootLayerTreeID.ref());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[self](const mozilla::ipc::ResponseRejectReason&) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompositorWidgetParent::SetRootLayerTreeID(
|
||||||
|
const layers::LayersId& aRootLayerTreeId) {
|
||||||
|
mRootLayerTreeID = Some(aRootLayerTreeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompositorWidgetParent::ActorDestroy(ActorDestroyReason aWhy) {}
|
void CompositorWidgetParent::ActorDestroy(ActorDestroyReason aWhy) {}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define widget_windows_CompositorWidgetParent_h
|
#define widget_windows_CompositorWidgetParent_h
|
||||||
|
|
||||||
#include "WinCompositorWidget.h"
|
#include "WinCompositorWidget.h"
|
||||||
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/widget/PCompositorWidgetParent.h"
|
#include "mozilla/widget/PCompositorWidgetParent.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -33,9 +34,11 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
|
|||||||
// PlatformCompositorWidgetDelegate Overrides
|
// PlatformCompositorWidgetDelegate Overrides
|
||||||
void UpdateCompositorWnd(const HWND aCompositorWnd,
|
void UpdateCompositorWnd(const HWND aCompositorWnd,
|
||||||
const HWND aParentWnd) override;
|
const HWND aParentWnd) override;
|
||||||
|
void SetRootLayerTreeID(const layers::LayersId& aRootLayerTreeId) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<VsyncObserver> mVsyncObserver;
|
RefPtr<VsyncObserver> mVsyncObserver;
|
||||||
|
Maybe<layers::LayersId> mRootLayerTreeID;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace widget
|
} // namespace widget
|
||||||
|
@ -27,7 +27,8 @@ parent:
|
|||||||
child:
|
child:
|
||||||
async ObserveVsync();
|
async ObserveVsync();
|
||||||
async UnobserveVsync();
|
async UnobserveVsync();
|
||||||
async UpdateCompositorWnd(WindowsHandle aCompositorWnd, WindowsHandle aParentWnd);
|
async UpdateCompositorWnd(WindowsHandle aCompositorWnd, WindowsHandle aParentWnd)
|
||||||
|
returns (bool success);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace widget
|
} // namespace widget
|
||||||
|
@ -29,6 +29,7 @@ WinCompositorWidget::WinCompositorWidget(
|
|||||||
const WinCompositorWidgetInitData& aInitData,
|
const WinCompositorWidgetInitData& aInitData,
|
||||||
const layers::CompositorOptions& aOptions)
|
const layers::CompositorOptions& aOptions)
|
||||||
: CompositorWidget(aOptions),
|
: CompositorWidget(aOptions),
|
||||||
|
mSetParentCompleted(false),
|
||||||
mWidgetKey(aInitData.widgetKey()),
|
mWidgetKey(aInitData.widgetKey()),
|
||||||
mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
|
mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
|
||||||
mCompositorWnds(nullptr, nullptr),
|
mCompositorWnds(nullptr, nullptr),
|
||||||
@ -339,13 +340,26 @@ void WinCompositorWidget::UpdateCompositorWndSizeIfNecessary() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a resize and redraw (but not a move, activate, etc.).
|
// This code is racing with the compositor, which needs to reparent
|
||||||
if (!::SetWindowPos(mCompositorWnds.mCompositorWnd, nullptr, 0, 0, size.width,
|
// the compositor surface to the actual window (mWnd). To avoid racing
|
||||||
size.height,
|
// mutations, we refuse to proceed until ::SetParent() is called in parent
|
||||||
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS |
|
// process. After the ::SetParent() call, composition is scheduled in
|
||||||
SWP_NOOWNERZORDER | SWP_NOZORDER)) {
|
// CompositorWidgetParent::UpdateCompositorWnd().
|
||||||
|
if (!mSetParentCompleted) {
|
||||||
|
// ::SetParent() is not completed yet.
|
||||||
return;
|
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;
|
mLastCompositorWndSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
#include "mozilla/gfx/CriticalSection.h"
|
#include "mozilla/gfx/CriticalSection.h"
|
||||||
#include "mozilla/gfx/Point.h"
|
#include "mozilla/gfx/Point.h"
|
||||||
|
#include "mozilla/layers/LayersTypes.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
#include "mozilla/widget/WinCompositorWindowThread.h"
|
#include "mozilla/widget/WinCompositorWindowThread.h"
|
||||||
#include "FxROutputHandler.h"
|
#include "FxROutputHandler.h"
|
||||||
@ -38,6 +39,7 @@ class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
|
|||||||
virtual void SetParentWnd(const HWND aParentWnd) {}
|
virtual void SetParentWnd(const HWND aParentWnd) {}
|
||||||
virtual void UpdateCompositorWnd(const HWND aCompositorWnd,
|
virtual void UpdateCompositorWnd(const HWND aCompositorWnd,
|
||||||
const HWND aParentWnd) {}
|
const HWND aParentWnd) {}
|
||||||
|
virtual void SetRootLayerTreeID(const layers::LayersId& aRootLayerTreeId) {}
|
||||||
|
|
||||||
// CompositorWidgetDelegate Overrides
|
// CompositorWidgetDelegate Overrides
|
||||||
|
|
||||||
@ -119,6 +121,9 @@ class WinCompositorWidget : public CompositorWidget,
|
|||||||
|
|
||||||
void CreateTransparentSurface(const gfx::IntSize& aSize);
|
void CreateTransparentSurface(const gfx::IntSize& aSize);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool mSetParentCompleted;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uintptr_t mWidgetKey;
|
uintptr_t mWidgetKey;
|
||||||
HWND mWnd;
|
HWND mWnd;
|
||||||
|
Loading…
Reference in New Issue
Block a user