Bug 1107009. r=BenWa

This commit is contained in:
Kartikaya Gupta 2015-01-12 14:57:54 -05:00
parent 34597a91c4
commit 8b9fe5f8f4

View File

@ -24,6 +24,7 @@
#endif
#include "gfxPrefs.h" // for gfxPrefs
#include "mozilla/AutoRestore.h" // for AutoRestore
#include "mozilla/ClearOnShutdown.h" // for ClearOnShutdown
#include "mozilla/DebugOnly.h" // for DebugOnly
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/Point.h" // for IntSize
@ -88,6 +89,16 @@ CompositorParent::LayerTreeState::LayerTreeState()
typedef map<uint64_t, CompositorParent::LayerTreeState> LayerTreeMap;
static LayerTreeMap sIndirectLayerTrees;
static StaticAutoPtr<mozilla::Monitor> sIndirectLayerTreesLock;
static void EnsureLayerTreeMapReady()
{
MOZ_ASSERT(NS_IsMainThread());
if (!sIndirectLayerTreesLock) {
sIndirectLayerTreesLock = new Monitor("IndirectLayerTree");
mozilla::ClearOnShutdown(&sIndirectLayerTreesLock);
}
}
/**
* A global map referencing each compositor by ID.
@ -384,7 +395,12 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(SetThreadPriority));
mRootLayerTreeID = AllocateLayerTreeId();
EnsureLayerTreeMapReady();
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
}
if (gfxPrefs::AsyncPanZoomEnabled()) {
mApzcTreeManager = new APZCTreeManager();
@ -433,7 +449,10 @@ CompositorParent::Destroy()
mApzcTreeManager->ClearTree();
mApzcTreeManager = nullptr;
}
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees.erase(mRootLayerTreeID);
}
if (mCompositorVsyncObserver) {
mCompositorVsyncObserver->UnobserveVsync();
mCompositorVsyncObserver = nullptr;
@ -454,6 +473,7 @@ CompositorParent::RecvWillStop()
// Ensure that the layer manager is destroyed before CompositorChild.
if (mLayerManager) {
MonitorAutoLock lock(*sIndirectLayerTreesLock);
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
it != sIndirectLayerTrees.end(); it++)
{
@ -585,7 +605,10 @@ CompositorParent::ActorDestroy(ActorDestroyReason why)
if (mLayerManager) {
mLayerManager->Destroy();
mLayerManager = nullptr;
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = nullptr;
}
mCompositionManager = nullptr;
mCompositor = nullptr;
}
@ -1098,6 +1121,7 @@ void
CompositorParent::GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData)
{
MonitorAutoLock lock(*sIndirectLayerTreesLock);
*aOutData = sIndirectLayerTrees[mRootLayerTreeID].mApzTestData;
}
@ -1145,6 +1169,7 @@ CompositorParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackend
mLayerManager = layerManager;
MOZ_ASSERT(compositor);
mCompositor = compositor;
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = layerManager;
return;
}
@ -1230,6 +1255,7 @@ CompositorParent::RecvNotifyChildCreated(const uint64_t& child)
void
CompositorParent::NotifyChildCreated(const uint64_t& aChild)
{
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[aChild].mParent = this;
sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
}
@ -1238,6 +1264,7 @@ bool
CompositorParent::RecvAdoptChild(const uint64_t& child)
{
NotifyChildCreated(child);
MonitorAutoLock lock(*sIndirectLayerTreesLock);
if (sIndirectLayerTrees[child].mLayerTree) {
sIndirectLayerTrees[child].mLayerTree->mLayerManager = mLayerManager;
}
@ -1259,6 +1286,7 @@ CompositorParent::AllocateLayerTreeId()
static void
EraseLayerState(uint64_t aId)
{
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees.erase(aId);
}
@ -1278,6 +1306,7 @@ UpdateControllerForLayersId(uint64_t aLayersId,
GeckoContentController* aController)
{
// Adopt ref given to us by SetControllerForLayerTree()
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[aLayersId].mController =
already_AddRefed<GeckoContentController>(aController);
}
@ -1287,12 +1316,15 @@ ScopedLayerTreeRegistration::ScopedLayerTreeRegistration(uint64_t aLayersId,
GeckoContentController* aController)
: mLayersId(aLayersId)
{
EnsureLayerTreeMapReady();
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[aLayersId].mRoot = aRoot;
sIndirectLayerTrees[aLayersId].mController = aController;
}
ScopedLayerTreeRegistration::~ScopedLayerTreeRegistration()
{
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees.erase(mLayersId);
}
@ -1463,6 +1495,7 @@ CompositorParent::DidComposite()
mPendingTransaction = 0;
}
MonitorAutoLock lock(*sIndirectLayerTreesLock);
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
it != sIndirectLayerTrees.end(); it++) {
LayerTreeState* lts = &it->second;
@ -1525,6 +1558,7 @@ CompositorParent::CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdM
static void
UpdateIndirectTree(uint64_t aId, Layer* aRoot, const TargetConfig& aTargetConfig)
{
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[aId].mRoot = aRoot;
sIndirectLayerTrees[aId].mTargetConfig = aTargetConfig;
}
@ -1532,6 +1566,8 @@ UpdateIndirectTree(uint64_t aId, Layer* aRoot, const TargetConfig& aTargetConfig
/* static */ CompositorParent::LayerTreeState*
CompositorParent::GetIndirectShadowTree(uint64_t aId)
{
EnsureLayerTreeMapReady();
MonitorAutoLock lock(*sIndirectLayerTreesLock);
LayerTreeMap::iterator cit = sIndirectLayerTrees.find(aId);
if (sIndirectLayerTrees.end() == cit) {
return nullptr;
@ -1539,12 +1575,6 @@ CompositorParent::GetIndirectShadowTree(uint64_t aId)
return &cit->second;
}
static void
RemoveIndirectTree(uint64_t aId)
{
sIndirectLayerTrees.erase(aId);
}
bool
CrossProcessCompositorParent::RecvRequestNotifyAfterRemotePaint()
{
@ -1568,6 +1598,9 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArray<Layers
{
MOZ_ASSERT(aId != 0);
EnsureLayerTreeMapReady();
MonitorAutoLock lock(*sIndirectLayerTreesLock);
CompositorParent::LayerTreeState* state = nullptr;
LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
if (sIndirectLayerTrees.end() != itr) {
@ -1598,7 +1631,7 @@ bool
CrossProcessCompositorParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
{
LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
RemoveIndirectTree(slp->GetId());
EraseLayerState(slp->GetId());
static_cast<LayerTransactionParent*>(aLayers)->ReleaseIPDLReference();
return true;
}
@ -1606,6 +1639,7 @@ CrossProcessCompositorParent::DeallocPLayerTransactionParent(PLayerTransactionPa
bool
CrossProcessCompositorParent::RecvNotifyChildCreated(const uint64_t& child)
{
MonitorAutoLock lock(*sIndirectLayerTreesLock);
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
it != sIndirectLayerTrees.end(); it++) {
CompositorParent::LayerTreeState* lts = &it->second;
@ -1659,6 +1693,7 @@ CrossProcessCompositorParent::ShadowLayersUpdated(
void
CrossProcessCompositorParent::DidComposite(uint64_t aId)
{
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree;
if (layerTree && layerTree->GetPendingTransactionId()) {
unused << SendDidComposite(aId, layerTree->GetPendingTransactionId());
@ -1671,7 +1706,12 @@ CrossProcessCompositorParent::ForceComposite(LayerTransactionParent* aLayerTree)
{
uint64_t id = aLayerTree->GetId();
MOZ_ASSERT(id != 0);
sIndirectLayerTrees[id].mParent->ForceComposite(aLayerTree);
CompositorParent* parent;
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
parent = sIndirectLayerTrees[id].mParent;
}
parent->ForceComposite(aLayerTree);
}
bool
@ -1709,6 +1749,7 @@ CrossProcessCompositorParent::GetAPZTestData(const LayerTransactionParent* aLaye
{
uint64_t id = aLayerTree->GetId();
MOZ_ASSERT(id != 0);
MonitorAutoLock lock(*sIndirectLayerTreesLock);
*aOutData = sIndirectLayerTrees[id].mApzTestData;
}