LCOV - code coverage report
Current view: top level - gfx/layers/ipc - CompositorBridgeParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 169 1059 16.0 %
Date: 2018-08-07 16:35:00 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/layers/CompositorBridgeParent.h"
       8             : 
       9             : #include <stdio.h>                      // for fprintf, stdout
      10             : #include <stdint.h>                     // for uint64_t
      11             : #include <map>                          // for _Rb_tree_iterator, etc
      12             : #include <utility>                      // for pair
      13             : 
      14             : #include "apz/src/APZCTreeManager.h"    // for APZCTreeManager
      15             : #include "LayerTransactionParent.h"     // for LayerTransactionParent
      16             : #include "RenderTrace.h"                // for RenderTraceLayers
      17             : #include "base/message_loop.h"          // for MessageLoop
      18             : #include "base/process.h"               // for ProcessId
      19             : #include "base/task.h"                  // for CancelableTask, etc
      20             : #include "base/thread.h"                // for Thread
      21             : #include "gfxContext.h"                 // for gfxContext
      22             : #include "gfxPlatform.h"                // for gfxPlatform
      23             : #include "TreeTraversal.h"              // for ForEachNode
      24             : #ifdef MOZ_WIDGET_GTK
      25             : #include "gfxPlatformGtk.h"             // for gfxPlatform
      26             : #endif
      27             : #include "gfxPrefs.h"                   // for gfxPrefs
      28             : #include "mozilla/AutoRestore.h"        // for AutoRestore
      29             : #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
      30             : #include "mozilla/DebugOnly.h"          // for DebugOnly
      31             : #include "mozilla/dom/ContentParent.h"
      32             : #include "mozilla/dom/TabParent.h"
      33             : #include "mozilla/gfx/2D.h"          // for DrawTarget
      34             : #include "mozilla/gfx/GPUChild.h"       // for GfxPrefValue
      35             : #include "mozilla/gfx/Point.h"          // for IntSize
      36             : #include "mozilla/gfx/Rect.h"          // for IntSize
      37             : #include "mozilla/gfx/gfxVars.h"        // for gfxVars
      38             : #include "VRManager.h"                  // for VRManager
      39             : #include "mozilla/ipc/Transport.h"      // for Transport
      40             : #include "mozilla/gfx/gfxVars.h"
      41             : #include "mozilla/gfx/GPUParent.h"
      42             : #include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
      43             : #include "mozilla/layers/APZCTreeManagerParent.h"  // for APZCTreeManagerParent
      44             : #include "mozilla/layers/APZSampler.h"  // for APZSampler
      45             : #include "mozilla/layers/APZThreadUtils.h"  // for APZThreadUtils
      46             : #include "mozilla/layers/APZUpdater.h"  // for APZUpdater
      47             : #include "mozilla/layers/AsyncCompositionManager.h"
      48             : #include "mozilla/layers/BasicCompositor.h"  // for BasicCompositor
      49             : #include "mozilla/layers/Compositor.h"  // for Compositor
      50             : #include "mozilla/layers/CompositorManagerParent.h" // for CompositorManagerParent
      51             : #include "mozilla/layers/CompositorOGL.h"  // for CompositorOGL
      52             : #include "mozilla/layers/CompositorThread.h"
      53             : #include "mozilla/layers/CompositorTypes.h"
      54             : #include "mozilla/layers/CompositorVsyncScheduler.h"
      55             : #include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
      56             : #include "mozilla/layers/FrameUniformityData.h"
      57             : #include "mozilla/layers/ImageBridgeParent.h"
      58             : #include "mozilla/layers/LayerManagerComposite.h"
      59             : #include "mozilla/layers/LayerManagerMLGPU.h"
      60             : #include "mozilla/layers/LayerTreeOwnerTracker.h"
      61             : #include "mozilla/layers/LayersTypes.h"
      62             : #include "mozilla/layers/PLayerTransactionParent.h"
      63             : #include "mozilla/layers/RemoteContentController.h"
      64             : #include "mozilla/layers/WebRenderBridgeParent.h"
      65             : #include "mozilla/layers/AsyncImagePipelineManager.h"
      66             : #include "mozilla/layout/RenderFrameParent.h"
      67             : #include "mozilla/webrender/WebRenderAPI.h"
      68             : #include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService
      69             : #include "mozilla/mozalloc.h"           // for operator new, etc
      70             : #include "mozilla/Telemetry.h"
      71             : #ifdef MOZ_WIDGET_GTK
      72             : #include "basic/X11BasicCompositor.h" // for X11BasicCompositor
      73             : #endif
      74             : #include "nsCOMPtr.h"                   // for already_AddRefed
      75             : #include "nsDebug.h"                    // for NS_ASSERTION, etc
      76             : #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
      77             : #include "nsIWidget.h"                  // for nsIWidget
      78             : #include "nsTArray.h"                   // for nsTArray
      79             : #include "nsThreadUtils.h"              // for NS_IsMainThread
      80             : #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop
      81             : #ifdef XP_WIN
      82             : #include "mozilla/layers/CompositorD3D11.h"
      83             : #include "mozilla/widget/WinCompositorWidget.h"
      84             : #endif
      85             : #include "GeckoProfiler.h"
      86             : #include "mozilla/ipc/ProtocolTypes.h"
      87             : #include "mozilla/Unused.h"
      88             : #include "mozilla/Hal.h"
      89             : #include "mozilla/HalTypes.h"
      90             : #include "mozilla/StaticPtr.h"
      91             : #include "mozilla/Telemetry.h"
      92             : #ifdef MOZ_GECKO_PROFILER
      93             : # include "ProfilerMarkerPayload.h"
      94             : #endif
      95             : #include "mozilla/VsyncDispatcher.h"
      96             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
      97             : # include "VsyncSource.h"
      98             : #endif
      99             : #include "mozilla/widget/CompositorWidget.h"
     100             : #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
     101             : # include "mozilla/widget/CompositorWidgetParent.h"
     102             : #endif
     103             : #ifdef XP_WIN
     104             : # include "mozilla/gfx/DeviceManagerDx.h"
     105             : #endif
     106             : 
     107             : #include "LayerScope.h"
     108             : 
     109             : namespace mozilla {
     110             : 
     111             : namespace layers {
     112             : 
     113             : using namespace mozilla::ipc;
     114             : using namespace mozilla::gfx;
     115             : using namespace std;
     116             : 
     117             : using base::ProcessId;
     118             : using base::Thread;
     119             : 
     120           0 : CompositorBridgeParentBase::CompositorBridgeParentBase(CompositorManagerParent* aManager)
     121             :   : mCanSend(true)
     122           0 :   , mCompositorManager(aManager)
     123             : {
     124           0 : }
     125             : 
     126           0 : CompositorBridgeParentBase::~CompositorBridgeParentBase()
     127             : {
     128           0 : }
     129             : 
     130             : ProcessId
     131           0 : CompositorBridgeParentBase::GetChildProcessId()
     132             : {
     133           0 :   return OtherPid();
     134             : }
     135             : 
     136             : void
     137           0 : CompositorBridgeParentBase::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
     138             : {
     139           0 :   RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
     140           0 :   if (!texture) {
     141           0 :     return;
     142             :   }
     143             : 
     144           0 :   if (!(texture->GetFlags() & TextureFlags::RECYCLE)) {
     145             :     return;
     146             :   }
     147             : 
     148           0 :   uint64_t textureId = TextureHost::GetTextureSerial(aTexture);
     149           0 :   mPendingAsyncMessage.push_back(
     150           0 :     OpNotifyNotUsed(textureId, aTransactionId));
     151             : }
     152             : 
     153             : void
     154           0 : CompositorBridgeParentBase::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
     155             : {
     156           0 :   Unused << SendParentAsyncMessages(aMessage);
     157           0 : }
     158             : 
     159             : bool
     160           0 : CompositorBridgeParentBase::AllocShmem(size_t aSize,
     161             :                                    ipc::SharedMemory::SharedMemoryType aType,
     162             :                                    ipc::Shmem* aShmem)
     163             : {
     164           0 :   return PCompositorBridgeParent::AllocShmem(aSize, aType, aShmem);
     165             : }
     166             : 
     167             : bool
     168           0 : CompositorBridgeParentBase::AllocUnsafeShmem(size_t aSize,
     169             :                                          ipc::SharedMemory::SharedMemoryType aType,
     170             :                                          ipc::Shmem* aShmem)
     171             : {
     172           0 :   return PCompositorBridgeParent::AllocUnsafeShmem(aSize, aType, aShmem);
     173             : }
     174             : 
     175             : void
     176           0 : CompositorBridgeParentBase::DeallocShmem(ipc::Shmem& aShmem)
     177             : {
     178           0 :   PCompositorBridgeParent::DeallocShmem(aShmem);
     179           0 : }
     180             : 
     181             : static inline MessageLoop*
     182             : CompositorLoop()
     183             : {
     184           0 :   return CompositorThreadHolder::Loop();
     185             : }
     186             : 
     187             : base::ProcessId
     188           0 : CompositorBridgeParentBase::RemotePid()
     189             : {
     190           0 :   return OtherPid();
     191             : }
     192             : 
     193             : bool
     194           0 : CompositorBridgeParentBase::StartSharingMetrics(ipc::SharedMemoryBasic::Handle aHandle,
     195             :                                                 CrossProcessMutexHandle aMutexHandle,
     196             :                                                 LayersId aLayersId,
     197             :                                                 uint32_t aApzcId)
     198             : {
     199           0 :   if (!CompositorThreadHolder::IsInCompositorThread()) {
     200           0 :     MOZ_ASSERT(CompositorLoop());
     201           0 :     CompositorLoop()->PostTask(
     202             :       NewRunnableMethod<ipc::SharedMemoryBasic::Handle,
     203             :                         CrossProcessMutexHandle,
     204             :                         LayersId,
     205           0 :                         uint32_t>(
     206             :         "layers::CompositorBridgeParent::StartSharingMetrics",
     207             :         this,
     208             :         &CompositorBridgeParentBase::StartSharingMetrics,
     209           0 :         aHandle, aMutexHandle, aLayersId, aApzcId));
     210           0 :     return true;
     211             :   }
     212             : 
     213           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     214           0 :   if (!mCanSend) {
     215             :     return false;
     216             :   }
     217           0 :   return PCompositorBridgeParent::SendSharedCompositorFrameMetrics(
     218           0 :     aHandle, aMutexHandle, aLayersId, aApzcId);
     219             : }
     220             : 
     221             : bool
     222           0 : CompositorBridgeParentBase::StopSharingMetrics(FrameMetrics::ViewID aScrollId,
     223             :                                                uint32_t aApzcId)
     224             : {
     225           0 :   if (!CompositorThreadHolder::IsInCompositorThread()) {
     226           0 :     MOZ_ASSERT(CompositorLoop());
     227           0 :     CompositorLoop()->PostTask(
     228           0 :       NewRunnableMethod<FrameMetrics::ViewID, uint32_t>(
     229             :         "layers::CompositorBridgeParent::StopSharingMetrics",
     230             :         this,
     231             :         &CompositorBridgeParentBase::StopSharingMetrics,
     232           0 :         aScrollId, aApzcId));
     233           0 :     return true;
     234             :   }
     235             : 
     236           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     237           0 :   if (!mCanSend) {
     238             :     return false;
     239             :   }
     240           0 :   return PCompositorBridgeParent::SendReleaseSharedCompositorFrameMetrics(
     241           0 :     aScrollId, aApzcId);
     242             : }
     243             : 
     244           0 : CompositorBridgeParent::LayerTreeState::LayerTreeState()
     245             :   : mApzcTreeManagerParent(nullptr)
     246             :   , mParent(nullptr)
     247             :   , mLayerManager(nullptr)
     248             :   , mCrossProcessParent(nullptr)
     249             :   , mLayerTree(nullptr)
     250           0 :   , mUpdatedPluginDataAvailable(false)
     251             : {
     252           0 : }
     253             : 
     254           0 : CompositorBridgeParent::LayerTreeState::~LayerTreeState()
     255             : {
     256           0 :   if (mController) {
     257           0 :     mController->Destroy();
     258             :   }
     259           0 : }
     260             : 
     261             : typedef map<LayersId, CompositorBridgeParent::LayerTreeState> LayerTreeMap;
     262             : LayerTreeMap sIndirectLayerTrees;
     263             : StaticAutoPtr<mozilla::Monitor> sIndirectLayerTreesLock;
     264             : 
     265           0 : static void EnsureLayerTreeMapReady()
     266             : {
     267           0 :   MOZ_ASSERT(NS_IsMainThread());
     268           0 :   if (!sIndirectLayerTreesLock) {
     269           0 :     sIndirectLayerTreesLock = new Monitor("IndirectLayerTree");
     270           0 :     mozilla::ClearOnShutdown(&sIndirectLayerTreesLock);
     271             :   }
     272           0 : }
     273             : 
     274             : template <typename Lambda>
     275             : inline void
     276           0 : CompositorBridgeParent::ForEachIndirectLayerTree(const Lambda& aCallback)
     277             : {
     278           0 :   sIndirectLayerTreesLock->AssertCurrentThreadOwns();
     279           0 :   for (auto it = sIndirectLayerTrees.begin(); it != sIndirectLayerTrees.end(); it++) {
     280           0 :     LayerTreeState* state = &it->second;
     281           0 :     if (state->mParent == this) {
     282           0 :       aCallback(state, it->first);
     283             :     }
     284             :   }
     285           0 : }
     286             : 
     287             : /**
     288             :   * A global map referencing each compositor by ID.
     289             :   *
     290             :   * This map is used by the ImageBridge protocol to trigger
     291             :   * compositions without having to keep references to the
     292             :   * compositor
     293             :   */
     294             : typedef map<uint64_t,CompositorBridgeParent*> CompositorMap;
     295           0 : static StaticAutoPtr<CompositorMap> sCompositorMap;
     296             : 
     297             : void
     298           0 : CompositorBridgeParent::Setup()
     299             : {
     300           0 :   EnsureLayerTreeMapReady();
     301             : 
     302           0 :   MOZ_ASSERT(!sCompositorMap);
     303           0 :   sCompositorMap = new CompositorMap;
     304           0 : }
     305             : 
     306             : void
     307           0 : CompositorBridgeParent::Shutdown()
     308             : {
     309           0 :   MOZ_ASSERT(sCompositorMap);
     310           0 :   MOZ_ASSERT(sCompositorMap->empty());
     311           0 :   sCompositorMap = nullptr;
     312           0 : }
     313             : 
     314             : void
     315           0 : CompositorBridgeParent::FinishShutdown()
     316             : {
     317             :   // TODO: this should be empty by now...
     318           0 :   sIndirectLayerTrees.clear();
     319           0 : }
     320             : 
     321             : #ifdef COMPOSITOR_PERFORMANCE_WARNING
     322             : static int32_t
     323             : CalculateCompositionFrameRate()
     324             : {
     325             :   // Used when layout.frame_rate is -1. Needs to be kept in sync with
     326             :   // DEFAULT_FRAME_RATE in nsRefreshDriver.cpp.
     327             :   // TODO: This should actually return the vsync rate.
     328             :   const int32_t defaultFrameRate = 60;
     329             :   int32_t compositionFrameRatePref = gfxPrefs::LayersCompositionFrameRate();
     330             :   if (compositionFrameRatePref < 0) {
     331             :     // Use the same frame rate for composition as for layout.
     332             :     int32_t layoutFrameRatePref = gfxPrefs::LayoutFrameRate();
     333             :     if (layoutFrameRatePref < 0) {
     334             :       // TODO: The main thread frame scheduling code consults the actual
     335             :       // monitor refresh rate in this case. We should do the same.
     336             :       return defaultFrameRate;
     337             :     }
     338             :     return layoutFrameRatePref;
     339             :   }
     340             :   return compositionFrameRatePref;
     341             : }
     342             : #endif
     343             : 
     344           0 : CompositorBridgeParent::CompositorBridgeParent(CompositorManagerParent* aManager,
     345             :                                                CSSToLayoutDeviceScale aScale,
     346             :                                                const TimeDuration& aVsyncRate,
     347             :                                                const CompositorOptions& aOptions,
     348             :                                                bool aUseExternalSurfaceSize,
     349           0 :                                                const gfx::IntSize& aSurfaceSize)
     350             :   : CompositorBridgeParentBase(aManager)
     351             :   , mWidget(nullptr)
     352             :   , mScale(aScale)
     353             :   , mVsyncRate(aVsyncRate)
     354             :   , mPendingTransaction{0}
     355             :   , mPaused(false)
     356             :   , mUseExternalSurfaceSize(aUseExternalSurfaceSize)
     357             :   , mEGLSurfaceSize(aSurfaceSize)
     358             :   , mOptions(aOptions)
     359             :   , mPauseCompositionMonitor("PauseCompositionMonitor")
     360             :   , mResumeCompositionMonitor("ResumeCompositionMonitor")
     361             :   , mRootLayerTreeID{0}
     362             :   , mOverrideComposeReadiness(false)
     363             :   , mForceCompositionTask(nullptr)
     364             :   , mCompositorScheduler(nullptr)
     365             :   , mAnimationStorage(nullptr)
     366             :   , mPaintTime(TimeDuration::Forever())
     367             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
     368             :   , mLastPluginUpdateLayerTreeId{0}
     369             :   , mDeferPluginWindows(false)
     370           0 :   , mPluginWindowsHidden(false)
     371             : #endif
     372             : {
     373           0 : }
     374             : 
     375             : void
     376           0 : CompositorBridgeParent::InitSameProcess(widget::CompositorWidget* aWidget,
     377             :                                         const LayersId& aLayerTreeId)
     378             : {
     379           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     380           0 :   MOZ_ASSERT(NS_IsMainThread());
     381             : 
     382           0 :   mWidget = aWidget;
     383           0 :   mRootLayerTreeID = aLayerTreeId;
     384             : 
     385           0 :   Initialize();
     386           0 : }
     387             : 
     388             : mozilla::ipc::IPCResult
     389           0 : CompositorBridgeParent::RecvInitialize(const LayersId& aRootLayerTreeId)
     390             : {
     391           0 :   MOZ_ASSERT(XRE_IsGPUProcess());
     392             : 
     393           0 :   mRootLayerTreeID = aRootLayerTreeId;
     394             : 
     395           0 :   Initialize();
     396           0 :   return IPC_OK();
     397             : }
     398             : 
     399             : void
     400           0 : CompositorBridgeParent::Initialize()
     401             : {
     402           0 :   MOZ_ASSERT(CompositorThread(),
     403             :              "The compositor thread must be Initialized before instanciating a CompositorBridgeParent.");
     404             : 
     405           0 :   if (mOptions.UseAPZ()) {
     406           0 :     MOZ_ASSERT(!mApzcTreeManager);
     407           0 :     MOZ_ASSERT(!mApzSampler);
     408           0 :     MOZ_ASSERT(!mApzUpdater);
     409           0 :     mApzcTreeManager = new APZCTreeManager(mRootLayerTreeID);
     410           0 :     mApzSampler = new APZSampler(mApzcTreeManager, mOptions.UseWebRender());
     411           0 :     mApzUpdater = new APZUpdater(mApzcTreeManager, mOptions.UseWebRender());
     412             :   }
     413             : 
     414           0 :   mPaused = mOptions.InitiallyPaused();
     415             : 
     416           0 :   mCompositorBridgeID = 0;
     417             :   // FIXME: This holds on the the fact that right now the only thing that
     418             :   // can destroy this instance is initialized on the compositor thread after
     419             :   // this task has been processed.
     420           0 :   MOZ_ASSERT(CompositorLoop());
     421           0 :   CompositorLoop()->PostTask(NewRunnableFunction("AddCompositorRunnable",
     422             :                                                  &AddCompositor,
     423           0 :                                                  this, &mCompositorBridgeID));
     424             : 
     425             : 
     426             :   { // scope lock
     427           0 :     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     428           0 :     sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
     429             :   }
     430             : 
     431           0 :   LayerScope::SetPixelScale(mScale.scale);
     432             : 
     433           0 :   if (!mOptions.UseWebRender()) {
     434           0 :     mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
     435             :   }
     436           0 : }
     437             : 
     438             : LayersId
     439           0 : CompositorBridgeParent::RootLayerTreeId()
     440             : {
     441           0 :   MOZ_ASSERT(mRootLayerTreeID.IsValid());
     442           0 :   return mRootLayerTreeID;
     443             : }
     444             : 
     445           0 : CompositorBridgeParent::~CompositorBridgeParent()
     446             : {
     447           0 :   InfallibleTArray<PTextureParent*> textures;
     448           0 :   ManagedPTextureParent(textures);
     449             :   // We expect all textures to be destroyed by now.
     450           0 :   MOZ_DIAGNOSTIC_ASSERT(textures.Length() == 0);
     451           0 :   for (unsigned int i = 0; i < textures.Length(); ++i) {
     452           0 :     RefPtr<TextureHost> tex = TextureHost::AsTextureHost(textures[i]);
     453           0 :     tex->DeallocateDeviceData();
     454             :   }
     455           0 : }
     456             : 
     457             : mozilla::ipc::IPCResult
     458           0 : CompositorBridgeParent::RecvForceIsFirstPaint()
     459             : {
     460           0 :   mCompositionManager->ForceIsFirstPaint();
     461           0 :   return IPC_OK();
     462             : }
     463             : 
     464             : void
     465           0 : CompositorBridgeParent::StopAndClearResources()
     466             : {
     467           0 :   if (mForceCompositionTask) {
     468           0 :     mForceCompositionTask->Cancel();
     469           0 :     mForceCompositionTask = nullptr;
     470             :   }
     471             : 
     472           0 :   mPaused = true;
     473             : 
     474             :   // We need to clear the APZ tree before we destroy the WebRender API below,
     475             :   // because in the case of async scene building that will shut down the updater
     476             :   // thread and we need to run the task before that happens.
     477           0 :   MOZ_ASSERT((mApzSampler != nullptr) == (mApzcTreeManager != nullptr));
     478           0 :   MOZ_ASSERT((mApzUpdater != nullptr) == (mApzcTreeManager != nullptr));
     479           0 :   if (mApzUpdater) {
     480           0 :     mApzSampler = nullptr;
     481           0 :     mApzUpdater->ClearTree(mRootLayerTreeID);
     482           0 :     mApzUpdater = nullptr;
     483           0 :     mApzcTreeManager = nullptr;
     484             :   }
     485             : 
     486             :   // Ensure that the layer manager is destroyed before CompositorBridgeChild.
     487           0 :   if (mLayerManager) {
     488           0 :     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     489           0 :     ForEachIndirectLayerTree([this] (LayerTreeState* lts, LayersId) -> void {
     490           0 :       mLayerManager->ClearCachedResources(lts->mRoot);
     491           0 :       lts->mLayerManager = nullptr;
     492           0 :       lts->mParent = nullptr;
     493           0 :     });
     494           0 :     mLayerManager->Destroy();
     495           0 :     mLayerManager = nullptr;
     496           0 :     mCompositionManager = nullptr;
     497             :   }
     498             : 
     499           0 :   if (mWrBridge) {
     500             :     // Ensure we are not holding the sIndirectLayerTreesLock when destroying
     501             :     // the WebRenderBridgeParent instances because it may block on WR.
     502           0 :     std::vector<RefPtr<WebRenderBridgeParent>> indirectBridgeParents;
     503             :     { // scope lock
     504           0 :       MonitorAutoLock lock(*sIndirectLayerTreesLock);
     505           0 :       ForEachIndirectLayerTree([&] (LayerTreeState* lts, LayersId) -> void {
     506           0 :         if (lts->mWrBridge) {
     507           0 :           indirectBridgeParents.emplace_back(lts->mWrBridge.forget());
     508             :         }
     509           0 :         lts->mParent = nullptr;
     510           0 :       });
     511             :     }
     512           0 :     for (const RefPtr<WebRenderBridgeParent>& bridge : indirectBridgeParents) {
     513           0 :       bridge->Destroy();
     514             :     }
     515           0 :     indirectBridgeParents.clear();
     516             : 
     517             :     // Ensure we are not holding the sIndirectLayerTreesLock here because we
     518             :     // are going to block on WR threads in order to shut it down properly.
     519           0 :     mWrBridge->Destroy();
     520           0 :     mWrBridge = nullptr;
     521           0 :     if (mAsyncImageManager) {
     522           0 :       mAsyncImageManager->Destroy();
     523             :       // WebRenderAPI should be already destructed
     524           0 :       mAsyncImageManager = nullptr;
     525             :     }
     526             :   }
     527             : 
     528           0 :   if (mCompositor) {
     529           0 :     mCompositor->DetachWidget();
     530           0 :     mCompositor->Destroy();
     531           0 :     mCompositor = nullptr;
     532             :   }
     533             : 
     534             :   // This must be destroyed now since it accesses the widget.
     535           0 :   if (mCompositorScheduler) {
     536           0 :     mCompositorScheduler->Destroy();
     537           0 :     mCompositorScheduler = nullptr;
     538             :   }
     539             : 
     540             :   // After this point, it is no longer legal to access the widget.
     541           0 :   mWidget = nullptr;
     542             : 
     543             :   // Clear mAnimationStorage here to ensure that the compositor thread
     544             :   // still exists when we destroy it.
     545           0 :   mAnimationStorage = nullptr;
     546           0 : }
     547             : 
     548             : mozilla::ipc::IPCResult
     549           0 : CompositorBridgeParent::RecvWillClose()
     550             : {
     551           0 :   StopAndClearResources();
     552             :   // Once we get the WillClose message, the client side is going to go away
     553             :   // soon and we can't be guaranteed that sending messages will work.
     554           0 :   mCanSend = false;
     555           0 :   return IPC_OK();
     556             : }
     557             : 
     558           0 : void CompositorBridgeParent::DeferredDestroy()
     559             : {
     560           0 :   MOZ_ASSERT(!NS_IsMainThread());
     561           0 :   mSelfRef = nullptr;
     562           0 : }
     563             : 
     564             : mozilla::ipc::IPCResult
     565           0 : CompositorBridgeParent::RecvPause()
     566             : {
     567           0 :   PauseComposition();
     568           0 :   return IPC_OK();
     569             : }
     570             : 
     571             : mozilla::ipc::IPCResult
     572           0 : CompositorBridgeParent::RecvResume()
     573             : {
     574           0 :   ResumeComposition();
     575           0 :   return IPC_OK();
     576             : }
     577             : 
     578             : mozilla::ipc::IPCResult
     579           0 : CompositorBridgeParent::RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
     580             :                                          const gfx::IntRect& aRect)
     581             : {
     582           0 :   RefPtr<DrawTarget> target = GetDrawTargetForDescriptor(aInSnapshot, gfx::BackendType::CAIRO);
     583           0 :   MOZ_ASSERT(target);
     584           0 :   if (!target) {
     585             :     // We kill the content process rather than have it continue with an invalid
     586             :     // snapshot, that may be too harsh and we could decide to return some sort
     587             :     // of error to the child process and let it deal with it...
     588           0 :     return IPC_FAIL_NO_REASON(this);
     589             :   }
     590           0 :   ForceComposeToTarget(target, &aRect);
     591             :   return IPC_OK();
     592             : }
     593             : 
     594             : mozilla::ipc::IPCResult
     595           0 : CompositorBridgeParent::RecvWaitOnTransactionProcessed()
     596             : {
     597           0 :   return IPC_OK();
     598             : }
     599             : 
     600             : mozilla::ipc::IPCResult
     601           0 : CompositorBridgeParent::RecvFlushRendering()
     602             : {
     603           0 :   if (mWrBridge) {
     604           0 :     mWrBridge->FlushRendering();
     605             :     return IPC_OK();
     606             :   }
     607             : 
     608           0 :   if (mCompositorScheduler->NeedsComposite()) {
     609           0 :     CancelCurrentCompositeTask();
     610           0 :     ForceComposeToTarget(nullptr);
     611             :   }
     612             :   return IPC_OK();
     613             : }
     614             : 
     615             : mozilla::ipc::IPCResult
     616           0 : CompositorBridgeParent::RecvFlushRenderingAsync()
     617             : {
     618           0 :   if (mWrBridge) {
     619           0 :     mWrBridge->FlushRenderingAsync();
     620             :     return IPC_OK();
     621             :   }
     622             : 
     623           0 :   return RecvFlushRendering();
     624             : }
     625             : 
     626             : mozilla::ipc::IPCResult
     627           0 : CompositorBridgeParent::RecvForcePresent()
     628             : {
     629           0 :   if (mWrBridge) {
     630           0 :     mWrBridge->ScheduleGenerateFrame();
     631             :   }
     632             :   // During the shutdown sequence mLayerManager may be null
     633           0 :   if (mLayerManager) {
     634           0 :     mLayerManager->ForcePresent();
     635             :   }
     636           0 :   return IPC_OK();
     637             : }
     638             : 
     639             : mozilla::ipc::IPCResult
     640           0 : CompositorBridgeParent::RecvNotifyRegionInvalidated(const nsIntRegion& aRegion)
     641             : {
     642           0 :   if (mLayerManager) {
     643           0 :     mLayerManager->AddInvalidRegion(aRegion);
     644             :   }
     645           0 :   return IPC_OK();
     646             : }
     647             : 
     648             : void
     649           0 : CompositorBridgeParent::Invalidate()
     650             : {
     651           0 :   if (mLayerManager) {
     652           0 :     mLayerManager->InvalidateAll();
     653             :   }
     654           0 : }
     655             : 
     656             : mozilla::ipc::IPCResult
     657           0 : CompositorBridgeParent::RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex)
     658             : {
     659           0 :   if (mLayerManager) {
     660           0 :     *aOutStartIndex = mLayerManager->StartFrameTimeRecording(aBufferSize);
     661             :   } else {
     662           0 :     *aOutStartIndex = 0;
     663             :   }
     664           0 :   return IPC_OK();
     665             : }
     666             : 
     667             : mozilla::ipc::IPCResult
     668           0 : CompositorBridgeParent::RecvStopFrameTimeRecording(const uint32_t& aStartIndex,
     669             :                                                    InfallibleTArray<float>* intervals)
     670             : {
     671           0 :   if (mLayerManager) {
     672           0 :     mLayerManager->StopFrameTimeRecording(aStartIndex, *intervals);
     673             :   }
     674           0 :   return IPC_OK();
     675             : }
     676             : 
     677             : void
     678           0 : CompositorBridgeParent::ActorDestroy(ActorDestroyReason why)
     679             : {
     680           0 :   mCanSend = false;
     681             : 
     682           0 :   StopAndClearResources();
     683             : 
     684           0 :   RemoveCompositor(mCompositorBridgeID);
     685             : 
     686           0 :   mCompositionManager = nullptr;
     687             : 
     688             :   { // scope lock
     689           0 :     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     690           0 :     sIndirectLayerTrees.erase(mRootLayerTreeID);
     691             :   }
     692             : 
     693             :   // There are chances that the ref count reaches zero on the main thread shortly
     694             :   // after this function returns while some ipdl code still needs to run on
     695             :   // this thread.
     696             :   // We must keep the compositor parent alive untill the code handling message
     697             :   // reception is finished on this thread.
     698           0 :   mSelfRef = this;
     699           0 :   MessageLoop::current()->PostTask(
     700           0 :     NewRunnableMethod("layers::CompositorBridgeParent::DeferredDestroy",
     701             :                       this,
     702           0 :                       &CompositorBridgeParent::DeferredDestroy));
     703           0 : }
     704             : 
     705             : void
     706           0 : CompositorBridgeParent::ScheduleRenderOnCompositorThread()
     707             : {
     708           0 :   MOZ_ASSERT(CompositorLoop());
     709           0 :   CompositorLoop()->PostTask(
     710           0 :     NewRunnableMethod("layers::CompositorBridgeParent::ScheduleComposition",
     711             :                       this,
     712           0 :                       &CompositorBridgeParent::ScheduleComposition));
     713           0 : }
     714             : 
     715             : void
     716           0 : CompositorBridgeParent::InvalidateOnCompositorThread()
     717             : {
     718           0 :   MOZ_ASSERT(CompositorLoop());
     719           0 :   CompositorLoop()->PostTask(
     720           0 :     NewRunnableMethod("layers::CompositorBridgeParent::Invalidate",
     721             :                       this,
     722           0 :                       &CompositorBridgeParent::Invalidate));
     723           0 : }
     724             : 
     725             : void
     726           0 : CompositorBridgeParent::PauseComposition()
     727             : {
     728           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
     729             :              "PauseComposition() can only be called on the compositor thread");
     730             : 
     731           0 :   MonitorAutoLock lock(mPauseCompositionMonitor);
     732             : 
     733           0 :   if (!mPaused) {
     734           0 :     mPaused = true;
     735             : 
     736           0 :     if (mCompositor) {
     737           0 :       mCompositor->Pause();
     738           0 :     } else if (mWrBridge) {
     739           0 :       mWrBridge->Pause();
     740             :     }
     741           0 :     TimeStamp now = TimeStamp::Now();
     742           0 :     DidComposite(now, now);
     743             :   }
     744             : 
     745             :   // if anyone's waiting to make sure that composition really got paused, tell them
     746           0 :   lock.NotifyAll();
     747           0 : }
     748             : 
     749             : void
     750           0 : CompositorBridgeParent::ResumeComposition()
     751             : {
     752           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
     753             :              "ResumeComposition() can only be called on the compositor thread");
     754             : 
     755           0 :   MonitorAutoLock lock(mResumeCompositionMonitor);
     756             : 
     757           0 :   bool resumed = mOptions.UseWebRender() ? mWrBridge->Resume() : mCompositor->Resume();
     758           0 :   if (!resumed) {
     759             : #ifdef MOZ_WIDGET_ANDROID
     760             :     // We can't get a surface. This could be because the activity changed between
     761             :     // the time resume was scheduled and now.
     762             :     __android_log_print(ANDROID_LOG_INFO, "CompositorBridgeParent", "Unable to renew compositor surface; remaining in paused state");
     763             : #endif
     764           0 :     lock.NotifyAll();
     765           0 :     return;
     766             :   }
     767             : 
     768           0 :   mPaused = false;
     769             : 
     770           0 :   Invalidate();
     771           0 :   mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr);
     772             : 
     773             :   // if anyone's waiting to make sure that composition really got resumed, tell them
     774           0 :   lock.NotifyAll();
     775             : }
     776             : 
     777             : void
     778           0 : CompositorBridgeParent::ForceComposition()
     779             : {
     780             :   // Cancel the orientation changed state to force composition
     781           0 :   mForceCompositionTask = nullptr;
     782           0 :   ScheduleRenderOnCompositorThread();
     783           0 : }
     784             : 
     785             : void
     786           0 : CompositorBridgeParent::CancelCurrentCompositeTask()
     787             : {
     788           0 :   mCompositorScheduler->CancelCurrentCompositeTask();
     789           0 : }
     790             : 
     791             : void
     792           0 : CompositorBridgeParent::SetEGLSurfaceSize(int width, int height)
     793             : {
     794           0 :   NS_ASSERTION(mUseExternalSurfaceSize, "Compositor created without UseExternalSurfaceSize provided");
     795           0 :   mEGLSurfaceSize.SizeTo(width, height);
     796           0 :   if (mCompositor) {
     797           0 :     mCompositor->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height));
     798             :   }
     799           0 : }
     800             : 
     801             : void
     802           0 : CompositorBridgeParent::ResumeCompositionAndResize(int width, int height)
     803             : {
     804           0 :   SetEGLSurfaceSize(width, height);
     805           0 :   ResumeComposition();
     806           0 : }
     807             : 
     808             : /*
     809             :  * This will execute a pause synchronously, waiting to make sure that the compositor
     810             :  * really is paused.
     811             :  */
     812             : void
     813           0 : CompositorBridgeParent::SchedulePauseOnCompositorThread()
     814             : {
     815           0 :   MonitorAutoLock lock(mPauseCompositionMonitor);
     816             : 
     817           0 :   MOZ_ASSERT(CompositorLoop());
     818           0 :   CompositorLoop()->PostTask(
     819           0 :     NewRunnableMethod("layers::CompositorBridgeParent::PauseComposition",
     820             :                       this,
     821           0 :                       &CompositorBridgeParent::PauseComposition));
     822             : 
     823             :   // Wait until the pause has actually been processed by the compositor thread
     824           0 :   lock.Wait();
     825           0 : }
     826             : 
     827             : bool
     828           0 : CompositorBridgeParent::ScheduleResumeOnCompositorThread()
     829             : {
     830           0 :   MonitorAutoLock lock(mResumeCompositionMonitor);
     831             : 
     832           0 :   MOZ_ASSERT(CompositorLoop());
     833           0 :   CompositorLoop()->PostTask(
     834           0 :     NewRunnableMethod("layers::CompositorBridgeParent::ResumeComposition",
     835             :                       this,
     836           0 :                       &CompositorBridgeParent::ResumeComposition));
     837             : 
     838             :   // Wait until the resume has actually been processed by the compositor thread
     839           0 :   lock.Wait();
     840             : 
     841           0 :   return !mPaused;
     842             : }
     843             : 
     844             : bool
     845           0 : CompositorBridgeParent::ScheduleResumeOnCompositorThread(int width, int height)
     846             : {
     847           0 :   MonitorAutoLock lock(mResumeCompositionMonitor);
     848             : 
     849           0 :   MOZ_ASSERT(CompositorLoop());
     850           0 :   CompositorLoop()->PostTask(NewRunnableMethod<int, int>(
     851             :     "layers::CompositorBridgeParent::ResumeCompositionAndResize",
     852             :     this,
     853             :     &CompositorBridgeParent::ResumeCompositionAndResize,
     854             :     width,
     855           0 :     height));
     856             : 
     857             :   // Wait until the resume has actually been processed by the compositor thread
     858           0 :   lock.Wait();
     859             : 
     860           0 :   return !mPaused;
     861             : }
     862             : 
     863             : void
     864           0 : CompositorBridgeParent::ScheduleTask(already_AddRefed<CancelableRunnable> task, int time)
     865             : {
     866           0 :   if (time == 0) {
     867           0 :     MessageLoop::current()->PostTask(std::move(task));
     868             :   } else {
     869           0 :     MessageLoop::current()->PostDelayedTask(std::move(task), time);
     870             :   }
     871           0 : }
     872             : 
     873             : void
     874           0 : CompositorBridgeParent::UpdatePaintTime(LayerTransactionParent* aLayerTree,
     875             :                                         const TimeDuration& aPaintTime)
     876             : {
     877             :   // We get a lot of paint timings for things with empty transactions.
     878           0 :   if (!mLayerManager || aPaintTime.ToMilliseconds() < 1.0) {
     879             :     return;
     880             :   }
     881             : 
     882           0 :   mLayerManager->SetPaintTime(aPaintTime);
     883             : }
     884             : 
     885             : void
     886           0 : CompositorBridgeParent::NotifyShadowTreeTransaction(LayersId aId, bool aIsFirstPaint,
     887             :     const FocusTarget& aFocusTarget,
     888             :     bool aScheduleComposite, uint32_t aPaintSequenceNumber,
     889             :     bool aIsRepeatTransaction, bool aHitTestUpdate)
     890             : {
     891           4 :   if (!aIsRepeatTransaction &&
     892           0 :       mLayerManager &&
     893           4 :       mLayerManager->GetRoot()) {
     894             :     // Process plugin data here to give time for them to update before the next
     895             :     // composition.
     896           0 :     bool pluginsUpdatedFlag = true;
     897             :     AutoResolveRefLayers resolve(mCompositionManager, this, nullptr,
     898           0 :                                  &pluginsUpdatedFlag);
     899             : 
     900             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
     901             :     // If plugins haven't been updated, stop waiting.
     902           0 :     if (!pluginsUpdatedFlag) {
     903           0 :       mWaitForPluginsUntil = TimeStamp();
     904           0 :       mHaveBlockedForPlugins = false;
     905             :     }
     906             : #endif
     907             : 
     908           0 :     if (mApzUpdater) {
     909           0 :       mApzUpdater->UpdateFocusState(mRootLayerTreeID, aId, aFocusTarget);
     910           0 :       if (aHitTestUpdate) {
     911           0 :         mApzUpdater->UpdateHitTestingTree(mRootLayerTreeID,
     912           0 :             mLayerManager->GetRoot(), aIsFirstPaint, aId, aPaintSequenceNumber);
     913             :       }
     914             :     }
     915             : 
     916           0 :     mLayerManager->NotifyShadowTreeTransaction();
     917             :   }
     918           0 :   if (aScheduleComposite) {
     919           2 :     ScheduleComposition();
     920             :   }
     921           0 : }
     922             : 
     923             : void
     924          10 : CompositorBridgeParent::ScheduleComposition()
     925             : {
     926           1 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     927          10 :   if (mPaused) {
     928             :     return;
     929             :   }
     930             : 
     931          20 :   if (mWrBridge) {
     932           0 :     mWrBridge->ScheduleGenerateFrame();
     933             :   } else {
     934          10 :     mCompositorScheduler->ScheduleComposition();
     935             :   }
     936             : }
     937             : 
     938             : // Go down the composite layer tree, setting properties to match their
     939             : // content-side counterparts.
     940             : /* static */ void
     941           0 : CompositorBridgeParent::SetShadowProperties(Layer* aLayer)
     942             : {
     943          17 :   ForEachNode<ForwardIterator>(
     944             :       aLayer,
     945           0 :       [] (Layer *layer)
     946             :       {
     947          40 :         if (Layer* maskLayer = layer->GetMaskLayer()) {
     948           0 :           SetShadowProperties(maskLayer);
     949             :         }
     950          40 :         for (size_t i = 0; i < layer->GetAncestorMaskLayerCount(); i++) {
     951           0 :           SetShadowProperties(layer->GetAncestorMaskLayerAt(i));
     952             :         }
     953             : 
     954             :         // FIXME: Bug 717688 -- Do these updates in LayerTransactionParent::RecvUpdate.
     955           0 :         HostLayer* layerCompositor = layer->AsHostLayer();
     956             :         // Set the layerComposite's base transform to the layer's base transform.
     957           0 :         AnimationArray& animations = layer->GetAnimations();
     958             :         // If there is any animation, the animation value will override
     959             :         // non-animated value later, so we don't need to set the non-animated
     960             :         // value here.
     961           0 :         if (animations.IsEmpty()) {
     962           0 :           layerCompositor->SetShadowBaseTransform(layer->GetBaseTransform());
     963           0 :           layerCompositor->SetShadowTransformSetByAnimation(false);
     964           0 :           layerCompositor->SetShadowOpacity(layer->GetOpacity());
     965             :           layerCompositor->SetShadowOpacitySetByAnimation(false);
     966             :         }
     967          80 :         layerCompositor->SetShadowVisibleRegion(layer->GetVisibleRegion());
     968           0 :         layerCompositor->SetShadowClipRect(layer->GetClipRect());
     969          40 :       }
     970           0 :     );
     971           0 : }
     972             : 
     973             : void
     974           9 : CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
     975             : {
     976          16 :   AUTO_PROFILER_TRACING("Paint", "Composite");
     977           0 :   AUTO_PROFILER_LABEL("CompositorBridgeParent::CompositeToTarget", GRAPHICS);
     978             : 
     979           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
     980             :              "Composite can only be called on the compositor thread");
     981           9 :   TimeStamp start = TimeStamp::Now();
     982             : 
     983           9 :   if (!CanComposite()) {
     984           0 :     TimeStamp end = TimeStamp::Now();
     985           1 :     DidComposite(start, end);
     986             :     return;
     987             :   }
     988             : 
     989             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
     990          14 :   if (!mWaitForPluginsUntil.IsNull() &&
     991           0 :       mWaitForPluginsUntil > start) {
     992           0 :     mHaveBlockedForPlugins = true;
     993           0 :     ScheduleComposition();
     994           0 :     return;
     995             :   }
     996             : #endif
     997             : 
     998             :   /*
     999             :    * AutoResolveRefLayers handles two tasks related to Windows and Linux
    1000             :    * plugin window management:
    1001             :    * 1) calculating if we have remote content in the view. If we do not have
    1002             :    * remote content, all plugin windows for this CompositorBridgeParent (window)
    1003             :    * can be hidden since we do not support plugins in chrome when running
    1004             :    * under e10s.
    1005             :    * 2) Updating plugin position, size, and clip. We do this here while the
    1006             :    * remote layer tree is hooked up to to chrome layer tree. This is needed
    1007             :    * since plugin clipping can depend on chrome (for example, due to tab modal
    1008             :    * prompts). Updates in step 2 are applied via an async ipc message sent
    1009             :    * to the main thread.
    1010             :    */
    1011           7 :   bool hasRemoteContent = false;
    1012           7 :   bool updatePluginsFlag = true;
    1013             :   AutoResolveRefLayers resolve(mCompositionManager, this,
    1014             :                                &hasRemoteContent,
    1015           0 :                                &updatePluginsFlag);
    1016             : 
    1017             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
    1018             :   // We do not support plugins in local content. When switching tabs
    1019             :   // to local pages, hide every plugin associated with the window.
    1020          14 :   if (!hasRemoteContent && gfxVars::BrowserTabsRemoteAutostart() &&
    1021           0 :       mCachedPluginData.Length()) {
    1022           0 :     Unused << SendHideAllPlugins(GetWidget()->GetWidgetKey());
    1023           0 :     mCachedPluginData.Clear();
    1024             :   }
    1025             : #endif
    1026             : 
    1027           0 :   if (aTarget) {
    1028           0 :     mLayerManager->BeginTransactionWithDrawTarget(aTarget, *aRect);
    1029             :   } else {
    1030           1 :     mLayerManager->BeginTransaction();
    1031             :   }
    1032             : 
    1033          14 :   SetShadowProperties(mLayerManager->GetRoot());
    1034             : 
    1035          14 :   if (mForceCompositionTask && !mOverrideComposeReadiness) {
    1036           0 :     if (mCompositionManager->ReadyForCompose()) {
    1037           0 :       mForceCompositionTask->Cancel();
    1038           0 :       mForceCompositionTask = nullptr;
    1039             :     } else {
    1040           0 :       return;
    1041             :     }
    1042             :   }
    1043             : 
    1044           7 :   mCompositionManager->ComputeRotation();
    1045             : 
    1046           7 :   TimeStamp time = mTestTime.valueOr(mCompositorScheduler->GetLastComposeTime());
    1047           0 :   bool requestNextFrame = mCompositionManager->TransformShadowTree(time, mVsyncRate);
    1048           1 :   if (requestNextFrame) {
    1049           0 :     ScheduleComposition();
    1050             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
    1051             :     // If we have visible windowed plugins then we need to wait for content (and
    1052             :     // then the plugins) to have been updated by the active animation.
    1053           0 :     if (!mPluginWindowsHidden && mCachedPluginData.Length()) {
    1054           0 :       mWaitForPluginsUntil = mCompositorScheduler->GetLastComposeTime() + (mVsyncRate * 2);
    1055             :     }
    1056             : #endif
    1057             :   }
    1058             : 
    1059          14 :   RenderTraceLayers(mLayerManager->GetRoot(), "0000");
    1060             : 
    1061             : #ifdef MOZ_DUMP_PAINTING
    1062           0 :   if (gfxPrefs::DumpHostLayers()) {
    1063           0 :     printf_stderr("Painting --- compositing layer tree:\n");
    1064           0 :     mLayerManager->Dump(/* aSorted = */ true);
    1065             :   }
    1066             : #endif
    1067          14 :   mLayerManager->SetDebugOverlayWantsNextFrame(false);
    1068           7 :   mLayerManager->EndTransaction(time);
    1069             : 
    1070           7 :   if (!aTarget) {
    1071           7 :     TimeStamp end = TimeStamp::Now();
    1072           7 :     DidComposite(start, end);
    1073             :   }
    1074             : 
    1075             :   // We're not really taking advantage of the stored composite-again-time here.
    1076             :   // We might be able to skip the next few composites altogether. However,
    1077             :   // that's a bit complex to implement and we'll get most of the advantage
    1078             :   // by skipping compositing when we detect there's nothing invalid. This is why
    1079             :   // we do "composite until" rather than "composite again at".
    1080             :   //
    1081             :   // TODO(bug 1328602) Figure out what we should do here with the render thread.
    1082          14 :   if (!mLayerManager->GetCompositeUntilTime().IsNull() ||
    1083           7 :       mLayerManager->DebugOverlayWantsNextFrame())
    1084             :   {
    1085           0 :       ScheduleComposition();
    1086             :   }
    1087             : 
    1088             : #ifdef COMPOSITOR_PERFORMANCE_WARNING
    1089             :   TimeDuration executionTime = TimeStamp::Now() - mCompositorScheduler->GetLastComposeTime();
    1090             :   TimeDuration frameBudget = TimeDuration::FromMilliseconds(15);
    1091             :   int32_t frameRate = CalculateCompositionFrameRate();
    1092             :   if (frameRate > 0) {
    1093             :     frameBudget = TimeDuration::FromSeconds(1.0 / frameRate);
    1094             :   }
    1095             :   if (executionTime > frameBudget) {
    1096             :     printf_stderr("Compositor: Composite execution took %4.1f ms\n",
    1097             :                   executionTime.ToMilliseconds());
    1098             :   }
    1099             : #endif
    1100             : 
    1101             :   // 0 -> Full-tilt composite
    1102          14 :   if (gfxPrefs::LayersCompositionFrameRate() == 0 ||
    1103           7 :       mLayerManager->AlwaysScheduleComposite())
    1104             :   {
    1105             :     // Special full-tilt composite mode for performance testing
    1106           0 :     ScheduleComposition();
    1107             :   }
    1108             : 
    1109             :   // TODO(bug 1328602) Need an equivalent that works with the rende thread.
    1110           1 :   mLayerManager->SetCompositionTime(TimeStamp());
    1111             : 
    1112           7 :   mozilla::Telemetry::AccumulateTimeDelta(mozilla::Telemetry::COMPOSITE_TIME, start);
    1113             : }
    1114             : 
    1115             : mozilla::ipc::IPCResult
    1116           0 : CompositorBridgeParent::RecvRemotePluginsReady()
    1117             : {
    1118             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
    1119           0 :   mWaitForPluginsUntil = TimeStamp();
    1120           0 :   if (mHaveBlockedForPlugins) {
    1121           0 :     mHaveBlockedForPlugins = false;
    1122           0 :     ForceComposeToTarget(nullptr);
    1123             :   } else {
    1124           0 :     ScheduleComposition();
    1125             :   }
    1126           0 :   return IPC_OK();
    1127             : #else
    1128             :   NS_NOTREACHED("CompositorBridgeParent::RecvRemotePluginsReady calls "
    1129             :                 "unexpected on this platform.");
    1130             :   return IPC_FAIL_NO_REASON(this);
    1131             : #endif
    1132             : }
    1133             : 
    1134             : void
    1135           0 : CompositorBridgeParent::ForceComposeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
    1136             : {
    1137           0 :   AUTO_PROFILER_LABEL("CompositorBridgeParent::ForceComposeToTarget", GRAPHICS);
    1138             : 
    1139           0 :   AutoRestore<bool> override(mOverrideComposeReadiness);
    1140           0 :   mOverrideComposeReadiness = true;
    1141           0 :   mCompositorScheduler->ForceComposeToTarget(aTarget, aRect);
    1142           0 : }
    1143             : 
    1144             : PAPZCTreeManagerParent*
    1145           0 : CompositorBridgeParent::AllocPAPZCTreeManagerParent(const LayersId& aLayersId)
    1146             : {
    1147             :   // This should only ever get called in the GPU process.
    1148           0 :   MOZ_ASSERT(XRE_IsGPUProcess());
    1149             :   // We should only ever get this if APZ is enabled in this compositor.
    1150           0 :   MOZ_ASSERT(mOptions.UseAPZ());
    1151             :   // The mApzcTreeManager and mApzUpdater should have been created via RecvInitialize()
    1152           0 :   MOZ_ASSERT(mApzcTreeManager);
    1153           0 :   MOZ_ASSERT(mApzUpdater);
    1154             :   // The main process should pass in 0 because we assume mRootLayerTreeID
    1155           0 :   MOZ_ASSERT(!aLayersId.IsValid());
    1156             : 
    1157           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1158           0 :   CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[mRootLayerTreeID];
    1159           0 :   MOZ_ASSERT(state.mParent.get() == this);
    1160           0 :   MOZ_ASSERT(!state.mApzcTreeManagerParent);
    1161           0 :   state.mApzcTreeManagerParent = new APZCTreeManagerParent(mRootLayerTreeID, mApzcTreeManager, mApzUpdater);
    1162             : 
    1163           0 :   return state.mApzcTreeManagerParent;
    1164             : }
    1165             : 
    1166             : bool
    1167           0 : CompositorBridgeParent::DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor)
    1168             : {
    1169           0 :   delete aActor;
    1170           0 :   return true;
    1171             : }
    1172             : 
    1173             : void
    1174           0 : CompositorBridgeParent::AllocateAPZCTreeManagerParent(const MonitorAutoLock& aProofOfLayerTreeStateLock,
    1175             :                                                       const LayersId& aLayersId,
    1176             :                                                       LayerTreeState& aState)
    1177             : {
    1178           2 :   MOZ_ASSERT(aState.mParent == this);
    1179           2 :   MOZ_ASSERT(mApzcTreeManager);
    1180           1 :   MOZ_ASSERT(mApzUpdater);
    1181           1 :   MOZ_ASSERT(!aState.mApzcTreeManagerParent);
    1182           2 :   aState.mApzcTreeManagerParent = new APZCTreeManagerParent(aLayersId, mApzcTreeManager, mApzUpdater);
    1183           1 : }
    1184             : 
    1185             : PAPZParent*
    1186           0 : CompositorBridgeParent::AllocPAPZParent(const LayersId& aLayersId)
    1187             : {
    1188             :   // The main process should pass in 0 because we assume mRootLayerTreeID
    1189           0 :   MOZ_ASSERT(!aLayersId.IsValid());
    1190             : 
    1191           0 :   RemoteContentController* controller = new RemoteContentController();
    1192             : 
    1193             :   // Increment the controller's refcount before we return it. This will keep the
    1194             :   // controller alive until it is released by IPDL in DeallocPAPZParent.
    1195           0 :   controller->AddRef();
    1196             : 
    1197           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1198           0 :   CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[mRootLayerTreeID];
    1199           0 :   MOZ_ASSERT(!state.mController);
    1200           0 :   state.mController = controller;
    1201             : 
    1202           0 :   return controller;
    1203             : }
    1204             : 
    1205             : bool
    1206           0 : CompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
    1207             : {
    1208           0 :   RemoteContentController* controller = static_cast<RemoteContentController*>(aActor);
    1209           0 :   controller->Release();
    1210           0 :   return true;
    1211             : }
    1212             : 
    1213             : #if defined(MOZ_WIDGET_ANDROID)
    1214             : AndroidDynamicToolbarAnimator*
    1215             : CompositorBridgeParent::GetAndroidDynamicToolbarAnimator()
    1216             : {
    1217             :   return mApzcTreeManager ? mApzcTreeManager->GetAndroidDynamicToolbarAnimator() : nullptr;
    1218             : }
    1219             : #endif
    1220             : 
    1221             : RefPtr<APZSampler>
    1222           1 : CompositorBridgeParent::GetAPZSampler()
    1223             : {
    1224           0 :   return mApzSampler;
    1225             : }
    1226             : 
    1227             : RefPtr<APZUpdater>
    1228           0 : CompositorBridgeParent::GetAPZUpdater()
    1229             : {
    1230           0 :   return mApzUpdater;
    1231             : }
    1232             : 
    1233             : CompositorBridgeParent*
    1234           0 : CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(const LayersId& aLayersId)
    1235             : {
    1236           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1237           0 :   return sIndirectLayerTrees[aLayersId].mParent;
    1238             : }
    1239             : 
    1240             : /*static*/ RefPtr<CompositorBridgeParent>
    1241           0 : CompositorBridgeParent::GetCompositorBridgeParentFromWindowId(const wr::WindowId& aWindowId)
    1242             : {
    1243           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1244           0 :   for (auto it = sIndirectLayerTrees.begin(); it != sIndirectLayerTrees.end(); it++) {
    1245           0 :     LayerTreeState* state = &it->second;
    1246           0 :     if (!state->mWrBridge) {
    1247             :       continue;
    1248             :     }
    1249             :     // state->mWrBridge might be a root WebRenderBridgeParent or one of a content
    1250             :     // process, but in either case the state->mParent will be the same. So we
    1251             :     // don't need to distinguish between the two.
    1252           0 :     if (RefPtr<wr::WebRenderAPI> api = state->mWrBridge->GetWebRenderAPI()) {
    1253           0 :       if (api->GetId() == aWindowId) {
    1254           0 :         return state->mParent;
    1255             :       }
    1256             :     }
    1257             :   }
    1258             :   return nullptr;
    1259             : }
    1260             : 
    1261             : bool
    1262           9 : CompositorBridgeParent::CanComposite()
    1263             : {
    1264           0 :   return mLayerManager &&
    1265          34 :          mLayerManager->GetRoot() &&
    1266          16 :          !mPaused;
    1267             : }
    1268             : 
    1269             : void
    1270           0 : CompositorBridgeParent::ScheduleRotationOnCompositorThread(const TargetConfig& aTargetConfig,
    1271             :                                                      bool aIsFirstPaint)
    1272             : {
    1273           1 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    1274             : 
    1275           0 :   if (!aIsFirstPaint &&
    1276          16 :       !mCompositionManager->IsFirstPaint() &&
    1277          12 :       mCompositionManager->RequiresReorientation(aTargetConfig.orientation())) {
    1278           0 :     if (mForceCompositionTask != nullptr) {
    1279           0 :       mForceCompositionTask->Cancel();
    1280             :     }
    1281           0 :     RefPtr<CancelableRunnable> task = NewCancelableRunnableMethod(
    1282             :       "layers::CompositorBridgeParent::ForceComposition",
    1283             :       this,
    1284           0 :       &CompositorBridgeParent::ForceComposition);
    1285           0 :     mForceCompositionTask = task;
    1286           0 :     ScheduleTask(task.forget(), gfxPrefs::OrientationSyncMillis());
    1287             :   }
    1288          10 : }
    1289             : 
    1290             : void
    1291           0 : CompositorBridgeParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
    1292             :                                             const TransactionInfo& aInfo,
    1293             :                                             bool aHitTestUpdate)
    1294             : {
    1295           8 :   const TargetConfig& targetConfig = aInfo.targetConfig();
    1296             : 
    1297           0 :   ScheduleRotationOnCompositorThread(targetConfig, aInfo.isFirstPaint());
    1298             : 
    1299             :   // Instruct the LayerManager to update its render bounds now. Since all the orientation
    1300             :   // change, dimension change would be done at the stage, update the size here is free of
    1301             :   // race condition.
    1302           0 :   mLayerManager->UpdateRenderBounds(targetConfig.naturalBounds());
    1303           0 :   mLayerManager->SetRegionToClear(targetConfig.clearRegion());
    1304           0 :   if (mLayerManager->GetCompositor()) {
    1305           8 :     mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation());
    1306             :   }
    1307             : 
    1308           8 :   mCompositionManager->Updated(aInfo.isFirstPaint(), targetConfig);
    1309           0 :   Layer* root = aLayerTree->GetRoot();
    1310           8 :   mLayerManager->SetRoot(root);
    1311             : 
    1312           0 :   if (mApzUpdater && !aInfo.isRepeatTransaction()) {
    1313           8 :     mApzUpdater->UpdateFocusState(mRootLayerTreeID,
    1314             :                                   mRootLayerTreeID,
    1315           0 :                                   aInfo.focusTarget());
    1316             : 
    1317           8 :     if (aHitTestUpdate) {
    1318           3 :       AutoResolveRefLayers resolve(mCompositionManager);
    1319             : 
    1320           2 :       mApzUpdater->UpdateHitTestingTree(
    1321           1 :         mRootLayerTreeID, root, aInfo.isFirstPaint(),
    1322           2 :         mRootLayerTreeID, aInfo.paintSequenceNumber());
    1323             :     }
    1324             :   }
    1325             : 
    1326             :   // The transaction ID might get reset to 1 if the page gets reloaded, see
    1327             :   // https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
    1328             :   // Otherwise, it should be continually increasing.
    1329           0 :   MOZ_ASSERT(aInfo.id() == TransactionId{1} || aInfo.id() > mPendingTransaction);
    1330           8 :   mPendingTransaction = aInfo.id();
    1331           0 :   mTxnStartTime = aInfo.transactionStart();
    1332           0 :   mFwdTime = aInfo.fwdTime();
    1333             : 
    1334           1 :   if (root) {
    1335           1 :     SetShadowProperties(root);
    1336             :   }
    1337           8 :   if (aInfo.scheduleComposite()) {
    1338           0 :     ScheduleComposition();
    1339           0 :     if (mPaused) {
    1340           0 :       TimeStamp now = TimeStamp::Now();
    1341           0 :       DidComposite(now, now);
    1342             :     }
    1343             :   }
    1344           0 :   mLayerManager->NotifyShadowTreeTransaction();
    1345           0 : }
    1346             : 
    1347             : void
    1348           0 : CompositorBridgeParent::ScheduleComposite(LayerTransactionParent* aLayerTree)
    1349             : {
    1350           0 :   ScheduleComposition();
    1351           0 : }
    1352             : 
    1353             : bool
    1354           0 : CompositorBridgeParent::SetTestSampleTime(const LayersId& aId,
    1355             :                                           const TimeStamp& aTime)
    1356             : {
    1357           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    1358             : 
    1359           0 :   if (aTime.IsNull()) {
    1360             :     return false;
    1361             :   }
    1362             : 
    1363           0 :   mTestTime = Some(aTime);
    1364             : 
    1365           0 :   if (mWrBridge) {
    1366           0 :     mWrBridge->FlushRendering();
    1367           0 :     return true;
    1368             :   }
    1369             : 
    1370           0 :   bool testComposite = mCompositionManager &&
    1371           0 :                        mCompositorScheduler->NeedsComposite();
    1372             : 
    1373             :   // Update but only if we were already scheduled to animate
    1374           0 :   if (testComposite) {
    1375           0 :     AutoResolveRefLayers resolve(mCompositionManager);
    1376           0 :     bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime, mVsyncRate);
    1377           0 :     if (!requestNextFrame) {
    1378           0 :       CancelCurrentCompositeTask();
    1379             :       // Pretend we composited in case someone is wating for this event.
    1380           0 :       TimeStamp now = TimeStamp::Now();
    1381           0 :       DidComposite(now, now);
    1382             :     }
    1383             :   }
    1384             : 
    1385             :   return true;
    1386             : }
    1387             : 
    1388             : void
    1389           0 : CompositorBridgeParent::LeaveTestMode(const LayersId& aId)
    1390             : {
    1391           0 :   mTestTime = Nothing();
    1392           0 : }
    1393             : 
    1394             : void
    1395           0 : CompositorBridgeParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree,
    1396             :                                              TransformsToSkip aSkip)
    1397             : {
    1398             :   // NOTE: This should only be used for testing. For example, when mTestTime is
    1399             :   // non-empty, or when called from test-only methods like
    1400             :   // LayerTransactionParent::RecvGetAnimationTransform.
    1401             : 
    1402             :   // Synchronously update the layer tree
    1403           0 :   if (aLayerTree->GetRoot()) {
    1404           0 :     AutoResolveRefLayers resolve(mCompositionManager);
    1405           0 :     SetShadowProperties(mLayerManager->GetRoot());
    1406             : 
    1407           0 :     TimeStamp time = mTestTime.valueOr(mCompositorScheduler->GetLastComposeTime());
    1408             :     bool requestNextFrame =
    1409           0 :       mCompositionManager->TransformShadowTree(time, mVsyncRate, aSkip);
    1410           0 :     if (!requestNextFrame) {
    1411           0 :       CancelCurrentCompositeTask();
    1412             :       // Pretend we composited in case someone is waiting for this event.
    1413           0 :       TimeStamp now = TimeStamp::Now();
    1414           0 :       DidComposite(now, now);
    1415             :     }
    1416             :   }
    1417           0 : }
    1418             : 
    1419             : CompositorAnimationStorage*
    1420           9 : CompositorBridgeParent::GetAnimationStorage()
    1421             : {
    1422          18 :   if (!mAnimationStorage) {
    1423           1 :     mAnimationStorage = new CompositorAnimationStorage();
    1424             :   }
    1425           1 :   return mAnimationStorage;
    1426             : }
    1427             : 
    1428             : mozilla::ipc::IPCResult
    1429           0 : CompositorBridgeParent::RecvGetFrameUniformity(FrameUniformityData* aOutData)
    1430             : {
    1431           0 :   mCompositionManager->GetFrameUniformity(aOutData);
    1432           0 :   return IPC_OK();
    1433             : }
    1434             : 
    1435             : void
    1436           0 : CompositorBridgeParent::SetTestAsyncScrollOffset(
    1437             :     const LayersId& aLayersId,
    1438             :     const FrameMetrics::ViewID& aScrollId,
    1439             :     const CSSPoint& aPoint)
    1440             : {
    1441           0 :   if (mApzUpdater) {
    1442           0 :     MOZ_ASSERT(aLayersId.IsValid());
    1443           0 :     mApzUpdater->SetTestAsyncScrollOffset(aLayersId, aScrollId, aPoint);
    1444             :   }
    1445           0 : }
    1446             : 
    1447             : void
    1448           0 : CompositorBridgeParent::SetTestAsyncZoom(
    1449             :     const LayersId& aLayersId,
    1450             :     const FrameMetrics::ViewID& aScrollId,
    1451             :     const LayerToParentLayerScale& aZoom)
    1452             : {
    1453           0 :   if (mApzUpdater) {
    1454           0 :     MOZ_ASSERT(aLayersId.IsValid());
    1455           0 :     mApzUpdater->SetTestAsyncZoom(aLayersId, aScrollId, aZoom);
    1456             :   }
    1457           0 : }
    1458             : 
    1459             : void
    1460           0 : CompositorBridgeParent::FlushApzRepaints(const LayersId& aLayersId)
    1461             : {
    1462           0 :   MOZ_ASSERT(mApzcTreeManager);
    1463           0 :   MOZ_ASSERT(mApzUpdater);
    1464           0 :   MOZ_ASSERT(aLayersId.IsValid());
    1465           0 :   RefPtr<CompositorBridgeParent> self = this;
    1466           0 :   mApzUpdater->RunOnControllerThread(aLayersId, NS_NewRunnableFunction(
    1467             :     "layers::CompositorBridgeParent::FlushApzRepaints",
    1468           0 :     [=]() { self->mApzcTreeManager->FlushApzRepaints(aLayersId); }));
    1469           0 : }
    1470             : 
    1471             : void
    1472           0 : CompositorBridgeParent::GetAPZTestData(const LayersId& aLayersId,
    1473             :                                        APZTestData* aOutData)
    1474             : {
    1475           0 :   if (mApzUpdater) {
    1476           0 :     MOZ_ASSERT(aLayersId.IsValid());
    1477           0 :     mApzUpdater->GetAPZTestData(aLayersId, aOutData);
    1478             :   }
    1479           0 : }
    1480             : 
    1481             : void
    1482           0 : CompositorBridgeParent::SetConfirmedTargetAPZC(const LayersId& aLayersId,
    1483             :                                                const uint64_t& aInputBlockId,
    1484             :                                                const nsTArray<ScrollableLayerGuid>& aTargets)
    1485             : {
    1486           0 :   if (!mApzcTreeManager || !mApzUpdater) {
    1487           0 :     return;
    1488             :   }
    1489             :   // Need to specifically bind this since it's overloaded.
    1490             :   void (APZCTreeManager::*setTargetApzcFunc)
    1491             :         (uint64_t, const nsTArray<ScrollableLayerGuid>&) =
    1492           0 :         &APZCTreeManager::SetTargetAPZC;
    1493             :   RefPtr<Runnable> task =
    1494             :     NewRunnableMethod<uint64_t,
    1495           0 :                       StoreCopyPassByConstLRef<nsTArray<ScrollableLayerGuid>>>(
    1496             :       "layers::CompositorBridgeParent::SetConfirmedTargetAPZC",
    1497           0 :       mApzcTreeManager.get(),
    1498             :       setTargetApzcFunc,
    1499             :       aInputBlockId,
    1500           0 :       aTargets);
    1501           0 :   mApzUpdater->RunOnControllerThread(aLayersId, task.forget());
    1502             : }
    1503             : 
    1504             : void
    1505           0 : CompositorBridgeParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints)
    1506             : {
    1507           1 :   NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager");
    1508           2 :   NS_ASSERTION(!mCompositor,   "Already initialised mCompositor");
    1509             : 
    1510           1 :   if (!InitializeAdvancedLayers(aBackendHints, nullptr)) {
    1511           0 :     mCompositor = NewCompositor(aBackendHints);
    1512           2 :     if (!mCompositor) {
    1513           0 :       return;
    1514             :     }
    1515           3 :     mLayerManager = new LayerManagerComposite(mCompositor);
    1516             :   }
    1517           1 :   mLayerManager->SetCompositorBridgeID(mCompositorBridgeID);
    1518             : 
    1519           3 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1520           2 :   sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = mLayerManager;
    1521             : }
    1522             : 
    1523             : bool
    1524           0 : CompositorBridgeParent::InitializeAdvancedLayers(const nsTArray<LayersBackend>& aBackendHints,
    1525             :                                                  TextureFactoryIdentifier* aOutIdentifier)
    1526             : {
    1527             : #ifdef XP_WIN
    1528             :   if (!mOptions.UseAdvancedLayers()) {
    1529             :     return false;
    1530             :   }
    1531             : 
    1532             :   // Currently LayerManagerMLGPU hardcodes a D3D11 device, so we reject using
    1533             :   // AL if LAYERS_D3D11 isn't in the backend hints.
    1534             :   if (!aBackendHints.Contains(LayersBackend::LAYERS_D3D11)) {
    1535             :     return false;
    1536             :   }
    1537             : 
    1538             :   RefPtr<LayerManagerMLGPU> manager = new LayerManagerMLGPU(mWidget);
    1539             :   if (!manager->Initialize()) {
    1540             :     return false;
    1541             :   }
    1542             : 
    1543             :   if (aOutIdentifier) {
    1544             :     *aOutIdentifier = manager->GetTextureFactoryIdentifier();
    1545             :   }
    1546             :   mLayerManager = manager;
    1547             :   return true;
    1548             : #else
    1549           0 :   return false;
    1550             : #endif
    1551             : }
    1552             : 
    1553             : RefPtr<Compositor>
    1554           1 : CompositorBridgeParent::NewCompositor(const nsTArray<LayersBackend>& aBackendHints)
    1555             : {
    1556           2 :   for (size_t i = 0; i < aBackendHints.Length(); ++i) {
    1557           0 :     RefPtr<Compositor> compositor;
    1558           0 :     if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL) {
    1559             :       compositor = new CompositorOGL(this,
    1560             :                                      mWidget,
    1561             :                                      mEGLSurfaceSize.width,
    1562             :                                      mEGLSurfaceSize.height,
    1563           0 :                                      mUseExternalSurfaceSize);
    1564           1 :     } else if (aBackendHints[i] == LayersBackend::LAYERS_BASIC) {
    1565             : #ifdef MOZ_WIDGET_GTK
    1566           1 :       if (gfxVars::UseXRender()) {
    1567           0 :         compositor = new X11BasicCompositor(this, mWidget);
    1568             :       } else
    1569             : #endif
    1570             :       {
    1571           1 :         compositor = new BasicCompositor(this, mWidget);
    1572             :       }
    1573             : #ifdef XP_WIN
    1574             :     } else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11) {
    1575             :       compositor = new CompositorD3D11(this, mWidget);
    1576             : #endif
    1577             :     }
    1578           1 :     nsCString failureReason;
    1579             : 
    1580             :     // Some software GPU emulation implementations will happily try to create
    1581             :     // unreasonably big surfaces and then fail in awful ways.
    1582             :     // Let's at least limit this to the default max texture size we use for content,
    1583             :     // anything larger than that will fail to render on the content side anyway.
    1584             :     // We can revisit this value and make it even tighter if need be.
    1585           1 :     const int max_fb_size = 32767;
    1586           0 :     const LayoutDeviceIntSize size = mWidget->GetClientSize();
    1587           0 :     if (size.width > max_fb_size || size.height > max_fb_size) {
    1588           0 :       failureReason = "FEATURE_FAILURE_MAX_FRAMEBUFFER_SIZE";
    1589           1 :       return nullptr;
    1590             :     }
    1591             : 
    1592           1 :     MOZ_ASSERT(!gfxVars::UseWebRender() || aBackendHints[i] == LayersBackend::LAYERS_BASIC);
    1593           0 :     if (compositor && compositor->Initialize(&failureReason)) {
    1594           0 :       if (failureReason.IsEmpty()){
    1595             :         failureReason = "SUCCESS";
    1596             :       }
    1597             : 
    1598             :       // should only report success here
    1599           2 :       if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL){
    1600           0 :         Telemetry::Accumulate(Telemetry::OPENGL_COMPOSITING_FAILURE_ID, failureReason);
    1601             :       }
    1602             : #ifdef XP_WIN
    1603             :       else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11){
    1604             :         Telemetry::Accumulate(Telemetry::D3D11_COMPOSITING_FAILURE_ID, failureReason);
    1605             :       }
    1606             : #endif
    1607             : 
    1608             :       return compositor;
    1609             :     }
    1610             : 
    1611             :     // report any failure reasons here
    1612           0 :     if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL){
    1613           0 :       gfxCriticalNote << "[OPENGL] Failed to init compositor with reason: "
    1614           0 :                       << failureReason.get();
    1615           0 :       Telemetry::Accumulate(Telemetry::OPENGL_COMPOSITING_FAILURE_ID, failureReason);
    1616             :     }
    1617             : #ifdef XP_WIN
    1618             :     else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11){
    1619             :       gfxCriticalNote << "[D3D11] Failed to init compositor with reason: "
    1620             :                       << failureReason.get();
    1621             :       Telemetry::Accumulate(Telemetry::D3D11_COMPOSITING_FAILURE_ID, failureReason);
    1622             :     }
    1623             : #endif
    1624             :   }
    1625             : 
    1626             :   return nullptr;
    1627             : }
    1628             : 
    1629             : PLayerTransactionParent*
    1630           1 : CompositorBridgeParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
    1631             :                                                      const LayersId& aId)
    1632             : {
    1633           1 :   MOZ_ASSERT(!aId.IsValid());
    1634             : 
    1635           1 :   InitializeLayerManager(aBackendHints);
    1636             : 
    1637           2 :   if (!mLayerManager) {
    1638           0 :     NS_WARNING("Failed to initialise Compositor");
    1639           0 :     LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, mRootLayerTreeID);
    1640           0 :     p->AddIPDLReference();
    1641           0 :     return p;
    1642             :   }
    1643             : 
    1644           4 :   mCompositionManager = new AsyncCompositionManager(this, mLayerManager);
    1645             : 
    1646           0 :   LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, GetAnimationStorage(), mRootLayerTreeID);
    1647           1 :   p->AddIPDLReference();
    1648           0 :   return p;
    1649             : }
    1650             : 
    1651             : bool
    1652           0 : CompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor)
    1653             : {
    1654           0 :   static_cast<LayerTransactionParent*>(actor)->ReleaseIPDLReference();
    1655           0 :   return true;
    1656             : }
    1657             : 
    1658           0 : CompositorBridgeParent* CompositorBridgeParent::GetCompositorBridgeParent(uint64_t id)
    1659             : {
    1660           0 :   MOZ_RELEASE_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    1661             : 
    1662           0 :   CompositorMap::iterator it = sCompositorMap->find(id);
    1663           0 :   return it != sCompositorMap->end() ? it->second : nullptr;
    1664             : }
    1665             : 
    1666           0 : void CompositorBridgeParent::AddCompositor(CompositorBridgeParent* compositor, uint64_t* outID)
    1667             : {
    1668           0 :   MOZ_RELEASE_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    1669             : 
    1670             :   static uint64_t sNextID = 1;
    1671             : 
    1672           1 :   ++sNextID;
    1673           0 :   (*sCompositorMap)[sNextID] = compositor;
    1674           1 :   *outID = sNextID;
    1675           0 : }
    1676             : 
    1677           0 : CompositorBridgeParent* CompositorBridgeParent::RemoveCompositor(uint64_t id)
    1678             : {
    1679           0 :   MOZ_RELEASE_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    1680             : 
    1681           0 :   CompositorMap::iterator it = sCompositorMap->find(id);
    1682           0 :   if (it == sCompositorMap->end()) {
    1683             :     return nullptr;
    1684             :   }
    1685           0 :   CompositorBridgeParent *retval = it->second;
    1686           0 :   sCompositorMap->erase(it);
    1687           0 :   return retval;
    1688             : }
    1689             : 
    1690             : void
    1691           0 : CompositorBridgeParent::NotifyVsync(const TimeStamp& aTimeStamp, const LayersId& aLayersId)
    1692             : {
    1693           0 :   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
    1694           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    1695             : 
    1696           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1697           0 :   auto it = sIndirectLayerTrees.find(aLayersId);
    1698           0 :   if (it == sIndirectLayerTrees.end())
    1699           0 :     return;
    1700             : 
    1701           0 :   CompositorBridgeParent* cbp = it->second.mParent;
    1702           0 :   if (!cbp || !cbp->mWidget)
    1703             :     return;
    1704             : 
    1705           0 :   RefPtr<VsyncObserver> obs = cbp->mWidget->GetVsyncObserver();
    1706           0 :   if (!obs)
    1707           0 :     return;
    1708             : 
    1709           0 :   obs->NotifyVsync(aTimeStamp);
    1710             : }
    1711             : 
    1712             : mozilla::ipc::IPCResult
    1713           0 : CompositorBridgeParent::RecvNotifyChildCreated(const LayersId& child,
    1714             :                                                CompositorOptions* aOptions)
    1715             : {
    1716           3 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1717           1 :   NotifyChildCreated(child);
    1718           1 :   *aOptions = mOptions;
    1719           1 :   return IPC_OK();
    1720             : }
    1721             : 
    1722             : mozilla::ipc::IPCResult
    1723           0 : CompositorBridgeParent::RecvNotifyChildRecreated(const LayersId& aChild,
    1724             :                                                  CompositorOptions* aOptions)
    1725             : {
    1726           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1727             : 
    1728           0 :   if (sIndirectLayerTrees.find(aChild) != sIndirectLayerTrees.end()) {
    1729           0 :     NS_WARNING("Invalid to register the same layer tree twice");
    1730           0 :     return IPC_FAIL_NO_REASON(this);
    1731             :   }
    1732             : 
    1733           0 :   NotifyChildCreated(aChild);
    1734           0 :   *aOptions = mOptions;
    1735             :   return IPC_OK();
    1736             : }
    1737             : 
    1738             : void
    1739           2 : CompositorBridgeParent::NotifyChildCreated(LayersId aChild)
    1740             : {
    1741           1 :   sIndirectLayerTreesLock->AssertCurrentThreadOwns();
    1742           4 :   sIndirectLayerTrees[aChild].mParent = this;
    1743           4 :   sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
    1744           2 : }
    1745             : 
    1746             : mozilla::ipc::IPCResult
    1747           0 : CompositorBridgeParent::RecvMapAndNotifyChildCreated(const LayersId& aChild,
    1748             :                                                      const base::ProcessId& aOwnerPid,
    1749             :                                                      CompositorOptions* aOptions)
    1750             : {
    1751             :   // We only use this message when the remote compositor is in the GPU process.
    1752             :   // It is harmless to call it, though.
    1753           0 :   MOZ_ASSERT(XRE_IsGPUProcess());
    1754             : 
    1755           0 :   LayerTreeOwnerTracker::Get()->Map(aChild, aOwnerPid);
    1756             : 
    1757           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1758           0 :   NotifyChildCreated(aChild);
    1759           0 :   *aOptions = mOptions;
    1760           0 :   return IPC_OK();
    1761             : }
    1762             : 
    1763             : mozilla::ipc::IPCResult
    1764           0 : CompositorBridgeParent::RecvAdoptChild(const LayersId& child)
    1765             : {
    1766           2 :   RefPtr<APZUpdater> oldApzUpdater;
    1767             :   APZCTreeManagerParent* parent;
    1768           0 :   bool scheduleComposition = false;
    1769           2 :   RefPtr<CrossProcessCompositorBridgeParent> cpcp;
    1770           2 :   RefPtr<WebRenderBridgeParent> childWrBridge;
    1771             : 
    1772             :   { // scope lock
    1773           3 :     MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1774           0 :     if (sIndirectLayerTrees[child].mParent) {
    1775             :       // We currently don't support adopting children from one compositor to
    1776             :       // another if the two compositors don't have the same options.
    1777           1 :       MOZ_ASSERT(sIndirectLayerTrees[child].mParent->mOptions == mOptions);
    1778           1 :       oldApzUpdater = sIndirectLayerTrees[child].mParent->mApzUpdater;
    1779             :     }
    1780           1 :     NotifyChildCreated(child);
    1781           0 :     if (sIndirectLayerTrees[child].mLayerTree) {
    1782           0 :       sIndirectLayerTrees[child].mLayerTree->SetLayerManager(mLayerManager, GetAnimationStorage());
    1783             :       // Trigger composition to handle a case that mLayerTree was not composited yet
    1784             :       // by previous CompositorBridgeParent, since nsRefreshDriver might wait composition complete.
    1785           0 :       scheduleComposition = true;
    1786             :     }
    1787           2 :     if (mWrBridge) {
    1788           0 :       childWrBridge = sIndirectLayerTrees[child].mWrBridge;
    1789           0 :       cpcp = sIndirectLayerTrees[child].mCrossProcessParent;
    1790             :     }
    1791           1 :     parent = sIndirectLayerTrees[child].mApzcTreeManagerParent;
    1792             :   }
    1793             : 
    1794           1 :   if (scheduleComposition) {
    1795           0 :     ScheduleComposition();
    1796             :   }
    1797             : 
    1798           1 :   if (childWrBridge) {
    1799           0 :     MOZ_ASSERT(mWrBridge);
    1800           0 :     RefPtr<wr::WebRenderAPI> api = mWrBridge->GetWebRenderAPI();
    1801           0 :     api = api->Clone();
    1802           0 :     childWrBridge->UpdateWebRender(mWrBridge->CompositorScheduler(),
    1803             :                                    api,
    1804             :                                    mWrBridge->AsyncImageManager(),
    1805           0 :                                    GetAnimationStorage());
    1806             :     // Pretend we composited, since parent CompositorBridgeParent was replaced.
    1807           0 :     if (cpcp) {
    1808           0 :       TimeStamp now = TimeStamp::Now();
    1809           0 :       cpcp->DidComposite(child, now, now);
    1810             :     }
    1811             :   }
    1812             : 
    1813           1 :   if (oldApzUpdater) {
    1814             :     // We don't support moving a child from an APZ-enabled compositor to a
    1815             :     // APZ-disabled compositor. The mOptions assertion above should already
    1816             :     // ensure this, since APZ-ness is one of the things in mOptions. Note
    1817             :     // however it is possible for mApzUpdater to be non-null here with
    1818             :     // oldApzUpdater null, because the child may not have been previously
    1819             :     // composited.
    1820           2 :     MOZ_ASSERT(mApzUpdater);
    1821             :   }
    1822           2 :   if (mApzUpdater) {
    1823           0 :     if (parent) {
    1824           0 :       MOZ_ASSERT(mApzcTreeManager);
    1825           0 :       parent->ChildAdopted(mApzcTreeManager, mApzUpdater);
    1826             :     }
    1827           1 :     mApzUpdater->NotifyLayerTreeAdopted(child, oldApzUpdater);
    1828             :   }
    1829           1 :   return IPC_OK();
    1830             : }
    1831             : 
    1832             : PWebRenderBridgeParent*
    1833           0 : CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
    1834             :                                                     const LayoutDeviceIntSize& aSize,
    1835             :                                                     TextureFactoryIdentifier* aTextureFactoryIdentifier,
    1836             :                                                     wr::IdNamespace* aIdNamespace)
    1837             : {
    1838             : #ifndef MOZ_BUILD_WEBRENDER
    1839             :   // Extra guard since this in the parent process and we don't want a malicious
    1840             :   // child process invoking this codepath before it's ready
    1841             :   MOZ_RELEASE_ASSERT(false);
    1842             : #endif
    1843           0 :   MOZ_ASSERT(wr::AsLayersId(aPipelineId) == mRootLayerTreeID);
    1844           0 :   MOZ_ASSERT(!mWrBridge);
    1845           0 :   MOZ_ASSERT(!mCompositor);
    1846           0 :   MOZ_ASSERT(!mCompositorScheduler);
    1847           0 :   MOZ_ASSERT(mWidget);
    1848             : 
    1849           0 :   RefPtr<widget::CompositorWidget> widget = mWidget;
    1850           0 :   wr::WrWindowId windowId = wr::NewWindowId();
    1851           0 :   if (mApzUpdater) {
    1852             :     // If APZ is enabled, we need to register the APZ updater with the window id
    1853             :     // before the updater thread is created in WebRenderAPI::Create, so
    1854             :     // that the callback from the updater thread can find the right APZUpdater.
    1855           0 :     mApzUpdater->SetWebRenderWindowId(windowId);
    1856             :   }
    1857           0 :   if (mApzSampler) {
    1858             :     // Same as for mApzUpdater, but for the sampler thread.
    1859           0 :     mApzSampler->SetWebRenderWindowId(windowId);
    1860             :   }
    1861           0 :   RefPtr<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(this, std::move(widget), windowId, aSize);
    1862           0 :   if (!api) {
    1863           0 :     mWrBridge = WebRenderBridgeParent::CreateDestroyed(aPipelineId);
    1864           0 :     mWrBridge.get()->AddRef(); // IPDL reference
    1865           0 :     *aIdNamespace = mWrBridge->GetIdNamespace();
    1866           0 :     *aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE);
    1867           0 :     return mWrBridge;
    1868             :   }
    1869           0 :   mAsyncImageManager = new AsyncImagePipelineManager(api->Clone());
    1870           0 :   RefPtr<AsyncImagePipelineManager> asyncMgr = mAsyncImageManager;
    1871           0 :   wr::TransactionBuilder txn;
    1872           0 :   txn.SetRootPipeline(aPipelineId);
    1873           0 :   api->SendTransaction(txn);
    1874           0 :   RefPtr<CompositorAnimationStorage> animStorage = GetAnimationStorage();
    1875           0 :   mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, std::move(api), std::move(asyncMgr), std::move(animStorage));
    1876           0 :   mWrBridge.get()->AddRef(); // IPDL reference
    1877             : 
    1878           0 :   *aIdNamespace = mWrBridge->GetIdNamespace();
    1879           0 :   mCompositorScheduler = mWrBridge->CompositorScheduler();
    1880           0 :   MOZ_ASSERT(mCompositorScheduler);
    1881             :   { // scope lock
    1882           0 :     MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1883           0 :     MOZ_ASSERT(sIndirectLayerTrees[mRootLayerTreeID].mWrBridge == nullptr);
    1884           0 :     sIndirectLayerTrees[mRootLayerTreeID].mWrBridge = mWrBridge;
    1885             :   }
    1886           0 :   *aTextureFactoryIdentifier = mWrBridge->GetTextureFactoryIdentifier();
    1887           0 :   return mWrBridge;
    1888             : }
    1889             : 
    1890             : bool
    1891           0 : CompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor)
    1892             : {
    1893             : #ifndef MOZ_BUILD_WEBRENDER
    1894             :   // Extra guard since this in the parent process and we don't want a malicious
    1895             :   // child process invoking this codepath before it's ready
    1896             :   MOZ_RELEASE_ASSERT(false);
    1897             : #endif
    1898           0 :   WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
    1899             :   {
    1900           0 :     MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1901           0 :     auto it = sIndirectLayerTrees.find(wr::AsLayersId(parent->PipelineId()));
    1902           0 :     if (it != sIndirectLayerTrees.end()) {
    1903           0 :       it->second.mWrBridge = nullptr;
    1904             :     }
    1905             :   }
    1906           0 :   parent->Release(); // IPDL reference
    1907           0 :   return true;
    1908             : }
    1909             : 
    1910             : RefPtr<WebRenderBridgeParent>
    1911           0 : CompositorBridgeParent::GetWebRenderBridgeParent() const
    1912             : {
    1913           0 :   return mWrBridge;
    1914             : }
    1915             : 
    1916             : Maybe<TimeStamp>
    1917           0 : CompositorBridgeParent::GetTestingTimeStamp() const
    1918             : {
    1919           0 :   return mTestTime;
    1920             : }
    1921             : 
    1922             : void
    1923           0 : EraseLayerState(LayersId aId)
    1924             : {
    1925           0 :   RefPtr<APZUpdater> apz;
    1926             : 
    1927             :   { // scope lock
    1928           0 :     MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1929           0 :     auto iter = sIndirectLayerTrees.find(aId);
    1930           0 :     if (iter != sIndirectLayerTrees.end()) {
    1931           0 :       CompositorBridgeParent* parent = iter->second.mParent;
    1932           0 :       if (parent) {
    1933           0 :         apz = parent->GetAPZUpdater();
    1934             :       }
    1935             :       sIndirectLayerTrees.erase(iter);
    1936             :     }
    1937             :   }
    1938             : 
    1939           0 :   if (apz) {
    1940           0 :     apz->NotifyLayerTreeRemoved(aId);
    1941             :   }
    1942           0 : }
    1943             : 
    1944             : /*static*/ void
    1945           0 : CompositorBridgeParent::DeallocateLayerTreeId(LayersId aId)
    1946             : {
    1947           0 :   MOZ_ASSERT(NS_IsMainThread());
    1948             :   // Here main thread notifies compositor to remove an element from
    1949             :   // sIndirectLayerTrees. This removed element might be queried soon.
    1950             :   // Checking the elements of sIndirectLayerTrees exist or not before using.
    1951           0 :   if (!CompositorLoop()) {
    1952           0 :     gfxCriticalError() << "Attempting to post to a invalid Compositor Loop";
    1953           0 :     return;
    1954             :   }
    1955           0 :   CompositorLoop()->PostTask(NewRunnableFunction("EraseLayerStateRunnable",
    1956           0 :                                                  &EraseLayerState, aId));
    1957             : }
    1958             : 
    1959             : static void
    1960           0 : UpdateControllerForLayersId(LayersId aLayersId,
    1961             :                             GeckoContentController* aController)
    1962             : {
    1963             :   // Adopt ref given to us by SetControllerForLayerTree()
    1964           3 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1965           1 :   sIndirectLayerTrees[aLayersId].mController =
    1966           0 :     already_AddRefed<GeckoContentController>(aController);
    1967           0 : }
    1968             : 
    1969           0 : ScopedLayerTreeRegistration::ScopedLayerTreeRegistration(APZCTreeManager* aApzctm,
    1970             :                                                          LayersId aLayersId,
    1971             :                                                          Layer* aRoot,
    1972           0 :                                                          GeckoContentController* aController)
    1973           0 :     : mLayersId(aLayersId)
    1974             : {
    1975           0 :   EnsureLayerTreeMapReady();
    1976           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1977           0 :   sIndirectLayerTrees[aLayersId].mRoot = aRoot;
    1978           0 :   sIndirectLayerTrees[aLayersId].mController = aController;
    1979           0 : }
    1980             : 
    1981           0 : ScopedLayerTreeRegistration::~ScopedLayerTreeRegistration()
    1982             : {
    1983           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    1984           0 :   sIndirectLayerTrees.erase(mLayersId);
    1985           0 : }
    1986             : 
    1987             : /*static*/ void
    1988           1 : CompositorBridgeParent::SetControllerForLayerTree(LayersId aLayersId,
    1989             :                                                   GeckoContentController* aController)
    1990             : {
    1991             :   // This ref is adopted by UpdateControllerForLayersId().
    1992           1 :   aController->AddRef();
    1993           3 :   CompositorLoop()->PostTask(NewRunnableFunction("UpdateControllerForLayersIdRunnable",
    1994             :                                                  &UpdateControllerForLayersId,
    1995             :                                                  aLayersId,
    1996           0 :                                                  aController));
    1997           0 : }
    1998             : 
    1999             : /*static*/ already_AddRefed<IAPZCTreeManager>
    2000           1 : CompositorBridgeParent::GetAPZCTreeManager(LayersId aLayersId)
    2001             : {
    2002           0 :   EnsureLayerTreeMapReady();
    2003           3 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2004           1 :   LayerTreeMap::iterator cit = sIndirectLayerTrees.find(aLayersId);
    2005           0 :   if (sIndirectLayerTrees.end() == cit) {
    2006             :     return nullptr;
    2007             :   }
    2008           1 :   LayerTreeState* lts = &cit->second;
    2009             : 
    2010             :   RefPtr<IAPZCTreeManager> apzctm = lts->mParent
    2011           1 :                                    ? lts->mParent->mApzcTreeManager.get()
    2012           0 :                                    : nullptr;
    2013           1 :   return apzctm.forget();
    2014             : }
    2015             : 
    2016             : #if defined(MOZ_GECKO_PROFILER)
    2017             : static void
    2018           0 : InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
    2019             : {
    2020           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    2021           0 :   profiler_add_marker(
    2022             :     "VsyncTimestamp",
    2023           0 :     MakeUnique<VsyncMarkerPayload>(aVsyncTimestamp));
    2024           0 : }
    2025             : #endif
    2026             : 
    2027             : /*static */ void
    2028           0 : CompositorBridgeParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
    2029             : {
    2030             : #if defined(MOZ_GECKO_PROFILER)
    2031             :   // Called in the vsync thread
    2032           0 :   if (profiler_is_active() && CompositorThreadHolder::IsActive()) {
    2033           0 :     CompositorLoop()->PostTask(
    2034           0 :       NewRunnableFunction("InsertVsyncProfilerMarkerRunnable", InsertVsyncProfilerMarker,
    2035           0 :                           aVsyncTimestamp));
    2036             :   }
    2037             : #endif
    2038           1 : }
    2039             : 
    2040             : widget::PCompositorWidgetParent*
    2041           0 : CompositorBridgeParent::AllocPCompositorWidgetParent(const CompositorWidgetInitData& aInitData)
    2042             : {
    2043             : #if defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
    2044           0 :   if (mWidget) {
    2045             :     // Should not create two widgets on the same compositor.
    2046             :     return nullptr;
    2047             :   }
    2048             : 
    2049             :   widget::CompositorWidgetParent* widget =
    2050           0 :     new widget::CompositorWidgetParent(aInitData, mOptions);
    2051           0 :   widget->AddRef();
    2052             : 
    2053             : #ifdef XP_WIN
    2054             :   if (mOptions.UseWebRender() && DeviceManagerDx::Get()->CanUseDComp()) {
    2055             :     widget->AsWindows()->EnsureCompositorWindow();
    2056             :   }
    2057             : #endif
    2058             : 
    2059             :   // Sending the constructor acts as initialization as well.
    2060           0 :   mWidget = widget;
    2061           0 :   return widget;
    2062             : #else
    2063             :   return nullptr;
    2064             : #endif
    2065             : }
    2066             : 
    2067             : bool
    2068           0 : CompositorBridgeParent::DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor)
    2069             : {
    2070             : #if defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
    2071           0 :   static_cast<widget::CompositorWidgetParent*>(aActor)->Release();
    2072           0 :   return true;
    2073             : #else
    2074             :   return false;
    2075             : #endif
    2076             : }
    2077             : 
    2078             : bool
    2079           0 : CompositorBridgeParent::IsPendingComposite()
    2080             : {
    2081          87 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    2082         174 :   if (!mCompositor) {
    2083             :     return false;
    2084             :   }
    2085           1 :   return mCompositor->IsPendingComposite();
    2086             : }
    2087             : 
    2088             : void
    2089           0 : CompositorBridgeParent::FinishPendingComposite()
    2090             : {
    2091           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    2092           0 :   if (!mCompositor) {
    2093             :     return;
    2094             :   }
    2095           0 :   return mCompositor->FinishPendingComposite();
    2096             : }
    2097             : 
    2098             : CompositorController*
    2099           0 : CompositorBridgeParent::LayerTreeState::GetCompositorController() const
    2100             : {
    2101           0 :   return mParent;
    2102             : }
    2103             : 
    2104             : MetricsSharingController*
    2105           0 : CompositorBridgeParent::LayerTreeState::CrossProcessSharingController() const
    2106             : {
    2107           0 :   return mCrossProcessParent;
    2108             : }
    2109             : 
    2110             : MetricsSharingController*
    2111           1 : CompositorBridgeParent::LayerTreeState::InProcessSharingController() const
    2112             : {
    2113           1 :   return mParent;
    2114             : }
    2115             : 
    2116             : void
    2117           0 : CompositorBridgeParent::DidComposite(LayersId aId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd)
    2118             : {
    2119           0 :   MOZ_ASSERT(aId == mRootLayerTreeID);
    2120           0 :   DidComposite(aCompositeStart, aCompositeEnd);
    2121           0 : }
    2122             : 
    2123             : void
    2124           0 : CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart,
    2125             :                                      TimeStamp& aCompositeEnd)
    2126             : {
    2127          18 :   if (mWrBridge) {
    2128           0 :     NotifyDidComposite(mWrBridge->FlushPendingTransactionIds(), aCompositeStart, aCompositeEnd);
    2129             :   } else {
    2130           9 :     NotifyDidComposite(mPendingTransaction, aCompositeStart, aCompositeEnd);
    2131             : #if defined(ENABLE_FRAME_LATENCY_LOG)
    2132             :     if (mPendingTransaction.IsValid()) {
    2133             :       if (mTxnStartTime) {
    2134             :         uint32_t latencyMs = round((aCompositeEnd - mTxnStartTime).ToMilliseconds());
    2135             :         printf_stderr("From transaction start to end of generate frame latencyMs %d this %p\n", latencyMs, this);
    2136             :       }
    2137             :       if (mFwdTime) {
    2138             :         uint32_t latencyMs = round((aCompositeEnd - mFwdTime).ToMilliseconds());
    2139             :         printf_stderr("From forwarding transaction to end of generate frame latencyMs %d this %p\n", latencyMs, this);
    2140             :       }
    2141             :     }
    2142             :     mTxnStartTime = TimeStamp();
    2143             :     mFwdTime = TimeStamp();
    2144             : #endif
    2145           9 :     mPendingTransaction = TransactionId{0};
    2146             :   }
    2147           9 : }
    2148             : 
    2149             : void
    2150           0 : CompositorBridgeParent::NotifyPipelineRendered(const wr::PipelineId& aPipelineId,
    2151             :                                                const wr::Epoch& aEpoch,
    2152             :                                                TimeStamp& aCompositeStart,
    2153             :                                                TimeStamp& aCompositeEnd)
    2154             : {
    2155           0 :   if (!mWrBridge) {
    2156           0 :     return;
    2157             :   }
    2158             : 
    2159           0 :   if (mWrBridge->PipelineId() == aPipelineId) {
    2160           0 :     mWrBridge->RemoveEpochDataPriorTo(aEpoch);
    2161             : 
    2162           0 :     if (!mPaused) {
    2163           0 :       TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch(aEpoch, aCompositeEnd);
    2164           0 :       Unused << SendDidComposite(LayersId{0}, transactionId, aCompositeStart, aCompositeEnd);
    2165             : 
    2166           0 :       nsTArray<ImageCompositeNotificationInfo> notifications;
    2167           0 :       mWrBridge->ExtractImageCompositeNotifications(&notifications);
    2168           0 :       if (!notifications.IsEmpty()) {
    2169           0 :         Unused << ImageBridgeParent::NotifyImageComposites(notifications);
    2170             :       }
    2171             :     }
    2172             :     return;
    2173             :   }
    2174             : 
    2175           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2176           0 :   ForEachIndirectLayerTree([&] (LayerTreeState* lts, const LayersId& aLayersId) -> void {
    2177           0 :     if (lts->mCrossProcessParent &&
    2178           0 :         lts->mWrBridge &&
    2179           0 :         lts->mWrBridge->PipelineId() == aPipelineId) {
    2180             : 
    2181           0 :       lts->mWrBridge->RemoveEpochDataPriorTo(aEpoch);
    2182             : 
    2183           0 :       if (!mPaused) {
    2184           0 :         CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
    2185           0 :         TransactionId transactionId = lts->mWrBridge->FlushTransactionIdsForEpoch(aEpoch, aCompositeEnd);
    2186           0 :         Unused << cpcp->SendDidComposite(aLayersId, transactionId, aCompositeStart, aCompositeEnd);
    2187             :       }
    2188             :     }
    2189           0 :   });
    2190             : }
    2191             : 
    2192             : RefPtr<AsyncImagePipelineManager>
    2193           0 : CompositorBridgeParent::GetAsyncImagePipelineManager() const
    2194             : {
    2195           0 :   return mAsyncImageManager;
    2196             : }
    2197             : 
    2198             : void
    2199           0 : CompositorBridgeParent::NotifyDidComposite(TransactionId aTransactionId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd)
    2200             : {
    2201           0 :   Unused << SendDidComposite(LayersId{0}, aTransactionId, aCompositeStart, aCompositeEnd);
    2202             : 
    2203          18 :   if (mLayerManager) {
    2204          18 :     nsTArray<ImageCompositeNotificationInfo> notifications;
    2205           0 :     mLayerManager->ExtractImageCompositeNotifications(&notifications);
    2206           1 :     if (!notifications.IsEmpty()) {
    2207           0 :       Unused << ImageBridgeParent::NotifyImageComposites(notifications);
    2208             :     }
    2209             :   }
    2210             : 
    2211          18 :   if (mWrBridge) {
    2212           0 :     nsTArray<ImageCompositeNotificationInfo> notifications;
    2213           0 :     mWrBridge->ExtractImageCompositeNotifications(&notifications);
    2214           0 :     if (!notifications.IsEmpty()) {
    2215           0 :       Unused << ImageBridgeParent::NotifyImageComposites(notifications);
    2216             :     }
    2217             :   }
    2218             : 
    2219           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2220           0 :   ForEachIndirectLayerTree([&] (LayerTreeState* lts, const LayersId& aLayersId) -> void {
    2221          27 :     if (lts->mCrossProcessParent && lts->mParent == this) {
    2222           9 :       CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
    2223           1 :       cpcp->DidCompositeLocked(aLayersId, aCompositeStart, aCompositeEnd);
    2224             :     }
    2225           1 :   });
    2226           9 : }
    2227             : 
    2228             : void
    2229           0 : CompositorBridgeParent::InvalidateRemoteLayers()
    2230             : {
    2231           0 :   MOZ_ASSERT(CompositorLoop() == MessageLoop::current());
    2232             : 
    2233           0 :   Unused << PCompositorBridgeParent::SendInvalidateLayers(LayersId{0});
    2234             : 
    2235           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2236           0 :   ForEachIndirectLayerTree([] (LayerTreeState* lts, const LayersId& aLayersId) -> void {
    2237           0 :     if (lts->mCrossProcessParent) {
    2238           0 :       CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
    2239           0 :       Unused << cpcp->SendInvalidateLayers(aLayersId);
    2240             :     }
    2241           0 :   });
    2242           0 : }
    2243             : 
    2244             : void
    2245           2 : UpdateIndirectTree(LayersId aId, Layer* aRoot, const TargetConfig& aTargetConfig)
    2246             : {
    2247           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2248           4 :   sIndirectLayerTrees[aId].mRoot = aRoot;
    2249           2 :   sIndirectLayerTrees[aId].mTargetConfig = aTargetConfig;
    2250           0 : }
    2251             : 
    2252             : /* static */ CompositorBridgeParent::LayerTreeState*
    2253           0 : CompositorBridgeParent::GetIndirectShadowTree(LayersId aId)
    2254             : {
    2255             :   // Only the compositor thread should use this method variant
    2256           6 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    2257             : 
    2258          18 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2259           6 :   LayerTreeMap::iterator cit = sIndirectLayerTrees.find(aId);
    2260           6 :   if (sIndirectLayerTrees.end() == cit) {
    2261             :     return nullptr;
    2262             :   }
    2263           6 :   return &cit->second;
    2264             : }
    2265             : 
    2266             : /* static */ bool
    2267           3 : CompositorBridgeParent::CallWithIndirectShadowTree(LayersId aId,
    2268             :                                                    const std::function<void(CompositorBridgeParent::LayerTreeState&)>& aFunc)
    2269             : {
    2270             :   // Note that this does not make things universally threadsafe just because the
    2271             :   // sIndirectLayerTreesLock mutex is held. This is because the compositor
    2272             :   // thread can mutate the LayerTreeState outside the lock. It does however
    2273             :   // ensure that the *storage* for the LayerTreeState remains stable, since we
    2274             :   // should always hold the lock when adding/removing entries to the map.
    2275           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2276           3 :   LayerTreeMap::iterator cit = sIndirectLayerTrees.find(aId);
    2277           3 :   if (sIndirectLayerTrees.end() == cit) {
    2278             :     return false;
    2279             :   }
    2280           3 :   aFunc(cit->second);
    2281           1 :   return true;
    2282             : }
    2283             : 
    2284             : static CompositorBridgeParent::LayerTreeState*
    2285           0 : GetStateForRoot(LayersId aContentLayersId, const MonitorAutoLock& aProofOfLock)
    2286             : {
    2287           0 :   CompositorBridgeParent::LayerTreeState* state = nullptr;
    2288           0 :   LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aContentLayersId);
    2289           0 :   if (sIndirectLayerTrees.end() != itr) {
    2290           0 :     state = &itr->second;
    2291             :   }
    2292             : 
    2293             :   // |state| is the state for the content process, but we want the APZCTMParent
    2294             :   // for the parent process owning that content process. So we have to jump to
    2295             :   // the LayerTreeState for the root layer tree id for that layer tree, and use
    2296             :   // the mApzcTreeManagerParent from that. This should also work with nested
    2297             :   // content processes, because RootLayerTreeId() will bypass any intermediate
    2298             :   // processes' ids and go straight to the root.
    2299           0 :   if (state) {
    2300           0 :     LayersId rootLayersId = state->mParent->RootLayerTreeId();
    2301           0 :     itr = sIndirectLayerTrees.find(rootLayersId);
    2302           0 :     state = (sIndirectLayerTrees.end() != itr) ? &itr->second : nullptr;
    2303             :   }
    2304             : 
    2305           0 :   return state;
    2306             : }
    2307             : 
    2308             : /* static */ APZCTreeManagerParent*
    2309           0 : CompositorBridgeParent::GetApzcTreeManagerParentForRoot(LayersId aContentLayersId)
    2310             : {
    2311           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2312             :   CompositorBridgeParent::LayerTreeState* state =
    2313           0 :       GetStateForRoot(aContentLayersId, lock);
    2314           0 :   return state ? state->mApzcTreeManagerParent : nullptr;
    2315             : }
    2316             : 
    2317             : /* static */ GeckoContentController*
    2318           0 : CompositorBridgeParent::GetGeckoContentControllerForRoot(LayersId aContentLayersId)
    2319             : {
    2320           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2321             :   CompositorBridgeParent::LayerTreeState* state =
    2322           0 :       GetStateForRoot(aContentLayersId, lock);
    2323           0 :   return state ? state->mController.get() : nullptr;
    2324             : }
    2325             : 
    2326             : PTextureParent*
    2327           2 : CompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
    2328             :                                             const ReadLockDescriptor& aReadLock,
    2329             :                                             const LayersBackend& aLayersBackend,
    2330             :                                             const TextureFlags& aFlags,
    2331             :                                             const LayersId& aId,
    2332             :                                             const uint64_t& aSerial,
    2333             :                                             const wr::MaybeExternalImageId& aExternalImageId)
    2334             : {
    2335           0 :   return TextureHost::CreateIPDLActor(this, aSharedData, aReadLock, aLayersBackend, aFlags, aSerial, aExternalImageId);
    2336             : }
    2337             : 
    2338             : bool
    2339           0 : CompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor)
    2340             : {
    2341           0 :   return TextureHost::DestroyIPDLActor(actor);
    2342             : }
    2343             : 
    2344             : bool
    2345           1 : CompositorBridgeParent::IsSameProcess() const
    2346             : {
    2347           1 :   return OtherPid() == base::GetCurrentProcId();
    2348             : }
    2349             : 
    2350             : void
    2351           0 : CompositorBridgeParent::NotifyWebRenderError(wr::WebRenderError aError)
    2352             : {
    2353           0 :   MOZ_ASSERT(CompositorLoop() == MessageLoop::current());
    2354           0 :   Unused << SendNotifyWebRenderError(aError);
    2355           0 : }
    2356             : 
    2357             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
    2358             : //#define PLUGINS_LOG(...) printf_stderr("CP [%s]: ", __FUNCTION__);
    2359             : //                         printf_stderr(__VA_ARGS__);
    2360             : //                         printf_stderr("\n");
    2361             : #define PLUGINS_LOG(...)
    2362             : 
    2363             : bool
    2364           0 : CompositorBridgeParent::UpdatePluginWindowState(LayersId aId)
    2365             : {
    2366           0 :   MonitorAutoLock lock(*sIndirectLayerTreesLock);
    2367           0 :   CompositorBridgeParent::LayerTreeState& lts = sIndirectLayerTrees[aId];
    2368           0 :   if (!lts.mParent) {
    2369             :     PLUGINS_LOG("[%" PRIu64 "] layer tree compositor parent pointer is null", aId);
    2370             :     return false;
    2371             :   }
    2372             : 
    2373             :   // Check if this layer tree has received any shadow layer updates
    2374           0 :   if (!lts.mUpdatedPluginDataAvailable) {
    2375             :     PLUGINS_LOG("[%" PRIu64 "] no plugin data", aId);
    2376             :     return false;
    2377             :   }
    2378             : 
    2379             :   // pluginMetricsChanged tracks whether we need to send plugin update
    2380             :   // data to the main thread. If we do we'll have to block composition,
    2381             :   // which we want to avoid if at all possible.
    2382           0 :   bool pluginMetricsChanged = false;
    2383             : 
    2384             :   // Same layer tree checks
    2385           0 :   if (mLastPluginUpdateLayerTreeId == aId) {
    2386             :     // no plugin data and nothing has changed, bail.
    2387           0 :     if (!mCachedPluginData.Length() && !lts.mPluginData.Length()) {
    2388             :       PLUGINS_LOG("[%" PRIu64 "] no data, no changes", aId);
    2389             :       return false;
    2390             :     }
    2391             : 
    2392           0 :     if (mCachedPluginData.Length() == lts.mPluginData.Length()) {
    2393             :       // check for plugin data changes
    2394           0 :       for (uint32_t idx = 0; idx < lts.mPluginData.Length(); idx++) {
    2395           0 :         if (!(mCachedPluginData[idx] == lts.mPluginData[idx])) {
    2396             :           pluginMetricsChanged = true;
    2397             :           break;
    2398             :         }
    2399             :       }
    2400             :     } else {
    2401             :       // array lengths don't match, need to update
    2402             :       pluginMetricsChanged = true;
    2403             :     }
    2404             :   } else {
    2405             :     // exchanging layer trees, we need to update
    2406             :     pluginMetricsChanged = true;
    2407             :   }
    2408             : 
    2409             :   // Check if plugin windows are currently hidden due to scrolling
    2410           0 :   if (mDeferPluginWindows) {
    2411             :     PLUGINS_LOG("[%" PRIu64 "] suppressing", aId);
    2412             :     return false;
    2413             :   }
    2414             : 
    2415             :   // If the plugin windows were hidden but now are not, we need to force
    2416             :   // update the metrics to make sure they are visible again.
    2417           0 :   if (mPluginWindowsHidden) {
    2418             :     PLUGINS_LOG("[%" PRIu64 "] re-showing", aId);
    2419           0 :     mPluginWindowsHidden = false;
    2420           0 :     pluginMetricsChanged = true;
    2421             :   }
    2422             : 
    2423           0 :   if (!lts.mPluginData.Length()) {
    2424             :     // Don't hide plugins if the previous remote layer tree didn't contain any.
    2425           0 :     if (!mCachedPluginData.Length()) {
    2426             :       PLUGINS_LOG("[%" PRIu64 "] nothing to hide", aId);
    2427           0 :       return false;
    2428             :     }
    2429             : 
    2430           0 :     uintptr_t parentWidget = GetWidget()->GetWidgetKey();
    2431             : 
    2432             :     // We will pass through here in cases where the previous shadow layer
    2433             :     // tree contained visible plugins and the new tree does not. All we need
    2434             :     // to do here is hide the plugins for the old tree, so don't waste time
    2435             :     // calculating clipping.
    2436           0 :     mPluginsLayerOffset = nsIntPoint(0,0);
    2437           0 :     mPluginsLayerVisibleRegion.SetEmpty();
    2438           0 :     Unused << lts.mParent->SendHideAllPlugins(parentWidget);
    2439           0 :     lts.mUpdatedPluginDataAvailable = false;
    2440             :     PLUGINS_LOG("[%" PRIu64 "] hide all", aId);
    2441             :   } else {
    2442             :     // Retrieve the offset and visible region of the layer that hosts
    2443             :     // the plugins, CompositorBridgeChild needs these in calculating proper
    2444             :     // plugin clipping.
    2445           0 :     LayerTransactionParent* layerTree = lts.mLayerTree;
    2446           0 :     Layer* contentRoot = layerTree->GetRoot();
    2447           0 :     if (contentRoot) {
    2448           0 :       nsIntPoint offset;
    2449           0 :       nsIntRegion visibleRegion;
    2450           0 :       if (contentRoot->GetVisibleRegionRelativeToRootLayer(visibleRegion,
    2451             :                                                             &offset)) {
    2452             :         // Check to see if these values have changed, if so we need to
    2453             :         // update plugin window position within the window.
    2454           0 :         if (!pluginMetricsChanged &&
    2455           0 :             mPluginsLayerVisibleRegion == visibleRegion &&
    2456           0 :             mPluginsLayerOffset == offset) {
    2457             :           PLUGINS_LOG("[%" PRIu64 "] no change", aId);
    2458           0 :           return false;
    2459             :         }
    2460           0 :         mPluginsLayerOffset = offset;
    2461           0 :         mPluginsLayerVisibleRegion = visibleRegion;
    2462           0 :         Unused << lts.mParent->SendUpdatePluginConfigurations(
    2463           0 :           LayoutDeviceIntPoint::FromUnknownPoint(offset),
    2464           0 :           LayoutDeviceIntRegion::FromUnknownRegion(visibleRegion),
    2465             :           lts.mPluginData);
    2466           0 :         lts.mUpdatedPluginDataAvailable = false;
    2467             :         PLUGINS_LOG("[%" PRIu64 "] updated", aId);
    2468             :       } else {
    2469             :         PLUGINS_LOG("[%" PRIu64 "] no visibility data", aId);
    2470             :         return false;
    2471             :       }
    2472             :     } else {
    2473             :       PLUGINS_LOG("[%" PRIu64 "] no content root", aId);
    2474             :       return false;
    2475             :     }
    2476             :   }
    2477             : 
    2478           0 :   mLastPluginUpdateLayerTreeId = aId;
    2479           0 :   mCachedPluginData = lts.mPluginData;
    2480           0 :   return true;
    2481             : }
    2482             : 
    2483             : void
    2484           0 : CompositorBridgeParent::ScheduleShowAllPluginWindows()
    2485             : {
    2486           0 :   MOZ_ASSERT(CompositorLoop());
    2487           0 :   CompositorLoop()->PostTask(
    2488           0 :     NewRunnableMethod("layers::CompositorBridgeParent::ShowAllPluginWindows",
    2489             :                       this,
    2490           0 :                       &CompositorBridgeParent::ShowAllPluginWindows));
    2491           0 : }
    2492             : 
    2493             : void
    2494           0 : CompositorBridgeParent::ShowAllPluginWindows()
    2495             : {
    2496           0 :   MOZ_ASSERT(!NS_IsMainThread());
    2497           0 :   mDeferPluginWindows = false;
    2498           0 :   ScheduleComposition();
    2499           0 : }
    2500             : 
    2501             : void
    2502           0 : CompositorBridgeParent::ScheduleHideAllPluginWindows()
    2503             : {
    2504           0 :   MOZ_ASSERT(CompositorLoop());
    2505           0 :   CompositorLoop()->PostTask(
    2506           0 :     NewRunnableMethod("layers::CompositorBridgeParent::HideAllPluginWindows",
    2507             :                       this,
    2508           0 :                       &CompositorBridgeParent::HideAllPluginWindows));
    2509           0 : }
    2510             : 
    2511             : void
    2512           0 : CompositorBridgeParent::HideAllPluginWindows()
    2513             : {
    2514           0 :   MOZ_ASSERT(!NS_IsMainThread());
    2515             :   // No plugins in the cache implies no plugins to manage
    2516             :   // in this content.
    2517           0 :   if (!mCachedPluginData.Length() || mDeferPluginWindows) {
    2518           0 :     return;
    2519             :   }
    2520             : 
    2521           0 :   uintptr_t parentWidget = GetWidget()->GetWidgetKey();
    2522             : 
    2523           0 :   mDeferPluginWindows = true;
    2524           0 :   mPluginWindowsHidden = true;
    2525             : 
    2526             : #if defined(XP_WIN)
    2527             :   // We will get an async reply that this has happened and then send hide.
    2528             :   mWaitForPluginsUntil = TimeStamp::Now() + mVsyncRate;
    2529             :   Unused << SendCaptureAllPlugins(parentWidget);
    2530             : #else
    2531           0 :   Unused << SendHideAllPlugins(parentWidget);
    2532           0 :   ScheduleComposition();
    2533             : #endif
    2534             : }
    2535             : #endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
    2536             : 
    2537             : mozilla::ipc::IPCResult
    2538           0 : CompositorBridgeParent::RecvAllPluginsCaptured()
    2539             : {
    2540             : #if defined(XP_WIN)
    2541             :   mWaitForPluginsUntil = TimeStamp();
    2542             :   mHaveBlockedForPlugins = false;
    2543             :   ForceComposeToTarget(nullptr);
    2544             :   Unused << SendHideAllPlugins(GetWidget()->GetWidgetKey());
    2545             :   return IPC_OK();
    2546             : #else
    2547             :   MOZ_ASSERT_UNREACHABLE(
    2548             :     "CompositorBridgeParent::RecvAllPluginsCaptured calls unexpected.");
    2549             :   return IPC_FAIL_NO_REASON(this);
    2550             : #endif
    2551             : }
    2552             : 
    2553             : } // namespace layers
    2554             : } // namespace mozilla

Generated by: LCOV version 1.13-14-ga5dd952