Hide top-level CompositorBridgeParents behind a new API. (bug 1272472 part 4, r=mattwoodrow,kats,gwagner)

This commit is contained in:
David Anderson 2016-05-17 22:33:22 -07:00
parent 3189d8ab85
commit c2a116cdd6
13 changed files with 271 additions and 50 deletions

View File

@ -0,0 +1,122 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* 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 "CompositorSession.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "base/process_util.h"
namespace mozilla {
namespace layers {
class InProcessCompositorSession final : public CompositorSession
{
public:
InProcessCompositorSession(
widget::CompositorWidgetProxy* aWidgetProxy,
ClientLayerManager* aLayerManager,
CSSToLayoutDeviceScale aScale,
bool aUseAPZ,
bool aUseExternalSurfaceSize,
int aSurfaceWidth, int aSurfaceHeight);
CompositorBridgeParent* GetInProcessBridge() const override;
void SetContentController(GeckoContentController* aController) override;
uint64_t RootLayerTreeId() const override;
APZCTreeManager* GetAPZCTreeManager() const override;
void Shutdown() override;
private:
RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
};
already_AddRefed<CompositorSession>
CompositorSession::CreateTopLevel(widget::CompositorWidgetProxy* aWidgetProxy,
ClientLayerManager* aLayerManager,
CSSToLayoutDeviceScale aScale,
bool aUseAPZ,
bool aUseExternalSurfaceSize,
int aSurfaceWidth, int aSurfaceHeight)
{
RefPtr<InProcessCompositorSession> session = new InProcessCompositorSession(
aWidgetProxy,
aLayerManager,
aScale,
aUseAPZ,
aUseExternalSurfaceSize,
aSurfaceWidth, aSurfaceHeight);
return session.forget();
}
CompositorSession::CompositorSession()
{
}
CompositorSession::~CompositorSession()
{
}
CompositorBridgeChild*
CompositorSession::GetCompositorBridgeChild()
{
return mCompositorBridgeChild;
}
InProcessCompositorSession::InProcessCompositorSession(widget::CompositorWidgetProxy* aWidgetProxy,
ClientLayerManager* aLayerManager,
CSSToLayoutDeviceScale aScale,
bool aUseAPZ,
bool aUseExternalSurfaceSize,
int aSurfaceWidth, int aSurfaceHeight)
{
mCompositorBridgeParent = new CompositorBridgeParent(
aWidgetProxy,
aScale,
aUseAPZ,
aUseExternalSurfaceSize,
aSurfaceWidth,
aSurfaceHeight);
mCompositorBridgeChild = new CompositorBridgeChild(aLayerManager);
mCompositorBridgeChild->OpenSameProcess(mCompositorBridgeParent);
mCompositorBridgeParent->SetOtherProcessId(base::GetCurrentProcId());
}
CompositorBridgeParent*
InProcessCompositorSession::GetInProcessBridge() const
{
return mCompositorBridgeParent;
}
void
InProcessCompositorSession::SetContentController(GeckoContentController* aController)
{
mCompositorBridgeParent->SetControllerForLayerTree(RootLayerTreeId(), aController);
}
uint64_t
InProcessCompositorSession::RootLayerTreeId() const
{
return mCompositorBridgeParent->RootLayerTreeId();
}
APZCTreeManager*
InProcessCompositorSession::GetAPZCTreeManager() const
{
return mCompositorBridgeParent->GetAPZCTreeManager(RootLayerTreeId());
}
void
InProcessCompositorSession::Shutdown()
{
// XXX CompositorBridgeChild and CompositorBridgeParent might be re-created in
// ClientLayerManager destructor. See bug 1133426.
RefPtr<CompositorBridgeChild> compositorChild = mCompositorBridgeChild;
RefPtr<CompositorBridgeParent> compositorParent = mCompositorBridgeParent;
mCompositorBridgeChild->Destroy();
mCompositorBridgeChild = nullptr;
}
} // namespace layers
} // namespace mozilla

View File

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* 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 _include_mozilla_gfx_ipc_CompositorSession_h_
#define _include_mozilla_gfx_ipc_CompositorSession_h_
#include "base/basictypes.h"
#include "Units.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace widget {
class CompositorWidgetProxy;
} // namespace widget
namespace layers {
class GeckoContentController;
class APZCTreeManager;
class CompositorBridgeParent;
class CompositorBridgeChild;
class ClientLayerManager;
// A CompositorSession provides access to a compositor without exposing whether
// or not it's in-process or out-of-process.
class CompositorSession
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorSession)
static already_AddRefed<CompositorSession> CreateTopLevel(
widget::CompositorWidgetProxy* aWidgetProxy,
ClientLayerManager* aLayerManager,
CSSToLayoutDeviceScale aScale,
bool aUseAPZ,
bool aUseExternalSurfaceSize,
int aSurfaceWidth, int aSurfaceHeight);
virtual void Shutdown() = 0;
// This returns a CompositorBridgeParent if the compositor resides in the same process.
virtual CompositorBridgeParent* GetInProcessBridge() const = 0;
// Set the GeckoContentController for the root of the layer tree.
virtual void SetContentController(GeckoContentController* aController) = 0;
// Return the id of the root layer tree.
virtual uint64_t RootLayerTreeId() const = 0;
// Return the Async Pan/Zoom Tree Manager for this compositor.
virtual APZCTreeManager* GetAPZCTreeManager() const = 0;
// Return the child end of the compositor IPC bridge.
CompositorBridgeChild* GetCompositorBridgeChild();
protected:
CompositorSession();
virtual ~CompositorSession();
protected:
RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
private:
DISALLOW_COPY_AND_ASSIGN(CompositorSession);
};
} // namespace layers
} // namespace mozilla
#endif // _include_mozilla_gfx_ipc_CompositorSession_h_

View File

@ -13,6 +13,10 @@ EXPORTS.mozilla.gfx += [
'SharedDIB.h',
]
EXPORTS.mozilla.layers += [
'CompositorSession.h',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS.mozilla.gfx += [
'SharedDIBSurface.h',
@ -24,6 +28,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
]
UNIFIED_SOURCES += [
'CompositorSession.cpp',
'D3DMessageUtils.cpp',
'SharedDIB.cpp',
]

View File

@ -19,8 +19,6 @@
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/media/MediaSystemResourceManagerParent.h" // for MediaSystemResourceManagerParent
#include "mozilla/layers/CompositableTransactionParent.h"
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/LayersMessages.h" // for EditReply
#include "mozilla/layers/LayersSurfaces.h" // for PGrallocBufferParent

View File

@ -14,7 +14,7 @@
#include "mozilla/Attributes.h" // for override
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/PImageBridgeParent.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h"

View File

@ -91,6 +91,7 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsBaseWidget)
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorSession.h"
#include "mozilla/layers/LayerTransactionParent.h"
#include "mozilla/Mutex.h"
#include "mozilla/Services.h"
@ -465,7 +466,7 @@ public:
}
RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
RefPtr<CompositorBridgeParent> compositor = mWindow->mCompositorBridgeParent;
RefPtr<CompositorBridgeParent> compositor = mWindow->GetCompositorBridgeParent();
if (controller && compositor) {
// TODO: Pass in correct values for presShellId and viewId.
controller->CancelAnimation(ScrollableLayerGuid(
@ -1016,8 +1017,8 @@ public:
// Since we are re-linking the new java objects to Gecko, we need
// to get the viewport from the compositor (since the Java copy was
// thrown away) and we do that by setting the first-paint flag.
if (window.mCompositorBridgeParent) {
window.mCompositorBridgeParent->ForceIsFirstPaint();
if (RefPtr<CompositorBridgeParent> bridge = window.GetCompositorBridgeParent()) {
bridge->ForceIsFirstPaint();
}
}
@ -1062,33 +1063,35 @@ public:
void SyncPauseCompositor()
{
if (window.mCompositorBridgeParent) {
window.mCompositorBridgeParent->SchedulePauseOnCompositorThread();
if (RefPtr<CompositorBridgeParent> bridge = window.GetCompositorBridgeParent()) {
bridge->SchedulePauseOnCompositorThread();
mCompositorPaused = true;
}
}
void SyncResumeCompositor()
{
if (window.mCompositorBridgeParent &&
window.mCompositorBridgeParent->ScheduleResumeOnCompositorThread()) {
mCompositorPaused = false;
if (RefPtr<CompositorBridgeParent> bridge = window.GetCompositorBridgeParent()) {
if (bridge->ScheduleResumeOnCompositorThread()) {
mCompositorPaused = false;
}
}
}
void SyncResumeResizeCompositor(int32_t aWidth, int32_t aHeight)
{
if (window.mCompositorBridgeParent && window.mCompositorBridgeParent->
ScheduleResumeOnCompositorThread(aWidth, aHeight)) {
mCompositorPaused = false;
if (RefPtr<CompositorBridgeParent> bridge = window.GetCompositorBridgeParent()) {
if (bridge->ScheduleResumeOnCompositorThread(aWidth, aHeight)) {
mCompositorPaused = false;
}
}
}
void SyncInvalidateAndScheduleComposite()
{
if (window.mCompositorBridgeParent) {
window.mCompositorBridgeParent->InvalidateOnCompositorThread();
window.mCompositorBridgeParent->ScheduleRenderOnCompositorThread();
if (RefPtr<CompositorBridgeParent> bridge = window.GetCompositorBridgeParent()) {
bridge->InvalidateOnCompositorThread();
bridge->ScheduleRenderOnCompositorThread();
}
}
};
@ -3535,8 +3538,10 @@ nsWindow::ScheduleResumeComposition()
float
nsWindow::ComputeRenderIntegrity()
{
if (gGeckoViewWindow && gGeckoViewWindow->mCompositorBridgeParent) {
return gGeckoViewWindow->mCompositorBridgeParent->ComputeRenderIntegrity();
if (gGeckoViewWindow) {
if (RefPtr<CompositorBridgeParent> bridge = gGeckoViewWindow->GetCompositorBridgeParent()) {
return bridge->ComputeRenderIntegrity();
}
}
return 1.f;
@ -3618,3 +3623,9 @@ nsWindow::UpdateZoomConstraints(const uint32_t& aPresShellId,
NS_ConvertASCIItoUTF16(json.get()).get());
#endif
}
CompositorBridgeParent*
nsWindow::GetCompositorBridgeParent() const
{
return mCompositorSession ? mCompositorSession->GetInProcessBridge() : nullptr;
}

View File

@ -204,6 +204,8 @@ public:
nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
nsIObserver* aObserver) override;
CompositorBridgeParent* GetCompositorBridgeParent() const;
protected:
void BringToFront();
nsWindow *FindTopLevel();

View File

@ -44,6 +44,7 @@
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorSession.h"
#include "mozilla/TouchEvents.h"
#include "HwcComposer2D.h"
@ -697,10 +698,10 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
}
CreateCompositor();
if (mCompositorBridgeParent) {
mScreen->SetCompositorBridgeParent(mCompositorBridgeParent);
if (RefPtr<CompositorBridgeParent> bridge = GetCompositorBridgeParent()) {
mScreen->SetCompositorBridgeParent(bridge);
if (mScreen->IsPrimaryScreen()) {
mComposer2D->SetCompositorBridgeParent(mCompositorBridgeParent);
mComposer2D->SetCompositorBridgeParent(bridge);
}
}
MOZ_ASSERT(mLayerManager);
@ -710,7 +711,7 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
void
nsWindow::DestroyCompositor()
{
if (mCompositorBridgeParent) {
if (RefPtr<CompositorBridgeParent> bridge = GetCompositorBridgeParent()) {
mScreen->SetCompositorBridgeParent(nullptr);
if (mScreen->IsPrimaryScreen()) {
// Unset CompositorBridgeParent
@ -793,3 +794,9 @@ nsWindow::GetComposer2D()
return mComposer2D;
}
CompositorBridgeParent*
nsWindow::GetCompositorBridgeParent() const
{
return mCompositorSession ? mCompositorSession->GetInProcessBridge() : nullptr;
}

View File

@ -149,6 +149,7 @@ protected:
bool UseExternalCompositingSurface() const override {
return true;
}
CompositorBridgeParent* GetCompositorBridgeParent() const;
private:
// This is used by SynthesizeNativeTouchPoint to maintain state between

View File

@ -2146,7 +2146,7 @@ nsWindow::OnExposeEvent(cairo_t *cr)
? static_cast<ClientLayerManager*>(GetLayerManager())
: nullptr;
if (clientLayers && mCompositorBridgeParent) {
if (clientLayers && mCompositorSession) {
// We need to paint to the screen even if nothing changed, since if we
// don't have a compositing window manager, our pixels could be stale.
clientLayers->SetNeedsComposite(true);

View File

@ -70,6 +70,7 @@
#include "nsAccessibilityService.h"
#endif
#include "gfxConfig.h"
#include "mozilla/layers/CompositorSession.h"
#ifdef DEBUG
#include "nsIObserver.h"
@ -271,8 +272,8 @@ void nsBaseWidget::DestroyCompositor()
// XXX CompositorBridgeChild and CompositorBridgeParent might be re-created in
// ClientLayerManager destructor. See bug 1133426.
RefPtr<CompositorBridgeChild> compositorChild = mCompositorBridgeChild;
RefPtr<CompositorBridgeParent> compositorParent = mCompositorBridgeParent;
mCompositorBridgeChild->Destroy();
RefPtr<CompositorSession> compositorSession = mCompositorSession;
mCompositorSession->Shutdown();
mCompositorBridgeChild = nullptr;
}
@ -296,7 +297,7 @@ void nsBaseWidget::DestroyLayerManager()
void
nsBaseWidget::OnRenderingDeviceReset()
{
if (!mLayerManager || !mCompositorBridgeParent) {
if (!mLayerManager || !mCompositorSession) {
return;
}
@ -316,9 +317,14 @@ nsBaseWidget::OnRenderingDeviceReset()
return;
}
RefPtr<CompositorBridgeParent> parent = mCompositorSession->GetInProcessBridge();
if (!parent) {
return;
}
// Recreate the compositor.
TextureFactoryIdentifier identifier;
if (!mCompositorBridgeParent->ResetCompositor(backendHints, &identifier)) {
if (!parent->ResetCompositor(backendHints, &identifier)) {
// No action was taken, so we don't have to do anything.
return;
}
@ -988,8 +994,7 @@ void nsBaseWidget::ConfigureAPZCTreeManager()
mRootContentController = CreateRootContentController();
if (mRootContentController) {
uint64_t rootLayerTreeId = mCompositorBridgeParent->RootLayerTreeId();
CompositorBridgeParent::SetControllerForLayerTree(rootLayerTreeId, mRootContentController);
mCompositorSession->SetContentController(mRootContentController);
}
// When APZ is enabled, we can actually enable raw touch events because we
@ -1025,7 +1030,7 @@ nsBaseWidget::UpdateZoomConstraints(const uint32_t& aPresShellId,
const FrameMetrics::ViewID& aViewId,
const Maybe<ZoomConstraints>& aConstraints)
{
if (!mCompositorBridgeParent || !mAPZC) {
if (!mCompositorSession || !mAPZC) {
if (mInitialZoomConstraints) {
MOZ_ASSERT(mInitialZoomConstraints->mPresShellID == aPresShellId);
MOZ_ASSERT(mInitialZoomConstraints->mViewID == aViewId);
@ -1041,7 +1046,7 @@ nsBaseWidget::UpdateZoomConstraints(const uint32_t& aPresShellId,
}
return;
}
uint64_t layersId = mCompositorBridgeParent->RootLayerTreeId();
uint64_t layersId = mCompositorSession->RootLayerTreeId();
mAPZC->UpdateZoomConstraints(ScrollableLayerGuid(layersId, aPresShellId, aViewId),
aConstraints);
}
@ -1066,7 +1071,7 @@ nsBaseWidget::ProcessUntransformedAPZEvent(WidgetInputEvent* aEvent,
// event. If the event is instead targeted to an APZC in the child process,
// the transform will be applied in the child process before dispatching
// the event there (see e.g. TabChild::RecvRealTouchEvent()).
if (aGuid.mLayersId == mCompositorBridgeParent->RootLayerTreeId()) {
if (aGuid.mLayersId == mCompositorSession->RootLayerTreeId()) {
APZCCallbackHelper::ApplyCallbackTransform(*aEvent, aGuid,
GetDefaultScale());
}
@ -1255,7 +1260,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
MOZ_ASSERT(gfxPlatform::UsesOffMainThreadCompositing(),
"This function assumes OMTC");
MOZ_ASSERT(!mCompositorBridgeParent && !mCompositorBridgeChild,
MOZ_ASSERT(!mCompositorSession && !mCompositorBridgeChild,
"Should have properly cleaned up the previous PCompositor pair beforehand");
if (mCompositorBridgeChild) {
@ -1277,21 +1282,18 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
mCompositorWidgetProxy = NewCompositorWidgetProxy();
}
mCompositorBridgeParent = new CompositorBridgeParent(
RefPtr<ClientLayerManager> lm = new ClientLayerManager(this);
mCompositorSession = CompositorSession::CreateTopLevel(
mCompositorWidgetProxy,
lm,
GetDefaultScale(),
UseAPZ(),
UseExternalCompositingSurface(),
aWidth, aHeight);
RefPtr<ClientLayerManager> lm = new ClientLayerManager(this);
mCompositorBridgeChild = new CompositorBridgeChild(lm);
mCompositorBridgeChild->OpenSameProcess(mCompositorBridgeParent);
mCompositorBridgeChild = mCompositorSession->GetCompositorBridgeChild();
// Make sure the parent knows it is same process.
mCompositorBridgeParent->SetOtherProcessId(base::GetCurrentProcId());
uint64_t rootLayerTreeId = mCompositorBridgeParent->RootLayerTreeId();
mAPZC = CompositorBridgeParent::GetAPZCTreeManager(rootLayerTreeId);
mAPZC = mCompositorSession->GetAPZCTreeManager();
if (mAPZC) {
ConfigureAPZCTreeManager();
}
@ -1327,7 +1329,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
DestroyCompositor();
mLayerManager = nullptr;
mCompositorBridgeChild = nullptr;
mCompositorBridgeParent = nullptr;
mCompositorSession = nullptr;
mCompositorVsyncDispatcher = nullptr;
return;
}
@ -1861,10 +1863,10 @@ nsBaseWidget::ZoomToRect(const uint32_t& aPresShellId,
const CSSRect& aRect,
const uint32_t& aFlags)
{
if (!mCompositorBridgeParent || !mAPZC) {
if (!mCompositorSession || !mAPZC) {
return;
}
uint64_t layerId = mCompositorBridgeParent->RootLayerTreeId();
uint64_t layerId = mCompositorSession->RootLayerTreeId();
mAPZC->ZoomToRect(ScrollableLayerGuid(layerId, aPresShellId, aViewId), aRect, aFlags);
}
@ -1910,9 +1912,9 @@ nsBaseWidget::StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics)
return;
}
MOZ_ASSERT(XRE_IsParentProcess() && mCompositorBridgeParent);
MOZ_ASSERT(XRE_IsParentProcess() && mCompositorSession);
int layersId = mCompositorBridgeParent->RootLayerTreeId();;
int layersId = mCompositorSession->RootLayerTreeId();;
ScrollableLayerGuid guid(layersId, aDragMetrics.mPresShellId, aDragMetrics.mViewId);
APZThreadUtils::RunOnControllerThread(NewRunnableMethod

View File

@ -46,6 +46,7 @@ class CompositorBridgeParent;
class APZCTreeManager;
class GeckoContentController;
class APZEventState;
class CompositorSession;
struct ScrollableLayerGuid;
} // namespace layers
@ -112,6 +113,7 @@ protected:
typedef mozilla::CSSRect CSSRect;
typedef mozilla::ScreenRotation ScreenRotation;
typedef mozilla::widget::CompositorWidgetProxy CompositorWidgetProxy;
typedef mozilla::layers::CompositorSession CompositorSession;
virtual ~nsBaseWidget();
@ -560,8 +562,8 @@ protected:
nsIWidgetListener* mAttachedWidgetListener;
nsIWidgetListener* mPreviouslyAttachedWidgetListener;
RefPtr<LayerManager> mLayerManager;
RefPtr<CompositorSession> mCompositorSession;
RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
RefPtr<mozilla::CompositorVsyncDispatcher> mCompositorVsyncDispatcher;
RefPtr<APZCTreeManager> mAPZC;
RefPtr<GeckoContentController> mRootContentController;

View File

@ -3629,7 +3629,7 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
}
if (!mLayerManager) {
MOZ_ASSERT(!mCompositorBridgeParent && !mCompositorBridgeChild);
MOZ_ASSERT(!mCompositorSession && !mCompositorBridgeChild);
// Ensure we have a widget proxy even if we're not using the compositor,
// since that's where we handle transparent windows.