Extract a delegate interface out of WinCompositorWidget. (bug 1281998 part 6, r=jimm)

This commit is contained in:
David Anderson 2016-07-01 01:15:16 -07:00
Родитель 6562af780a
Коммит 97a92d5d5e
10 изменённых файлов: 96 добавлений и 61 удалений

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

@ -33,6 +33,7 @@ public:
private:
RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
RefPtr<CompositorWidget> mCompositorWidget;
};
already_AddRefed<CompositorSession>
@ -54,6 +55,7 @@ CompositorSession::CreateInProcess(nsIWidget* aWidget,
}
CompositorSession::CompositorSession()
: mCompositorWidgetDelegate(nullptr)
{
}
@ -77,6 +79,7 @@ InProcessCompositorSession::InProcessCompositorSession(nsIWidget* aWidget,
CompositorWidgetInitData initData;
aWidget->GetCompositorWidgetInitData(&initData);
mCompositorWidget = CompositorWidget::CreateLocal(initData, aWidget);
mCompositorWidgetDelegate = mCompositorWidget->AsDelegate();
mCompositorBridgeParent = new CompositorBridgeParent(
mCompositorWidget,

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

@ -16,6 +16,7 @@ class nsIWidget;
namespace mozilla {
namespace widget {
class CompositorWidget;
class CompositorWidgetDelegate;
} // namespace widget
namespace gfx {
class GPUProcessManager;
@ -36,6 +37,7 @@ class CompositorSession
protected:
typedef widget::CompositorWidget CompositorWidget;
typedef widget::CompositorWidgetDelegate CompositorWidgetDelegate;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorSession)
@ -58,8 +60,8 @@ public:
CompositorBridgeChild* GetCompositorBridgeChild();
// Return the proxy for accessing the compositor's widget.
RefPtr<CompositorWidget> GetCompositorWidget() {
return mCompositorWidget;
CompositorWidgetDelegate* GetCompositorWidgetDelegate() {
return mCompositorWidgetDelegate;
}
protected:
@ -76,7 +78,7 @@ protected:
protected:
RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
RefPtr<CompositorWidget> mCompositorWidget;
CompositorWidgetDelegate* mCompositorWidgetDelegate;
private:
DISALLOW_COPY_AND_ASSIGN(CompositorSession);

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

@ -31,6 +31,13 @@ namespace widget {
class WinCompositorWidget;
class CompositorWidgetInitData;
// Gecko widgets usually need to communicate with the CompositorWidget with
// platform-specific messages (for example to update the window size or
// transparency). This functionality is controlled through a "host". Since
// this functionality is platform-dependent, it is only forward declared
// here.
class CompositorWidgetDelegate;
/**
* Access to a widget from the compositor is restricted to these methods.
*/
@ -211,6 +218,13 @@ public:
return nullptr;
}
/**
* Return the platform-specific delegate for the widget, if any.
*/
virtual CompositorWidgetDelegate* AsDelegate() {
return nullptr;
}
protected:
virtual ~CompositorWidget();

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

@ -171,6 +171,7 @@ nsBaseWidget::nsBaseWidget()
, mSizeMode(nsSizeMode_Normal)
, mPopupLevel(ePopupLevelTop)
, mPopupType(ePopupTypeAny)
, mCompositorWidgetDelegate(nullptr)
, mUpdateCursor(true)
, mUseAttachedEvents(false)
, mIMEHasFocus(false)
@ -273,7 +274,7 @@ void nsBaseWidget::DestroyCompositor()
if (mCompositorSession) {
ReleaseContentController();
mAPZC = nullptr;
mCompositorWidget = nullptr;
mCompositorWidgetDelegate = nullptr;
mCompositorBridgeChild = nullptr;
// XXX CompositorBridgeChild and CompositorBridgeParent might be re-created in
@ -1314,7 +1315,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
UseExternalCompositingSurface(),
gfx::IntSize(aWidth, aHeight));
mCompositorBridgeChild = mCompositorSession->GetCompositorBridgeChild();
mCompositorWidget = mCompositorSession->GetCompositorWidget();
mCompositorWidgetDelegate = mCompositorSession->GetCompositorWidgetDelegate();
mAPZC = mCompositorSession->GetAPZCTreeManager();
if (mAPZC) {

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

@ -50,7 +50,7 @@ struct ScrollableLayerGuid;
} // namespace layers
namespace widget {
class CompositorWidget;
class CompositorWidgetDelegate;
class InProcessCompositorWidget;
} // namespace widget
@ -116,7 +116,7 @@ protected:
typedef mozilla::CSSIntRect CSSIntRect;
typedef mozilla::CSSRect CSSRect;
typedef mozilla::ScreenRotation ScreenRotation;
typedef mozilla::widget::CompositorWidget CompositorWidget;
typedef mozilla::widget::CompositorWidgetDelegate CompositorWidgetDelegate;
typedef mozilla::layers::CompositorSession CompositorSession;
virtual ~nsBaseWidget();
@ -588,7 +588,7 @@ protected:
nsPopupType mPopupType;
SizeConstraints mSizeConstraints;
RefPtr<CompositorWidget> mCompositorWidget;
CompositorWidgetDelegate* mCompositorWidgetDelegate;
bool mUpdateCursor;
bool mUseAttachedEvents;

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

@ -205,7 +205,7 @@ WinCompositorWidget::EnsureTransparentSurface()
if (!mTransparentSurface) {
LayoutDeviceIntSize size = GetClientSize();
CreateTransparentSurface(size.width, size.height);
CreateTransparentSurface(IntSize(size.width, size.height));
}
RefPtr<gfxASurface> surface = mTransparentSurface;
@ -213,11 +213,10 @@ WinCompositorWidget::EnsureTransparentSurface()
}
void
WinCompositorWidget::CreateTransparentSurface(int32_t aWidth, int32_t aHeight)
WinCompositorWidget::CreateTransparentSurface(const gfx::IntSize& aSize)
{
MOZ_ASSERT(!mTransparentSurface && !mMemoryDC);
RefPtr<gfxWindowsSurface> surface =
new gfxWindowsSurface(IntSize(aWidth, aHeight), SurfaceFormat::A8R8G8B8_UINT32);
RefPtr<gfxWindowsSurface> surface = new gfxWindowsSurface(aSize, SurfaceFormat::A8R8G8B8_UINT32);
mTransparentSurface = surface;
mMemoryDC = surface->GetDC();
}
@ -253,13 +252,11 @@ WinCompositorWidget::ClearTransparentWindow()
}
void
WinCompositorWidget::ResizeTransparentWindow(int32_t aNewWidth, int32_t aNewHeight)
WinCompositorWidget::ResizeTransparentWindow(const gfx::IntSize& aSize)
{
MOZ_ASSERT(mTransparencyMode == eTransparencyTransparent);
if (mTransparentSurface &&
mTransparentSurface->GetSize() == IntSize(aNewWidth, aNewHeight))
{
if (mTransparentSurface && mTransparentSurface->GetSize() == aSize) {
return;
}
@ -267,7 +264,7 @@ WinCompositorWidget::ResizeTransparentWindow(int32_t aNewWidth, int32_t aNewHeig
mTransparentSurface = nullptr;
mMemoryDC = nullptr;
CreateTransparentSurface(aNewWidth, aNewHeight);
CreateTransparentSurface(aSize);
}
bool

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

@ -8,17 +8,40 @@
#include "CompositorWidget.h"
#include "mozilla/gfx/CriticalSection.h"
#include "mozilla/gfx/Point.h"
class nsWindow;
namespace mozilla {
namespace widget {
class CompositorWidgetDelegate
{
public:
// Callbacks for nsWindow.
virtual void EnterPresentLock() = 0;
virtual void LeavePresentLock() = 0;
virtual void OnDestroyWindow() = 0;
// Transparency handling.
virtual void UpdateTransparency(nsTransparencyMode aMode) = 0;
virtual void ClearTransparentWindow() = 0;
// Update the bounds of the transparent surface.
virtual void ResizeTransparentWindow(const gfx::IntSize& aSize) = 0;
// If in-process and using software rendering, return the backing transparent
// DC.
virtual HDC GetTransparentDC() const = 0;
};
// This is the Windows-specific implementation of CompositorWidget. For
// 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
class WinCompositorWidget
: public CompositorWidget,
public CompositorWidgetDelegate
{
public:
WinCompositorWidget(const CompositorWidgetInitData& aInitData,
@ -39,24 +62,24 @@ public:
WinCompositorWidget* AsWindows() override {
return this;
}
CompositorWidgetDelegate* AsDelegate() override {
return this;
}
// Callbacks for nsWindow.
void EnterPresentLock();
void LeavePresentLock();
void OnDestroyWindow();
// CompositorWidgetDelegate overrides.
void EnterPresentLock() override;
void LeavePresentLock() override;
void OnDestroyWindow() override;
void UpdateTransparency(nsTransparencyMode aMode) override;
void ClearTransparentWindow() override;
void ResizeTransparentWindow(const gfx::IntSize& aSize) override;
// Transparency handling.
void UpdateTransparency(nsTransparencyMode aMode);
void ClearTransparentWindow();
bool RedrawTransparentWindow();
// Update the bounds of the transparent surface.
void ResizeTransparentWindow(int32_t aNewWidth, int32_t aNewHeight);
// Ensure that a transparent surface exists, then return it.
RefPtr<gfxASurface> EnsureTransparentSurface();
HDC GetTransparentDC() const {
HDC GetTransparentDC() const override {
return mMemoryDC;
}
HWND GetHwnd() const {
@ -67,7 +90,7 @@ private:
HDC GetWindowSurface();
void FreeWindowSurface(HDC dc);
void CreateTransparentSurface(int32_t aWidth, int32_t aHeight);
void CreateTransparentSurface(const gfx::IntSize& aSize);
private:
nsWindow* mWindow;

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

@ -1292,8 +1292,8 @@ NS_METHOD nsWindow::Show(bool bState)
// Clear contents to avoid ghosting of old content if we display
// this window again.
if (wasVisible && mTransparencyMode == eTransparencyTransparent) {
if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
proxy->ClearTransparentWindow();
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->ClearTransparentWindow();
}
}
if (mWindowType != eWindowType_dialog) {
@ -1551,8 +1551,8 @@ NS_METHOD nsWindow::Resize(double aWidth, double aHeight, bool aRepaint)
}
if (mTransparencyMode == eTransparencyTransparent) {
if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
proxy->ResizeTransparentWindow(width, height);
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->ResizeTransparentWindow(gfx::IntSize(width, height));
}
}
@ -1610,8 +1610,8 @@ NS_METHOD nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
}
if (eTransparencyTransparent == mTransparencyMode) {
if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
proxy->ResizeTransparentWindow(width, height);
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->ResizeTransparentWindow(gfx::IntSize(width, height));
}
}
@ -3618,7 +3618,7 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
if (!mLayerManager) {
MOZ_ASSERT(!mCompositorSession && !mCompositorBridgeChild);
MOZ_ASSERT(!mCompositorWidget);
MOZ_ASSERT(!mCompositorWidgetDelegate);
// Ensure we have a widget proxy even if we're not using the compositor,
// since all our transparent window handling lives there.
@ -3626,7 +3626,8 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
reinterpret_cast<uintptr_t>(mWnd),
reinterpret_cast<uintptr_t>(static_cast<nsIWidget*>(this)),
mTransparencyMode);
mCompositorWidget = new WinCompositorWidget(initData, this);
mBasicLayersSurface = new WinCompositorWidget(initData, this);
mCompositorWidgetDelegate = mBasicLayersSurface;
mLayerManager = CreateBasicLayerManager();
}
@ -3687,12 +3688,6 @@ nsWindow::OnDefaultButtonLoaded(const LayoutDeviceIntRect& aButtonRect)
return NS_OK;
}
mozilla::widget::WinCompositorWidget*
nsWindow::GetCompositorWidget()
{
return mCompositorWidget? mCompositorWidget->AsWindows() : nullptr;
}
void
nsWindow::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
{
@ -4895,17 +4890,16 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
//
// To do this we take mPresentLock in nsWindow::PreRender and
// if that lock is taken we wait before doing WM_SETTEXT
RefPtr<WinCompositorWidget> proxy = GetCompositorWidget();
if (proxy) {
proxy->EnterPresentLock();
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->EnterPresentLock();
}
DWORD style = GetWindowLong(mWnd, GWL_STYLE);
SetWindowLong(mWnd, GWL_STYLE, style & ~WS_VISIBLE);
*aRetValue = CallWindowProcW(GetPrevWindowProc(), mWnd,
msg, wParam, lParam);
SetWindowLong(mWnd, GWL_STYLE, style);
if (proxy) {
proxy->LeavePresentLock();
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->LeavePresentLock();
}
return true;
@ -6206,8 +6200,8 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp)
nsIntRect rect(wp->x, wp->y, newWidth, newHeight);
if (eTransparencyTransparent == mTransparencyMode) {
if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
proxy->ResizeTransparentWindow(newWidth, newHeight);
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->ResizeTransparentWindow(gfx::IntSize(newWidth, newHeight));
}
}
@ -6727,9 +6721,10 @@ void nsWindow::OnDestroy()
if (mCursor == -1)
SetCursor(eCursor_standard);
if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
proxy->OnDestroyWindow();
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->OnDestroyWindow();
}
mBasicLayersSurface = nullptr;
// Finalize panning feedback to possibly restore window displacement
mGesture.PanFeedbackFinalize(mWnd, true);
@ -7044,8 +7039,8 @@ void nsWindow::SetWindowTranslucencyInner(nsTransparencyMode aMode)
memset(&mGlassMargins, 0, sizeof mGlassMargins);
mTransparencyMode = aMode;
if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
proxy->UpdateTransparency(aMode);
if (mCompositorWidgetDelegate) {
mCompositorWidgetDelegate->UpdateTransparency(aMode);
}
UpdateGlass();
}

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

@ -57,8 +57,8 @@ class imgIContainer;
namespace mozilla {
namespace widget {
class NativeKey;
struct MSGResult;
class WinCompositorWidget;
struct MSGResult;
} // namespace widget
} // namespacw mozilla;
@ -487,8 +487,6 @@ protected:
void ClearCachedResources();
nsIWidgetListener* GetPaintListener();
mozilla::widget::WinCompositorWidget* GetCompositorWidget();
protected:
nsCOMPtr<nsIWidget> mParent;
nsIntSize mLastSize;
@ -621,6 +619,8 @@ protected:
TimeStamp mCachedHitTestTime;
int32_t mCachedHitTestResult;
RefPtr<mozilla::widget::WinCompositorWidget> mBasicLayersSurface;
static bool sNeedsToInitMouseWheelSettings;
static void InitMouseWheelScrollData();

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

@ -239,7 +239,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
::EndPaint(mWnd, &ps);
// We're guaranteed to have a widget proxy since we called GetLayerManager().
aDC = GetCompositorWidget()->GetTransparentDC();
aDC = mCompositorWidgetDelegate->GetTransparentDC();
}
#endif
@ -313,7 +313,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
#if defined(MOZ_XUL)
// don't support transparency for non-GDI rendering, for now
if (eTransparencyTransparent == mTransparencyMode) {
targetSurface = GetCompositorWidget()->EnsureTransparentSurface();
targetSurface = mBasicLayersSurface->EnsureTransparentSurface();
}
#endif
@ -378,7 +378,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
// Data from offscreen drawing surface was copied to memory bitmap of transparent
// bitmap. Now it can be read from memory bitmap to apply alpha channel and after
// that displayed on the screen.
GetCompositorWidget()->RedrawTransparentWindow();
mBasicLayersSurface->RedrawTransparentWindow();
}
#endif
}