Bug 1604412 - Clarify purpose of PlatformCompositorWidgetDelegate r=sotaro

PlatformCompositorWidgetDelegate was meant to be a pure virtual base
class for all the functions that nsWindow could call that would
either go to an in-process compositor widget or an OMTC widget.

By that definition, it does not seem like CompositorWidgetParent should
be a subclass, since nsWindow cannot directly call its methods and
currently CompositorWidgetParent has several "do nothing"
implementations of the interface methods because they don't really
belong.

This changeset remedies this by refactoring CompositorWidgetParent so
it is no longer an implementor of PlatformCompositorWidgetDelegate. Now
the only implementors are CompositorWidgetChild and InProcessWin-
CompositorWidget, which makes sense because they are both directly
called through the nsWindow delegate.

It also eliminates some of the methods that seem like they don't belong
in PlatformCompositorWidgetDelegate.

Differential Revision: https://phabricator.services.mozilla.com/D57429

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Chris Martin 2020-01-08 18:36:30 +00:00
Родитель 342c2113fe
Коммит cebb0d2c6c
12 изменённых файлов: 73 добавлений и 114 удалений

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

@ -795,7 +795,7 @@ RefPtr<CompositorSession> GPUProcessManager::CreateRemoteSession(
new CompositorWidgetVsyncObserver(mVsyncBridge, aRootLayerTreeId);
CompositorWidgetChild* widget =
new CompositorWidgetChild(dispatcher, observer);
new CompositorWidgetChild(dispatcher, observer, initData);
if (!child->SendPCompositorWidgetConstructor(widget, initData)) {
return nullptr;
}

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

@ -12,7 +12,8 @@ namespace widget {
CompositorWidgetChild::CompositorWidgetChild(
RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver)
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver,
const CompositorWidgetInitData&)
: mVsyncDispatcher(aVsyncDispatcher), mVsyncObserver(aVsyncObserver) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!gfxPlatform::IsHeadless());

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

@ -17,7 +17,8 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
public PlatformCompositorWidgetDelegate {
public:
CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver);
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver,
const CompositorWidgetInitData&);
~CompositorWidgetChild() override;
mozilla::ipc::IPCResult RecvObserveVsync() override;

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

@ -6,6 +6,7 @@
#include "CompositorWidgetChild.h"
#include "mozilla/Unused.h"
#include "mozilla/widget/CompositorWidgetVsyncObserver.h"
#include "mozilla/widget/PlatformWidgetTypes.h"
#include "nsBaseWidget.h"
#include "VsyncDispatcher.h"
#include "gfxPlatform.h"
@ -15,13 +16,16 @@ namespace widget {
CompositorWidgetChild::CompositorWidgetChild(
RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver)
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver,
const CompositorWidgetInitData& aInitData)
: mVsyncDispatcher(aVsyncDispatcher),
mVsyncObserver(aVsyncObserver),
mCompositorWnd(nullptr),
mParentWnd(nullptr) {
mParentWnd(reinterpret_cast<HWND>(
aInitData.get_WinCompositorWidgetInitData().hWnd())) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!gfxPlatform::IsHeadless());
MOZ_ASSERT(mParentWnd && ::IsWindow(mParentWnd));
}
CompositorWidgetChild::~CompositorWidgetChild() {}
@ -44,15 +48,6 @@ void CompositorWidgetChild::ClearTransparentWindow() {
Unused << SendClearTransparentWindow();
}
HDC CompositorWidgetChild::GetTransparentDC() const {
// Not supported in out-of-process mode.
return nullptr;
}
void CompositorWidgetChild::SetParentWnd(const HWND aParentWnd) {
mParentWnd = reinterpret_cast<HWND>(aParentWnd);
}
mozilla::ipc::IPCResult CompositorWidgetChild::RecvObserveVsync() {
mVsyncDispatcher->SetCompositorVsyncObserver(mVsyncObserver);
return IPC_OK();

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

@ -19,7 +19,8 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
public PlatformCompositorWidgetDelegate {
public:
CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver);
RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver,
const CompositorWidgetInitData& aInitData);
~CompositorWidgetChild() override;
void EnterPresentLock() override;
@ -27,8 +28,6 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
void OnDestroyWindow() override;
void UpdateTransparency(nsTransparencyMode aMode) override;
void ClearTransparentWindow() override;
HDC GetTransparentDC() const override;
void SetParentWnd(const HWND aParentWnd) override;
mozilla::ipc::IPCResult RecvObserveVsync() override;
mozilla::ipc::IPCResult RecvUnobserveVsync() override;

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

@ -52,12 +52,6 @@ CompositorWidgetParent::CompositorWidgetParent(
CompositorWidgetParent::~CompositorWidgetParent() {}
void CompositorWidgetParent::OnDestroyWindow() {
MutexAutoLock lock(mTransparentSurfaceLock);
mTransparentSurface = nullptr;
mMemoryDC = nullptr;
}
bool CompositorWidgetParent::PreRender(WidgetRenderingContext* aContext) {
// This can block waiting for WM_SETTEXT to finish
// Using PreRender is unnecessarily pessimistic because
@ -210,10 +204,6 @@ bool CompositorWidgetParent::InitCompositor(layers::Compositor* aCompositor) {
return true;
}
void CompositorWidgetParent::EnterPresentLock() { mPresentLock.Enter(); }
void CompositorWidgetParent::LeavePresentLock() { mPresentLock.Leave(); }
RefPtr<gfxASurface> CompositorWidgetParent::EnsureTransparentSurface() {
mTransparentSurfaceLock.AssertCurrentThreadOwns();
MOZ_ASSERT(mTransparencyMode == eTransparencyTransparent);
@ -239,21 +229,6 @@ void CompositorWidgetParent::CreateTransparentSurface(
mMemoryDC = surface->GetDC();
}
void CompositorWidgetParent::UpdateTransparency(nsTransparencyMode aMode) {
MutexAutoLock lock(mTransparentSurfaceLock);
if (mTransparencyMode == aMode) {
return;
}
mTransparencyMode = aMode;
mTransparentSurface = nullptr;
mMemoryDC = nullptr;
if (mTransparencyMode == eTransparencyTransparent) {
EnsureTransparentSurface();
}
}
bool CompositorWidgetParent::HasGlass() const {
MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread() ||
wr::RenderThread::IsInRenderThread());
@ -263,26 +238,6 @@ bool CompositorWidgetParent::HasGlass() const {
transparencyMode == eTransparencyBorderlessGlass;
}
void CompositorWidgetParent::ClearTransparentWindow() {
MutexAutoLock lock(mTransparentSurfaceLock);
if (!mTransparentSurface) {
return;
}
EnsureTransparentSurface();
IntSize size = mTransparentSurface->GetSize();
if (!size.IsEmpty()) {
RefPtr<DrawTarget> drawTarget =
gfxPlatform::CreateDrawTargetForSurface(mTransparentSurface, size);
if (!drawTarget) {
return;
}
drawTarget->ClearRect(Rect(0, 0, size.width, size.height));
RedrawTransparentWindow();
}
}
bool CompositorWidgetParent::RedrawTransparentWindow() {
MOZ_ASSERT(mTransparencyMode == eTransparencyTransparent);
@ -314,23 +269,50 @@ void CompositorWidgetParent::FreeWindowSurface(HDC dc) {
bool CompositorWidgetParent::IsHidden() const { return ::IsIconic(mWnd); }
mozilla::ipc::IPCResult CompositorWidgetParent::RecvEnterPresentLock() {
EnterPresentLock();
mPresentLock.Enter();
return IPC_OK();
}
mozilla::ipc::IPCResult CompositorWidgetParent::RecvLeavePresentLock() {
LeavePresentLock();
mPresentLock.Leave();
return IPC_OK();
}
mozilla::ipc::IPCResult CompositorWidgetParent::RecvUpdateTransparency(
const nsTransparencyMode& aMode) {
UpdateTransparency(aMode);
MutexAutoLock lock(mTransparentSurfaceLock);
if (mTransparencyMode == aMode) {
return IPC_OK();
}
mTransparencyMode = aMode;
mTransparentSurface = nullptr;
mMemoryDC = nullptr;
if (mTransparencyMode == eTransparencyTransparent) {
EnsureTransparentSurface();
}
return IPC_OK();
}
mozilla::ipc::IPCResult CompositorWidgetParent::RecvClearTransparentWindow() {
ClearTransparentWindow();
MutexAutoLock lock(mTransparentSurfaceLock);
if (!mTransparentSurface) {
return IPC_OK();
}
EnsureTransparentSurface();
IntSize size = mTransparentSurface->GetSize();
if (!size.IsEmpty()) {
RefPtr<DrawTarget> drawTarget =
gfxPlatform::CreateDrawTargetForSurface(mTransparentSurface, size);
if (!drawTarget) {
return IPC_OK();
}
drawTarget->ClearRect(Rect(0, 0, size.width, size.height));
RedrawTransparentWindow();
}
return IPC_OK();
}

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

@ -33,25 +33,6 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
bool InitCompositor(layers::Compositor* aCompositor) override;
bool IsHidden() const override;
// PlatformCompositorWidgetDelegate Overrides
void EnterPresentLock() override;
void LeavePresentLock() override;
void OnDestroyWindow() override;
void UpdateTransparency(nsTransparencyMode aMode) override;
void ClearTransparentWindow() override;
bool RedrawTransparentWindow() override;
// Ensure that a transparent surface exists, then return it.
RefPtr<gfxASurface> EnsureTransparentSurface() override;
HDC GetTransparentDC() const override { return mMemoryDC; }
mozilla::Mutex& GetTransparentSurfaceLock() override {
return mTransparentSurfaceLock;
}
bool HasGlass() const override;
mozilla::ipc::IPCResult RecvEnterPresentLock() override;
@ -71,6 +52,11 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
void SetRootLayerTreeID(const layers::LayersId& aRootLayerTreeId) override;
private:
bool RedrawTransparentWindow();
// Ensure that a transparent surface exists, then return it.
RefPtr<gfxASurface> EnsureTransparentSurface();
HDC GetWindowSurface();
void FreeWindowSurface(HDC dc);

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

@ -17,7 +17,9 @@ namespace widget {
// the most part it only requires an HWND, however it maintains extra state
// for transparent windows, as well as for synchronizing WM_SETTEXT messages
// with the compositor.
class InProcessWinCompositorWidget final : public WinCompositorWidget {
class InProcessWinCompositorWidget final
: public WinCompositorWidget,
public PlatformCompositorWidgetDelegate {
public:
InProcessWinCompositorWidget(const WinCompositorWidgetInitData& aInitData,
const layers::CompositorOptions& aOptions,
@ -34,6 +36,7 @@ class InProcessWinCompositorWidget final : public WinCompositorWidget {
bool* aOutIsCleared) override;
already_AddRefed<gfx::SourceSurface> EndBackBufferDrawing() override;
bool InitCompositor(layers::Compositor* aCompositor) override;
CompositorWidgetDelegate* AsDelegate() override { return this; }
bool IsHidden() const override;
// PlatformCompositorWidgetDelegate Overrides
@ -44,14 +47,14 @@ class InProcessWinCompositorWidget final : public WinCompositorWidget {
void UpdateTransparency(nsTransparencyMode aMode) override;
void ClearTransparentWindow() override;
bool RedrawTransparentWindow() override;
bool RedrawTransparentWindow();
// Ensure that a transparent surface exists, then return it.
RefPtr<gfxASurface> EnsureTransparentSurface() override;
RefPtr<gfxASurface> EnsureTransparentSurface();
HDC GetTransparentDC() const override { return mMemoryDC; }
HDC GetTransparentDC() const { return mMemoryDC; }
mozilla::Mutex& GetTransparentSurfaceLock() override {
mozilla::Mutex& GetTransparentSurfaceLock() {
return mTransparentSurfaceLock;
}
@ -60,6 +63,10 @@ class InProcessWinCompositorWidget final : public WinCompositorWidget {
void ObserveVsync(VsyncObserver* aObserver) override;
nsIWidget* RealWidget() override;
void UpdateCompositorWnd(const HWND aCompositorWnd,
const HWND aParentWnd) override {}
void SetRootLayerTreeID(const layers::LayersId& aRootLayerTreeId) override {}
private:
HDC GetWindowSurface();
void FreeWindowSurface(HDC dc);

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

@ -33,14 +33,6 @@ class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
virtual void UpdateTransparency(nsTransparencyMode aMode) = 0;
virtual void ClearTransparentWindow() = 0;
// If in-process and using software rendering, return the backing transparent
// DC.
virtual HDC GetTransparentDC() const = 0;
virtual void SetParentWnd(const HWND aParentWnd) {}
virtual void UpdateCompositorWnd(const HWND aCompositorWnd,
const HWND aParentWnd) {}
virtual void SetRootLayerTreeID(const layers::LayersId& aRootLayerTreeId) {}
// CompositorWidgetDelegate Overrides
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
@ -54,8 +46,7 @@ class WinCompositorWidgetInitData;
// the most part it only requires an HWND, however it maintains extra state
// for transparent windows, as well as for synchronizing WM_SETTEXT messages
// with the compositor.
class WinCompositorWidget : public CompositorWidget,
public PlatformCompositorWidgetDelegate {
class WinCompositorWidget : public CompositorWidget {
public:
WinCompositorWidget(const WinCompositorWidgetInitData& aInitData,
const layers::CompositorOptions& aOptions);
@ -65,12 +56,6 @@ class WinCompositorWidget : public CompositorWidget,
uintptr_t GetWidgetKey() override;
WinCompositorWidget* AsWindows() override { return this; }
CompositorWidgetDelegate* AsDelegate() override { return this; }
virtual bool RedrawTransparentWindow() = 0;
// Ensure that a transparent surface exists, then return it.
virtual RefPtr<gfxASurface> EnsureTransparentSurface() = 0;
HWND GetHwnd() const {
return mCompositorWnds.mCompositorWnd ? mCompositorWnds.mCompositorWnd
@ -83,14 +68,16 @@ class WinCompositorWidget : public CompositorWidget,
void DestroyCompositorWindow();
void UpdateCompositorWndSizeIfNecessary();
virtual mozilla::Mutex& GetTransparentSurfaceLock() = 0;
void RequestFxrOutput();
bool HasFxrOutputHandler() const { return mFxrHandler != nullptr; }
FxROutputHandler* GetFxrOutputHandler() const { return mFxrHandler.get(); }
virtual bool HasGlass() const = 0;
virtual void UpdateCompositorWnd(const HWND aCompositorWnd,
const HWND aParentWnd) = 0;
virtual void SetRootLayerTreeID(const layers::LayersId& aRootLayerTreeId) = 0;
protected:
bool mSetParentCompleted;

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

@ -3813,7 +3813,6 @@ void nsWindow::SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) {
MOZ_ASSERT(mCompositorWidgetDelegate,
"nsWindow::SetCompositorWidgetDelegate called with a "
"non-PlatformCompositorWidgetDelegate");
mCompositorWidgetDelegate->SetParentWnd(mWnd);
} else {
mCompositorWidgetDelegate = nullptr;
}

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

@ -60,7 +60,7 @@ class imgIContainer;
namespace mozilla {
namespace widget {
class NativeKey;
class WinCompositorWidget;
class InProcessWinCompositorWidget;
struct MSGResult;
} // namespace widget
} // namespace mozilla
@ -688,7 +688,7 @@ class nsWindow final : public nsWindowBase {
POINT mCachedHitTestPoint;
TimeStamp mCachedHitTestTime;
RefPtr<mozilla::widget::WinCompositorWidget> mBasicLayersSurface;
RefPtr<mozilla::widget::InProcessWinCompositorWidget> mBasicLayersSurface;
static bool sNeedsToInitMouseWheelSettings;
static void InitMouseWheelScrollData();

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

@ -46,7 +46,7 @@ using mozilla::plugins::PluginInstanceParent;
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "ClientLayerManager.h"
#include "WinCompositorWidget.h"
#include "InProcessWinCompositorWidget.h"
#include "nsUXThemeData.h"
#include "nsUXThemeConstants.h"
@ -227,7 +227,9 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) {
mLastPaintBounds = mBounds;
#ifdef MOZ_XUL
if (!aDC && (eTransparencyTransparent == mTransparencyMode)) {
if (!aDC &&
(GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) &&
(eTransparencyTransparent == mTransparencyMode)) {
// For layered translucent windows all drawing should go to memory DC and no
// WM_PAINT messages are normally generated. To support asynchronous
// painting we force generation of WM_PAINT messages by invalidating window
@ -240,7 +242,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) {
// We're guaranteed to have a widget proxy since we called
// GetLayerManager().
aDC = mCompositorWidgetDelegate->GetTransparentDC();
aDC = mBasicLayersSurface->GetTransparentDC();
}
#endif