LCOV - code coverage report
Current view: top level - gfx/layers/ipc - CompositorBridgeChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 122 502 24.3 %
Date: 2017-07-14 16:53:18 Functions: 24 82 29.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=2 et 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/CompositorBridgeChild.h"
       8             : #include "mozilla/layers/CompositorBridgeParent.h"
       9             : #include "mozilla/layers/CompositorThread.h"
      10             : #include <stddef.h>                     // for size_t
      11             : #include "ClientLayerManager.h"         // for ClientLayerManager
      12             : #include "base/message_loop.h"          // for MessageLoop
      13             : #include "base/task.h"                  // for NewRunnableMethod, etc
      14             : #include "gfxPrefs.h"
      15             : #include "mozilla/dom/TabGroup.h"
      16             : #include "mozilla/layers/CompositorManagerChild.h"
      17             : #include "mozilla/layers/ImageBridgeChild.h"
      18             : #include "mozilla/layers/APZChild.h"
      19             : #include "mozilla/layers/IAPZCTreeManager.h"
      20             : #include "mozilla/layers/APZCTreeManagerChild.h"
      21             : #include "mozilla/layers/LayerTransactionChild.h"
      22             : #include "mozilla/layers/PaintThread.h"
      23             : #include "mozilla/layers/PLayerTransactionChild.h"
      24             : #include "mozilla/layers/PTextureChild.h"
      25             : #include "mozilla/layers/TextureClient.h"// for TextureClient
      26             : #include "mozilla/layers/TextureClientPool.h"// for TextureClientPool
      27             : #include "mozilla/layers/WebRenderBridgeChild.h"
      28             : #include "mozilla/gfx/gfxVars.h"
      29             : #include "mozilla/gfx/GPUProcessManager.h"
      30             : #include "mozilla/gfx/Logging.h"
      31             : #include "mozilla/mozalloc.h"           // for operator new, etc
      32             : #include "nsAutoPtr.h"
      33             : #include "nsDebug.h"                    // for NS_RUNTIMEABORT
      34             : #include "nsIObserver.h"                // for nsIObserver
      35             : #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
      36             : #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
      37             : #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop, etc
      38             : #include "FrameLayerBuilder.h"
      39             : #include "mozilla/dom/TabChild.h"
      40             : #include "mozilla/dom/TabParent.h"
      41             : #include "mozilla/dom/ContentChild.h"
      42             : #include "mozilla/Unused.h"
      43             : #include "mozilla/DebugOnly.h"
      44             : #if defined(XP_WIN)
      45             : #include "WinUtils.h"
      46             : #endif
      47             : #include "mozilla/widget/CompositorWidget.h"
      48             : #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
      49             : # include "mozilla/widget/CompositorWidgetChild.h"
      50             : #endif
      51             : #include "VsyncSource.h"
      52             : 
      53             : using mozilla::layers::LayerTransactionChild;
      54             : using mozilla::dom::TabChildBase;
      55             : using mozilla::Unused;
      56             : using mozilla::gfx::GPUProcessManager;
      57             : 
      58             : namespace mozilla {
      59             : namespace layers {
      60             : 
      61             : static int sShmemCreationCounter = 0;
      62             : 
      63          29 : static void ResetShmemCounter()
      64             : {
      65          29 :   sShmemCreationCounter = 0;
      66          29 : }
      67             : 
      68           1 : static void ShmemAllocated(CompositorBridgeChild* aProtocol)
      69             : {
      70           1 :   sShmemCreationCounter++;
      71           1 :   if (sShmemCreationCounter > 256) {
      72           0 :     aProtocol->SendSyncWithCompositor();
      73           0 :     ResetShmemCounter();
      74           0 :     MOZ_PERFORMANCE_WARNING("gfx", "The number of shmem allocations is too damn high!");
      75             :   }
      76           1 : }
      77             : 
      78           3 : static StaticRefPtr<CompositorBridgeChild> sCompositorBridge;
      79             : 
      80             : Atomic<int32_t> KnowsCompositor::sSerialCounter(0);
      81             : 
      82           3 : CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild *aManager)
      83             :   : mCompositorManager(aManager)
      84             :   , mIdNamespace(0)
      85             :   , mResourceId(0)
      86             :   , mCanSend(false)
      87             :   , mActorDestroyed(false)
      88             :   , mFwdTransactionId(0)
      89             :   , mDeviceResetSequenceNumber(0)
      90           3 :   , mMessageLoop(MessageLoop::current())
      91             :   , mProcessToken(0)
      92             :   , mSectionAllocator(nullptr)
      93             :   , mPaintLock("CompositorBridgeChild.mPaintLock")
      94             :   , mOutstandingAsyncPaints(0)
      95           6 :   , mIsWaitingForPaint(false)
      96             : {
      97           3 :   MOZ_ASSERT(NS_IsMainThread());
      98           3 : }
      99             : 
     100           0 : CompositorBridgeChild::~CompositorBridgeChild()
     101             : {
     102           0 :   if (mCanSend) {
     103           0 :     gfxCriticalError() << "CompositorBridgeChild was not deinitialized";
     104             :   }
     105           0 : }
     106             : 
     107             : bool
     108          37 : CompositorBridgeChild::IsSameProcess() const
     109             : {
     110          37 :   return OtherPid() == base::GetCurrentProcId();
     111             : }
     112             : 
     113             : void
     114           0 : CompositorBridgeChild::AfterDestroy()
     115             : {
     116             :   // Note that we cannot rely upon mCanSend here because we already set that to
     117             :   // false to prevent normal IPDL calls from being made after SendWillClose.
     118             :   // The only time we should not issue Send__delete__ is if the actor is already
     119             :   // destroyed, e.g. the compositor process crashed.
     120           0 :   if (!mActorDestroyed) {
     121           0 :     Send__delete__(this);
     122             :   }
     123             : 
     124           0 :   if (sCompositorBridge == this) {
     125           0 :     sCompositorBridge = nullptr;
     126             :   }
     127           0 : }
     128             : 
     129             : void
     130           0 : CompositorBridgeChild::Destroy()
     131             : {
     132             :   // This must not be called from the destructor!
     133           0 :   mTexturesWaitingRecycled.Clear();
     134             : 
     135           0 :   if (!mCanSend) {
     136           0 :     return;
     137             :   }
     138             : 
     139           0 :   for (size_t i = 0; i < mTexturePools.Length(); i++) {
     140           0 :     mTexturePools[i]->Destroy();
     141             :   }
     142             : 
     143           0 :   if (mSectionAllocator) {
     144           0 :     delete mSectionAllocator;
     145           0 :     mSectionAllocator = nullptr;
     146             :   }
     147             : 
     148             :   // Destroying the layer manager may cause all sorts of things to happen, so
     149             :   // let's make sure there is still a reference to keep this alive whatever
     150             :   // happens.
     151           0 :   RefPtr<CompositorBridgeChild> selfRef = this;
     152             : 
     153           0 :   if (mLayerManager) {
     154           0 :     mLayerManager->Destroy();
     155           0 :     mLayerManager = nullptr;
     156             :   }
     157             : 
     158           0 :   AutoTArray<PLayerTransactionChild*, 16> transactions;
     159           0 :   ManagedPLayerTransactionChild(transactions);
     160           0 :   for (int i = transactions.Length() - 1; i >= 0; --i) {
     161             :     RefPtr<LayerTransactionChild> layers =
     162           0 :       static_cast<LayerTransactionChild*>(transactions[i]);
     163           0 :     layers->Destroy();
     164             :   }
     165             : 
     166           0 :   AutoTArray<PWebRenderBridgeChild*, 16> wrBridges;
     167           0 :   ManagedPWebRenderBridgeChild(wrBridges);
     168           0 :   for (int i = wrBridges.Length() - 1; i >= 0; --i) {
     169             :     RefPtr<WebRenderBridgeChild> wrBridge =
     170           0 :       static_cast<WebRenderBridgeChild*>(wrBridges[i]);
     171           0 :     wrBridge->Destroy(/* aIsSync */ false);
     172             :   }
     173             : 
     174           0 :   const ManagedContainer<PTextureChild>& textures = ManagedPTextureChild();
     175           0 :   for (auto iter = textures.ConstIter(); !iter.Done(); iter.Next()) {
     176           0 :     RefPtr<TextureClient> texture = TextureClient::AsTextureClient(iter.Get()->GetKey());
     177             : 
     178           0 :     if (texture) {
     179           0 :       texture->Destroy();
     180             :     }
     181             :   }
     182             : 
     183           0 :   SendWillClose();
     184           0 :   mCanSend = false;
     185             : 
     186             :   // We no longer care about unexpected shutdowns, in the remote process case.
     187           0 :   mProcessToken = 0;
     188             : 
     189             :   // The call just made to SendWillClose can result in IPC from the
     190             :   // CompositorBridgeParent to the CompositorBridgeChild (e.g. caused by the destruction
     191             :   // of shared memory). We need to ensure this gets processed by the
     192             :   // CompositorBridgeChild before it gets destroyed. It suffices to ensure that
     193             :   // events already in the MessageLoop get processed before the
     194             :   // CompositorBridgeChild is destroyed, so we add a task to the MessageLoop to
     195             :   // handle compositor destruction.
     196             : 
     197             :   // From now on we can't send any message message.
     198           0 :   MessageLoop::current()->PostTask(NewRunnableMethod(
     199             :     "CompositorBridgeChild::AfterDestroy",
     200           0 :     selfRef, &CompositorBridgeChild::AfterDestroy));
     201             : }
     202             : 
     203             : // static
     204             : void
     205           0 : CompositorBridgeChild::ShutDown()
     206             : {
     207           0 :   if (sCompositorBridge) {
     208           0 :     sCompositorBridge->Destroy();
     209           0 :     SpinEventLoopUntil([&]() { return !sCompositorBridge; });
     210             :   }
     211           0 : }
     212             : 
     213             : bool
     214           0 : CompositorBridgeChild::LookupCompositorFrameMetrics(const FrameMetrics::ViewID aId,
     215             :                                                     FrameMetrics& aFrame)
     216             : {
     217           0 :   SharedFrameMetricsData* data = mFrameMetricsTable.Get(aId);
     218           0 :   if (data) {
     219           0 :     data->CopyFrameMetrics(&aFrame);
     220           0 :     return true;
     221             :   }
     222           0 :   return false;
     223             : }
     224             : 
     225             : void
     226           2 : CompositorBridgeChild::InitForContent(uint32_t aNamespace)
     227             : {
     228           2 :   MOZ_ASSERT(NS_IsMainThread());
     229           2 :   MOZ_ASSERT(aNamespace);
     230             : 
     231           4 :   if (RefPtr<CompositorBridgeChild> old = sCompositorBridge.forget()) {
     232             :     // Note that at this point, ActorDestroy may not have been called yet,
     233             :     // meaning mCanSend is still true. In this case we will try to send a
     234             :     // synchronous WillClose message to the parent, and will certainly get
     235             :     // a false result and a MsgDropped processing error. This is okay.
     236           0 :     old->Destroy();
     237             :   }
     238             : 
     239           2 :   mCanSend = true;
     240           2 :   mIdNamespace = aNamespace;
     241           2 :   sCompositorBridge = this;
     242           2 : }
     243             : 
     244             : void
     245           1 : CompositorBridgeChild::InitForWidget(uint64_t aProcessToken,
     246             :                                      LayerManager* aLayerManager,
     247             :                                      uint32_t aNamespace)
     248             : {
     249           1 :   MOZ_ASSERT(NS_IsMainThread());
     250           1 :   MOZ_ASSERT(aProcessToken);
     251           1 :   MOZ_ASSERT(aLayerManager);
     252           1 :   MOZ_ASSERT(aNamespace);
     253             : 
     254           1 :   mCanSend = true;
     255           1 :   mProcessToken = aProcessToken;
     256           1 :   mLayerManager = aLayerManager;
     257           1 :   mIdNamespace = aNamespace;
     258           1 : }
     259             : 
     260             : /*static*/ CompositorBridgeChild*
     261          10 : CompositorBridgeChild::Get()
     262             : {
     263             :   // This is only expected to be used in child processes.
     264          10 :   MOZ_ASSERT(!XRE_IsParentProcess());
     265          10 :   return sCompositorBridge;
     266             : }
     267             : 
     268             : // static
     269             : bool
     270           0 : CompositorBridgeChild::ChildProcessHasCompositorBridge()
     271             : {
     272           0 :   return sCompositorBridge != nullptr;
     273             : }
     274             : 
     275             : /* static */ bool
     276           0 : CompositorBridgeChild::CompositorIsInGPUProcess()
     277             : {
     278           0 :   MOZ_ASSERT(NS_IsMainThread());
     279             : 
     280           0 :   if (XRE_IsParentProcess()) {
     281           0 :     return !!GPUProcessManager::Get()->GetGPUChild();
     282             :   }
     283             : 
     284           0 :   MOZ_ASSERT(XRE_IsContentProcess());
     285           0 :   CompositorBridgeChild* bridge = CompositorBridgeChild::Get();
     286           0 :   if (!bridge) {
     287           0 :     return false;
     288             :   }
     289             : 
     290           0 :   return bridge->OtherPid() != dom::ContentChild::GetSingleton()->OtherPid();
     291             : }
     292             : 
     293             : PLayerTransactionChild*
     294           2 : CompositorBridgeChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints, const uint64_t& aId)
     295             : {
     296           2 :   LayerTransactionChild* c = new LayerTransactionChild(aId);
     297           2 :   c->AddIPDLReference();
     298             : 
     299           2 :   TabChild* tabChild = TabChild::GetFrom(c->GetId());
     300             : 
     301             :   // Do the DOM Labeling.
     302           2 :   if (tabChild) {
     303             :     nsCOMPtr<nsIEventTarget> target =
     304           2 :       tabChild->TabGroup()->EventTargetFor(TaskCategory::Other);
     305           1 :     SetEventTargetForActor(c, target);
     306           1 :     MOZ_ASSERT(c->GetActorEventTarget());
     307             :   }
     308             : 
     309           2 :   return c;
     310             : }
     311             : 
     312             : bool
     313           0 : CompositorBridgeChild::DeallocPLayerTransactionChild(PLayerTransactionChild* actor)
     314             : {
     315           0 :   uint64_t childId = static_cast<LayerTransactionChild*>(actor)->GetId();
     316             : 
     317           0 :   for (auto iter = mFrameMetricsTable.Iter(); !iter.Done(); iter.Next()) {
     318           0 :     nsAutoPtr<SharedFrameMetricsData>& data = iter.Data();
     319           0 :     if (data->GetLayersId() == childId) {
     320           0 :       iter.Remove();
     321             :     }
     322             :   }
     323           0 :   static_cast<LayerTransactionChild*>(actor)->ReleaseIPDLReference();
     324           0 :   return true;
     325             : }
     326             : 
     327             : mozilla::ipc::IPCResult
     328           0 : CompositorBridgeChild::RecvInvalidateLayers(const uint64_t& aLayersId)
     329             : {
     330           0 :   if (mLayerManager) {
     331           0 :     MOZ_ASSERT(aLayersId == 0);
     332           0 :     FrameLayerBuilder::InvalidateAllLayers(mLayerManager);
     333           0 :   } else if (aLayersId != 0) {
     334           0 :     if (dom::TabChild* child = dom::TabChild::GetFrom(aLayersId)) {
     335           0 :       child->InvalidateLayers();
     336             :     }
     337             :   }
     338           0 :   return IPC_OK();
     339             : }
     340             : 
     341             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
     342           0 : static void CalculatePluginClip(const LayoutDeviceIntRect& aBounds,
     343             :                                 const nsTArray<LayoutDeviceIntRect>& aPluginClipRects,
     344             :                                 const LayoutDeviceIntPoint& aContentOffset,
     345             :                                 const LayoutDeviceIntRegion& aParentLayerVisibleRegion,
     346             :                                 nsTArray<LayoutDeviceIntRect>& aResult,
     347             :                                 LayoutDeviceIntRect& aVisibleBounds,
     348             :                                 bool& aPluginIsVisible)
     349             : {
     350           0 :   aPluginIsVisible = true;
     351           0 :   LayoutDeviceIntRegion contentVisibleRegion;
     352             :   // aPluginClipRects (plugin widget origin) - contains *visible* rects
     353           0 :   for (uint32_t idx = 0; idx < aPluginClipRects.Length(); idx++) {
     354           0 :     LayoutDeviceIntRect rect = aPluginClipRects[idx];
     355             :     // shift to content origin
     356           0 :     rect.MoveBy(aBounds.x, aBounds.y);
     357             :     // accumulate visible rects
     358           0 :     contentVisibleRegion.OrWith(rect);
     359             :   }
     360             :   // apply layers clip (window origin)
     361           0 :   LayoutDeviceIntRegion region = aParentLayerVisibleRegion;
     362           0 :   region.MoveBy(-aContentOffset.x, -aContentOffset.y);
     363           0 :   contentVisibleRegion.AndWith(region);
     364           0 :   if (contentVisibleRegion.IsEmpty()) {
     365           0 :     aPluginIsVisible = false;
     366           0 :     return;
     367             :   }
     368             :   // shift to plugin widget origin
     369           0 :   contentVisibleRegion.MoveBy(-aBounds.x, -aBounds.y);
     370           0 :   for (auto iter = contentVisibleRegion.RectIter(); !iter.Done(); iter.Next()) {
     371           0 :     const LayoutDeviceIntRect& rect = iter.Get();
     372           0 :     aResult.AppendElement(rect);
     373           0 :     aVisibleBounds.UnionRect(aVisibleBounds, rect);
     374             :   }
     375             : }
     376             : #endif
     377             : 
     378             : mozilla::ipc::IPCResult
     379           0 : CompositorBridgeChild::RecvUpdatePluginConfigurations(const LayoutDeviceIntPoint& aContentOffset,
     380             :                                                       const LayoutDeviceIntRegion& aParentLayerVisibleRegion,
     381             :                                                       nsTArray<PluginWindowData>&& aPlugins)
     382             : {
     383             : #if !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
     384             :   NS_NOTREACHED("CompositorBridgeChild::RecvUpdatePluginConfigurations calls "
     385             :                 "unexpected on this platform.");
     386             :   return IPC_FAIL_NO_REASON(this);
     387             : #else
     388             :   // Now that we are on the main thread, update plugin widget config.
     389             :   // This should happen a little before we paint to the screen assuming
     390             :   // the main thread is running freely.
     391           0 :   DebugOnly<nsresult> rv;
     392           0 :   MOZ_ASSERT(NS_IsMainThread());
     393             : 
     394             :   // Tracks visible plugins we update, so we can hide any plugins we don't.
     395           0 :   nsTArray<uintptr_t> visiblePluginIds;
     396           0 :   nsIWidget* parent = nullptr;
     397           0 :   for (uint32_t pluginsIdx = 0; pluginsIdx < aPlugins.Length(); pluginsIdx++) {
     398             :     nsIWidget* widget =
     399           0 :       nsIWidget::LookupRegisteredPluginWindow(aPlugins[pluginsIdx].windowId());
     400           0 :     if (!widget) {
     401           0 :       NS_WARNING("Unexpected, plugin id not found!");
     402           0 :       continue;
     403             :     }
     404           0 :     if (!parent) {
     405           0 :       parent = widget->GetParent();
     406             :     }
     407           0 :     bool isVisible = aPlugins[pluginsIdx].visible();
     408           0 :     if (widget && !widget->Destroyed()) {
     409           0 :       LayoutDeviceIntRect bounds;
     410           0 :       LayoutDeviceIntRect visibleBounds;
     411             :       // If the plugin is visible update it's geometry.
     412           0 :       if (isVisible) {
     413             :         // Set bounds (content origin)
     414           0 :         bounds = aPlugins[pluginsIdx].bounds();
     415           0 :         nsTArray<LayoutDeviceIntRect> rectsOut;
     416             :         // This call may change the value of isVisible
     417           0 :         CalculatePluginClip(bounds, aPlugins[pluginsIdx].clip(),
     418             :                             aContentOffset,
     419             :                             aParentLayerVisibleRegion,
     420           0 :                             rectsOut, visibleBounds, isVisible);
     421             :         // content clipping region (widget origin)
     422           0 :         rv = widget->SetWindowClipRegion(rectsOut, false);
     423           0 :         NS_ASSERTION(NS_SUCCEEDED(rv), "widget call failure");
     424             :         // This will trigger a browser window paint event for areas uncovered
     425             :         // by a child window move, and will call invalidate on the plugin
     426             :         // parent window which the browser owns. The latter gets picked up in
     427             :         // our OnPaint handler and forwarded over to the plugin process async.
     428           0 :         widget->Resize(aContentOffset.x + bounds.x,
     429           0 :                        aContentOffset.y + bounds.y,
     430           0 :                        bounds.width, bounds.height, true);
     431             :       }
     432             : 
     433           0 :       widget->Enable(isVisible);
     434             : 
     435             :       // visible state - updated after clipping, prior to invalidating
     436           0 :       widget->Show(isVisible);
     437             : 
     438             :       // Handle invalidation, this can be costly, avoid if it is not needed.
     439           0 :       if (isVisible) {
     440             :         // invalidate region (widget origin)
     441             : #if defined(XP_WIN)
     442             :         // Work around for flash's crummy sandbox. See bug 762948. This call
     443             :         // digs down into the window hirearchy, invalidating regions on
     444             :         // windows owned by other processes.
     445             :         mozilla::widget::WinUtils::InvalidatePluginAsWorkaround(
     446             :           widget, visibleBounds);
     447             : #else
     448           0 :         widget->Invalidate(visibleBounds);
     449             : #endif
     450           0 :         visiblePluginIds.AppendElement(aPlugins[pluginsIdx].windowId());
     451             :       }
     452             :     }
     453             :   }
     454             :   // Any plugins we didn't update need to be hidden, as they are
     455             :   // not associated with visible content.
     456           0 :   nsIWidget::UpdateRegisteredPluginWindowVisibility((uintptr_t)parent, visiblePluginIds);
     457           0 :   if (!mCanSend) {
     458           0 :     return IPC_OK();
     459             :   }
     460           0 :   SendRemotePluginsReady();
     461           0 :   return IPC_OK();
     462             : #endif // !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
     463             : }
     464             : 
     465             : #if defined(XP_WIN)
     466             : static void
     467             : ScheduleSendAllPluginsCaptured(CompositorBridgeChild* aThis, MessageLoop* aLoop)
     468             : {
     469             :   aLoop->PostTask(NewNonOwningRunnableMethod(
     470             :     "CompositorBridgeChild::SendAllPluginsCaptured",
     471             :     aThis, &CompositorBridgeChild::SendAllPluginsCaptured));
     472             : }
     473             : #endif
     474             : 
     475             : mozilla::ipc::IPCResult
     476           0 : CompositorBridgeChild::RecvCaptureAllPlugins(const uintptr_t& aParentWidget)
     477             : {
     478             : #if defined(XP_WIN)
     479             :   MOZ_ASSERT(NS_IsMainThread());
     480             :   nsIWidget::CaptureRegisteredPlugins(aParentWidget);
     481             : 
     482             :   // Bounce the call to SendAllPluginsCaptured off the ImageBridgeChild loop,
     483             :   // to make sure that the image updates on that thread have been processed.
     484             :   ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
     485             :     NewRunnableFunction(&ScheduleSendAllPluginsCaptured, this,
     486             :                         MessageLoop::current()));
     487             :   return IPC_OK();
     488             : #else
     489           0 :   MOZ_ASSERT_UNREACHABLE(
     490             :     "CompositorBridgeChild::RecvCaptureAllPlugins calls unexpected.");
     491             :   return IPC_FAIL_NO_REASON(this);
     492             : #endif
     493             : }
     494             : 
     495             : mozilla::ipc::IPCResult
     496           0 : CompositorBridgeChild::RecvHideAllPlugins(const uintptr_t& aParentWidget)
     497             : {
     498             : #if !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
     499             :   NS_NOTREACHED("CompositorBridgeChild::RecvHideAllPlugins calls "
     500             :                 "unexpected on this platform.");
     501             :   return IPC_FAIL_NO_REASON(this);
     502             : #else
     503           0 :   MOZ_ASSERT(NS_IsMainThread());
     504           0 :   nsTArray<uintptr_t> list;
     505           0 :   nsIWidget::UpdateRegisteredPluginWindowVisibility(aParentWidget, list);
     506           0 :   if (!mCanSend) {
     507           0 :     return IPC_OK();
     508             :   }
     509           0 :   SendRemotePluginsReady();
     510           0 :   return IPC_OK();
     511             : #endif // !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
     512             : }
     513             : 
     514             : mozilla::ipc::IPCResult
     515          54 : CompositorBridgeChild::RecvDidComposite(const uint64_t& aId, const uint64_t& aTransactionId,
     516             :                                         const TimeStamp& aCompositeStart,
     517             :                                         const TimeStamp& aCompositeEnd)
     518             : {
     519          54 :   if (mLayerManager) {
     520          27 :     MOZ_ASSERT(aId == 0);
     521          27 :     MOZ_ASSERT(mLayerManager->GetBackendType() == LayersBackend::LAYERS_CLIENT ||
     522             :                mLayerManager->GetBackendType() == LayersBackend::LAYERS_WR);
     523             :     // Hold a reference to keep LayerManager alive. See Bug 1242668.
     524          54 :     RefPtr<LayerManager> m = mLayerManager;
     525          27 :     m->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
     526          27 :   } else if (aId != 0) {
     527          54 :     RefPtr<dom::TabChild> child = dom::TabChild::GetFrom(aId);
     528          27 :     if (child) {
     529          27 :       child->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
     530             :     }
     531             :   }
     532             : 
     533          54 :   for (size_t i = 0; i < mTexturePools.Length(); i++) {
     534           0 :     mTexturePools[i]->ReturnDeferredClients();
     535             :   }
     536             : 
     537          54 :   return IPC_OK();
     538             : }
     539             : 
     540             : void
     541           0 : CompositorBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
     542             : {
     543           0 :   if (aWhy == AbnormalShutdown) {
     544             :     // If the parent side runs into a problem then the actor will be destroyed.
     545             :     // There is nothing we can do in the child side, here sets mCanSend as false.
     546           0 :     gfxCriticalNote << "Receive IPC close with reason=AbnormalShutdown";
     547             :   }
     548             : 
     549             :   {
     550             :     // We take the lock to update these fields, since they are read from the
     551             :     // paint thread. We don't need the lock to init them, since that happens
     552             :     // on the main thread before the paint thread can ever grab a reference
     553             :     // to the CompositorBridge object.
     554             :     //
     555             :     // Note that it is useful to take this lock for one other reason: It also
     556             :     // tells us whether GetIPCChannel is safe to call. If we access the IPC
     557             :     // channel within this lock, when mCanSend is true, then we know it has not
     558             :     // been zapped by IPDL.
     559           0 :     MonitorAutoLock lock(mPaintLock);
     560           0 :     mCanSend = false;
     561           0 :     mActorDestroyed = true;
     562             :   }
     563             : 
     564           0 :   if (mProcessToken && XRE_IsParentProcess()) {
     565           0 :     GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
     566             :   }
     567           0 : }
     568             : 
     569             : mozilla::ipc::IPCResult
     570           0 : CompositorBridgeChild::RecvSharedCompositorFrameMetrics(
     571             :     const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
     572             :     const CrossProcessMutexHandle& handle,
     573             :     const uint64_t& aLayersId,
     574             :     const uint32_t& aAPZCId)
     575             : {
     576             :   SharedFrameMetricsData* data = new SharedFrameMetricsData(
     577           0 :     metrics, handle, aLayersId, aAPZCId);
     578           0 :   mFrameMetricsTable.Put(data->GetViewID(), data);
     579           0 :   return IPC_OK();
     580             : }
     581             : 
     582             : mozilla::ipc::IPCResult
     583           0 : CompositorBridgeChild::RecvReleaseSharedCompositorFrameMetrics(
     584             :     const ViewID& aId,
     585             :     const uint32_t& aAPZCId)
     586             : {
     587           0 :   if (auto entry = mFrameMetricsTable.Lookup(aId)) {
     588             :     // The SharedFrameMetricsData may have been removed previously if
     589             :     // a SharedFrameMetricsData with the same ViewID but later APZCId had
     590             :     // been store and over wrote it.
     591           0 :     if (entry.Data()->GetAPZCId() == aAPZCId) {
     592           0 :       entry.Remove();
     593             :     }
     594             :   }
     595           0 :   return IPC_OK();
     596             : }
     597             : 
     598           0 : CompositorBridgeChild::SharedFrameMetricsData::SharedFrameMetricsData(
     599             :     const ipc::SharedMemoryBasic::Handle& metrics,
     600             :     const CrossProcessMutexHandle& handle,
     601             :     const uint64_t& aLayersId,
     602           0 :     const uint32_t& aAPZCId)
     603             :   : mMutex(nullptr)
     604           0 :   , mLayersId(aLayersId)
     605           0 :   , mAPZCId(aAPZCId)
     606             : {
     607           0 :   mBuffer = new ipc::SharedMemoryBasic;
     608           0 :   mBuffer->SetHandle(metrics, ipc::SharedMemory::RightsReadOnly);
     609           0 :   mBuffer->Map(sizeof(FrameMetrics));
     610           0 :   mMutex = new CrossProcessMutex(handle);
     611           0 :   MOZ_COUNT_CTOR(SharedFrameMetricsData);
     612           0 : }
     613             : 
     614           0 : CompositorBridgeChild::SharedFrameMetricsData::~SharedFrameMetricsData()
     615             : {
     616             :   // When the hash table deletes the class, delete
     617             :   // the shared memory and mutex.
     618           0 :   delete mMutex;
     619           0 :   mBuffer = nullptr;
     620           0 :   MOZ_COUNT_DTOR(SharedFrameMetricsData);
     621           0 : }
     622             : 
     623             : void
     624           0 : CompositorBridgeChild::SharedFrameMetricsData::CopyFrameMetrics(FrameMetrics* aFrame)
     625             : {
     626             :   const FrameMetrics* frame =
     627           0 :     static_cast<const FrameMetrics*>(mBuffer->memory());
     628           0 :   MOZ_ASSERT(frame);
     629           0 :   mMutex->Lock();
     630           0 :   *aFrame = *frame;
     631           0 :   mMutex->Unlock();
     632           0 : }
     633             : 
     634             : FrameMetrics::ViewID
     635           0 : CompositorBridgeChild::SharedFrameMetricsData::GetViewID()
     636             : {
     637             :   const FrameMetrics* frame =
     638           0 :     static_cast<const FrameMetrics*>(mBuffer->memory());
     639           0 :   MOZ_ASSERT(frame);
     640             :   // Not locking to read of mScrollId since it should not change after being
     641             :   // initially set.
     642           0 :   return frame->GetScrollId();
     643             : }
     644             : 
     645             : uint64_t
     646           0 : CompositorBridgeChild::SharedFrameMetricsData::GetLayersId() const
     647             : {
     648           0 :   return mLayersId;
     649             : }
     650             : 
     651             : uint32_t
     652           0 : CompositorBridgeChild::SharedFrameMetricsData::GetAPZCId()
     653             : {
     654           0 :   return mAPZCId;
     655             : }
     656             : 
     657             : 
     658             : mozilla::ipc::IPCResult
     659           0 : CompositorBridgeChild::RecvRemotePaintIsReady()
     660             : {
     661             :   // Used on the content thread, this bounces the message to the
     662             :   // TabParent (via the TabChild) if the notification was previously requested.
     663             :   // XPCOM gives a soup of compiler errors when trying to do_QueryReference
     664             :   // so I'm using static_cast<>
     665           0 :   MOZ_LAYERS_LOG(("[RemoteGfx] CompositorBridgeChild received RemotePaintIsReady"));
     666           0 :   RefPtr<nsISupports> iTabChildBase(do_QueryReferent(mWeakTabChild));
     667           0 :   if (!iTabChildBase) {
     668           0 :     MOZ_LAYERS_LOG(("[RemoteGfx] Note: TabChild was released before RemotePaintIsReady. "
     669             :         "MozAfterRemotePaint will not be sent to listener."));
     670           0 :     return IPC_OK();
     671             :   }
     672           0 :   TabChildBase* tabChildBase = static_cast<TabChildBase*>(iTabChildBase.get());
     673           0 :   TabChild* tabChild = static_cast<TabChild*>(tabChildBase);
     674           0 :   MOZ_ASSERT(tabChild);
     675           0 :   Unused << tabChild->SendRemotePaintIsReady();
     676           0 :   mWeakTabChild = nullptr;
     677           0 :   return IPC_OK();
     678             : }
     679             : 
     680             : 
     681             : void
     682           0 : CompositorBridgeChild::RequestNotifyAfterRemotePaint(TabChild* aTabChild)
     683             : {
     684           0 :   MOZ_ASSERT(aTabChild, "NULL TabChild not allowed in CompositorBridgeChild::RequestNotifyAfterRemotePaint");
     685           0 :   mWeakTabChild = do_GetWeakReference( static_cast<dom::TabChildBase*>(aTabChild) );
     686           0 :   if (!mCanSend) {
     687           0 :     return;
     688             :   }
     689           0 :   Unused << SendRequestNotifyAfterRemotePaint();
     690             : }
     691             : 
     692             : void
     693           0 : CompositorBridgeChild::CancelNotifyAfterRemotePaint(TabChild* aTabChild)
     694             : {
     695           0 :   RefPtr<nsISupports> iTabChildBase(do_QueryReferent(mWeakTabChild));
     696           0 :   if (!iTabChildBase) {
     697           0 :     return;
     698             :   }
     699           0 :   TabChildBase* tabChildBase = static_cast<TabChildBase*>(iTabChildBase.get());
     700           0 :   TabChild* tabChild = static_cast<TabChild*>(tabChildBase);
     701           0 :   if (tabChild == aTabChild) {
     702           0 :     mWeakTabChild = nullptr;
     703             :   }
     704             : }
     705             : 
     706             : bool
     707           0 : CompositorBridgeChild::SendWillClose()
     708             : {
     709           0 :   MOZ_RELEASE_ASSERT(mCanSend);
     710           0 :   return PCompositorBridgeChild::SendWillClose();
     711             : }
     712             : 
     713             : bool
     714           0 : CompositorBridgeChild::SendPause()
     715             : {
     716           0 :   if (!mCanSend) {
     717           0 :     return false;
     718             :   }
     719           0 :   return PCompositorBridgeChild::SendPause();
     720             : }
     721             : 
     722             : bool
     723           0 : CompositorBridgeChild::SendResume()
     724             : {
     725           0 :   if (!mCanSend) {
     726           0 :     return false;
     727             :   }
     728           0 :   return PCompositorBridgeChild::SendResume();
     729             : }
     730             : 
     731             : bool
     732           0 : CompositorBridgeChild::SendNotifyChildCreated(const uint64_t& id,
     733             :                                               CompositorOptions* aOptions)
     734             : {
     735           0 :   if (!mCanSend) {
     736           0 :     return false;
     737             :   }
     738           0 :   return PCompositorBridgeChild::SendNotifyChildCreated(id, aOptions);
     739             : }
     740             : 
     741             : bool
     742           1 : CompositorBridgeChild::SendAdoptChild(const uint64_t& id)
     743             : {
     744           1 :   if (!mCanSend) {
     745           0 :     return false;
     746             :   }
     747           1 :   return PCompositorBridgeChild::SendAdoptChild(id);
     748             : }
     749             : 
     750             : bool
     751           0 : CompositorBridgeChild::SendMakeSnapshot(const SurfaceDescriptor& inSnapshot, const gfx::IntRect& dirtyRect)
     752             : {
     753           0 :   if (!mCanSend) {
     754           0 :     return false;
     755             :   }
     756           0 :   return PCompositorBridgeChild::SendMakeSnapshot(inSnapshot, dirtyRect);
     757             : }
     758             : 
     759             : bool
     760           1 : CompositorBridgeChild::SendFlushRendering()
     761             : {
     762           1 :   if (!mCanSend) {
     763           0 :     return false;
     764             :   }
     765           1 :   return PCompositorBridgeChild::SendFlushRendering();
     766             : }
     767             : 
     768             : bool
     769           0 : CompositorBridgeChild::SendStartFrameTimeRecording(const int32_t& bufferSize, uint32_t* startIndex)
     770             : {
     771           0 :   if (!mCanSend) {
     772           0 :     return false;
     773             :   }
     774           0 :   return PCompositorBridgeChild::SendStartFrameTimeRecording(bufferSize, startIndex);
     775             : }
     776             : 
     777             : bool
     778           0 : CompositorBridgeChild::SendStopFrameTimeRecording(const uint32_t& startIndex, nsTArray<float>* intervals)
     779             : {
     780           0 :   if (!mCanSend) {
     781           0 :     return false;
     782             :   }
     783           0 :   return PCompositorBridgeChild::SendStopFrameTimeRecording(startIndex, intervals);
     784             : }
     785             : 
     786             : bool
     787           1 : CompositorBridgeChild::SendNotifyRegionInvalidated(const nsIntRegion& region)
     788             : {
     789           1 :   if (!mCanSend) {
     790           0 :     return false;
     791             :   }
     792           1 :   return PCompositorBridgeChild::SendNotifyRegionInvalidated(region);
     793             : }
     794             : 
     795             : bool
     796           0 : CompositorBridgeChild::SendRequestNotifyAfterRemotePaint()
     797             : {
     798           0 :   if (!mCanSend) {
     799           0 :     return false;
     800             :   }
     801           0 :   return PCompositorBridgeChild::SendRequestNotifyAfterRemotePaint();
     802             : }
     803             : 
     804             : bool
     805           0 : CompositorBridgeChild::SendClearApproximatelyVisibleRegions(uint64_t aLayersId,
     806             :                                                             uint32_t aPresShellId)
     807             : {
     808           0 :   if (!mCanSend) {
     809           0 :     return false;
     810             :   }
     811           0 :   return PCompositorBridgeChild::SendClearApproximatelyVisibleRegions(aLayersId,
     812           0 :                                                                 aPresShellId);
     813             : }
     814             : 
     815             : bool
     816           0 : CompositorBridgeChild::SendNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
     817             :                                                             const CSSIntRegion& aRegion)
     818             : {
     819           0 :   if (!mCanSend) {
     820           0 :     return false;
     821             :   }
     822           0 :   return PCompositorBridgeChild::SendNotifyApproximatelyVisibleRegion(aGuid, aRegion);
     823             : }
     824             : 
     825             : bool
     826           0 : CompositorBridgeChild::SendAllPluginsCaptured()
     827             : {
     828           0 :   if (!mCanSend) {
     829           0 :     return false;
     830             :   }
     831           0 :   return PCompositorBridgeChild::SendAllPluginsCaptured();
     832             : }
     833             : 
     834             : PTextureChild*
     835           9 : CompositorBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
     836             :                                           const LayersBackend&,
     837             :                                           const TextureFlags&,
     838             :                                           const uint64_t&,
     839             :                                           const uint64_t& aSerial,
     840             :                                           const wr::MaybeExternalImageId& aExternalImageId)
     841             : {
     842           9 :   return TextureClient::CreateIPDLActor();
     843             : }
     844             : 
     845             : bool
     846           6 : CompositorBridgeChild::DeallocPTextureChild(PTextureChild* actor)
     847             : {
     848           6 :   return TextureClient::DestroyIPDLActor(actor);
     849             : }
     850             : 
     851             : mozilla::ipc::IPCResult
     852           0 : CompositorBridgeChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages)
     853             : {
     854           0 :   for (AsyncParentMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
     855           0 :     const AsyncParentMessageData& message = aMessages[i];
     856             : 
     857           0 :     switch (message.type()) {
     858             :       case AsyncParentMessageData::TOpNotifyNotUsed: {
     859           0 :         const OpNotifyNotUsed& op = message.get_OpNotifyNotUsed();
     860           0 :         NotifyNotUsed(op.TextureId(), op.fwdTransactionId());
     861           0 :         break;
     862             :       }
     863             :       default:
     864           0 :         NS_ERROR("unknown AsyncParentMessageData type");
     865           0 :         return IPC_FAIL_NO_REASON(this);
     866             :     }
     867             :   }
     868           0 :   return IPC_OK();
     869             : }
     870             : 
     871             : mozilla::ipc::IPCResult
     872           1 : CompositorBridgeChild::RecvObserveLayerUpdate(const uint64_t& aLayersId,
     873             :                                               const uint64_t& aEpoch,
     874             :                                               const bool& aActive)
     875             : {
     876             :   // This message is sent via the window compositor, not the tab compositor -
     877             :   // however it still has a layers id.
     878           1 :   MOZ_ASSERT(aLayersId);
     879           1 :   MOZ_ASSERT(XRE_IsParentProcess());
     880             : 
     881           2 :   if (RefPtr<dom::TabParent> tab = dom::TabParent::GetTabParentFromLayersId(aLayersId)) {
     882           1 :     tab->LayerTreeUpdate(aEpoch, aActive);
     883             :   }
     884           1 :   return IPC_OK();
     885             : }
     886             : 
     887             : void
     888          33 : CompositorBridgeChild::HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient)
     889             : {
     890          33 :   if (!aClient) {
     891           0 :     return;
     892             :   }
     893             : 
     894          33 :   if (!(aClient->GetFlags() & TextureFlags::RECYCLE)) {
     895          33 :     return;
     896             :   }
     897             : 
     898           0 :   aClient->SetLastFwdTransactionId(GetFwdTransactionId());
     899           0 :   mTexturesWaitingRecycled.Put(aClient->GetSerial(), aClient);
     900             : }
     901             : 
     902             : void
     903           0 : CompositorBridgeChild::NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId)
     904             : {
     905           0 :   if (auto entry = mTexturesWaitingRecycled.Lookup(aTextureId)) {
     906           0 :     if (aFwdTransactionId < entry.Data()->GetLastFwdTransactionId()) {
     907             :       // Released on host side, but client already requested newer use texture.
     908           0 :       return;
     909             :     }
     910           0 :     entry.Remove();
     911             :   }
     912             : }
     913             : 
     914             : void
     915           0 : CompositorBridgeChild::CancelWaitForRecycle(uint64_t aTextureId)
     916             : {
     917           0 :   mTexturesWaitingRecycled.Remove(aTextureId);
     918           0 : }
     919             : 
     920             : TextureClientPool*
     921           0 : CompositorBridgeChild::GetTexturePool(KnowsCompositor* aAllocator,
     922             :                                       SurfaceFormat aFormat,
     923             :                                       TextureFlags aFlags)
     924             : {
     925           0 :   for (size_t i = 0; i < mTexturePools.Length(); i++) {
     926           0 :     if (mTexturePools[i]->GetBackend() == aAllocator->GetCompositorBackendType() &&
     927           0 :         mTexturePools[i]->GetMaxTextureSize() == aAllocator->GetMaxTextureSize() &&
     928           0 :         mTexturePools[i]->GetFormat() == aFormat &&
     929           0 :         mTexturePools[i]->GetFlags() == aFlags) {
     930           0 :       return mTexturePools[i];
     931             :     }
     932             :   }
     933             : 
     934           0 :   mTexturePools.AppendElement(
     935           0 :       new TextureClientPool(aAllocator->GetCompositorBackendType(),
     936           0 :                             aAllocator->GetMaxTextureSize(),
     937             :                             aFormat,
     938           0 :                             gfx::gfxVars::TileSize(),
     939             :                             aFlags,
     940           0 :                             gfxPrefs::LayersTilePoolShrinkTimeout(),
     941           0 :                             gfxPrefs::LayersTilePoolClearTimeout(),
     942           0 :                             gfxPrefs::LayersTileInitialPoolSize(),
     943           0 :                             gfxPrefs::LayersTilePoolUnusedSize(),
     944           0 :                             this));
     945             : 
     946           0 :   return mTexturePools.LastElement();
     947             : }
     948             : 
     949             : void
     950           0 : CompositorBridgeChild::HandleMemoryPressure()
     951             : {
     952           0 :   for (size_t i = 0; i < mTexturePools.Length(); i++) {
     953           0 :     mTexturePools[i]->Clear();
     954             :   }
     955           0 : }
     956             : 
     957             : void
     958           0 : CompositorBridgeChild::ClearTexturePool()
     959             : {
     960           0 :   for (size_t i = 0; i < mTexturePools.Length(); i++) {
     961           0 :     mTexturePools[i]->Clear();
     962             :   }
     963           0 : }
     964             : 
     965             : FixedSizeSmallShmemSectionAllocator*
     966           0 : CompositorBridgeChild::GetTileLockAllocator()
     967             : {
     968           0 :   if (!IPCOpen()) {
     969           0 :     return nullptr;
     970             :   }
     971             : 
     972           0 :   if (!mSectionAllocator) {
     973           0 :     mSectionAllocator = new FixedSizeSmallShmemSectionAllocator(this);
     974             :   }
     975           0 :   return mSectionAllocator;
     976             : }
     977             : 
     978             : PTextureChild*
     979           9 : CompositorBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
     980             :                                      LayersBackend aLayersBackend,
     981             :                                      TextureFlags aFlags,
     982             :                                      uint64_t aSerial,
     983             :                                      wr::MaybeExternalImageId& aExternalImageId,
     984             :                                      nsIEventTarget* aTarget)
     985             : {
     986          18 :   PTextureChild* textureChild = AllocPTextureChild(
     987           9 :     aSharedData, aLayersBackend, aFlags, 0 /* FIXME */, aSerial, aExternalImageId);
     988             : 
     989             :   // Do the DOM labeling.
     990           9 :   if (aTarget) {
     991           1 :     SetEventTargetForActor(textureChild, aTarget);
     992             :   }
     993             : 
     994          18 :   return SendPTextureConstructor(
     995          18 :     textureChild, aSharedData, aLayersBackend, aFlags, 0 /* FIXME? */, aSerial, aExternalImageId);
     996             : }
     997             : 
     998             : bool
     999           1 : CompositorBridgeChild::AllocUnsafeShmem(size_t aSize,
    1000             :                                    ipc::SharedMemory::SharedMemoryType aType,
    1001             :                                    ipc::Shmem* aShmem)
    1002             : {
    1003           1 :   ShmemAllocated(this);
    1004           1 :   return PCompositorBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem);
    1005             : }
    1006             : 
    1007             : bool
    1008           0 : CompositorBridgeChild::AllocShmem(size_t aSize,
    1009             :                              ipc::SharedMemory::SharedMemoryType aType,
    1010             :                              ipc::Shmem* aShmem)
    1011             : {
    1012           0 :   ShmemAllocated(this);
    1013           0 :   return PCompositorBridgeChild::AllocShmem(aSize, aType, aShmem);
    1014             : }
    1015             : 
    1016             : bool
    1017           0 : CompositorBridgeChild::DeallocShmem(ipc::Shmem& aShmem)
    1018             : {
    1019           0 :   if (!mCanSend) {
    1020           0 :     return false;
    1021             :   }
    1022           0 :   return PCompositorBridgeChild::DeallocShmem(aShmem);
    1023             : }
    1024             : 
    1025             : widget::PCompositorWidgetChild*
    1026           0 : CompositorBridgeChild::AllocPCompositorWidgetChild(const CompositorWidgetInitData& aInitData)
    1027             : {
    1028             :   // We send the constructor manually.
    1029           0 :   MOZ_CRASH("Should not be called");
    1030             :   return nullptr;
    1031             : }
    1032             : 
    1033             : bool
    1034           0 : CompositorBridgeChild::DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor)
    1035             : {
    1036             : #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
    1037           0 :   delete aActor;
    1038           0 :   return true;
    1039             : #else
    1040             :   return false;
    1041             : #endif
    1042             : }
    1043             : 
    1044             : PAPZCTreeManagerChild*
    1045           1 : CompositorBridgeChild::AllocPAPZCTreeManagerChild(const uint64_t& aLayersId)
    1046             : {
    1047           1 :   APZCTreeManagerChild* child = new APZCTreeManagerChild();
    1048           1 :   child->AddRef();
    1049           1 :   if (aLayersId != 0) {
    1050           1 :     TabChild* tabChild = TabChild::GetFrom(aLayersId);
    1051           1 :     if (tabChild) {
    1052           1 :       SetEventTargetForActor(
    1053           2 :         child, tabChild->TabGroup()->EventTargetFor(TaskCategory::Other));
    1054           1 :       MOZ_ASSERT(child->GetActorEventTarget());
    1055             :     }
    1056             :   }
    1057             : 
    1058           1 :   return child;
    1059             : }
    1060             : 
    1061             : PAPZChild*
    1062           0 : CompositorBridgeChild::AllocPAPZChild(const uint64_t& aLayersId)
    1063             : {
    1064             :   // We send the constructor manually.
    1065           0 :   MOZ_CRASH("Should not be called");
    1066             :   return nullptr;
    1067             : }
    1068             : 
    1069             : bool
    1070           0 : CompositorBridgeChild::DeallocPAPZChild(PAPZChild* aActor)
    1071             : {
    1072           0 :   delete aActor;
    1073           0 :   return true;
    1074             : }
    1075             : 
    1076             : bool
    1077           0 : CompositorBridgeChild::DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor)
    1078             : {
    1079           0 :   APZCTreeManagerChild* parent = static_cast<APZCTreeManagerChild*>(aActor);
    1080           0 :   parent->Release();
    1081           0 :   return true;
    1082             : }
    1083             : 
    1084             : void
    1085          29 : CompositorBridgeChild::WillEndTransaction()
    1086             : {
    1087          29 :   ResetShmemCounter();
    1088          29 : }
    1089             : 
    1090             : PWebRenderBridgeChild*
    1091           0 : CompositorBridgeChild::AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId,
    1092             :                                                   const LayoutDeviceIntSize&,
    1093             :                                                   TextureFactoryIdentifier*,
    1094             :                                                   uint32_t *aIdNamespace)
    1095             : {
    1096           0 :   WebRenderBridgeChild* child = new WebRenderBridgeChild(aPipelineId);
    1097           0 :   child->AddIPDLReference();
    1098           0 :   return child;
    1099             : }
    1100             : 
    1101             : bool
    1102           0 : CompositorBridgeChild::DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor)
    1103             : {
    1104           0 :   WebRenderBridgeChild* child = static_cast<WebRenderBridgeChild*>(aActor);
    1105           0 :   child->ReleaseIPDLReference();
    1106           0 :   return true;
    1107             : }
    1108             : 
    1109             : uint64_t
    1110           9 : CompositorBridgeChild::GetNextResourceId()
    1111             : {
    1112           9 :   ++mResourceId;
    1113           9 :   MOZ_RELEASE_ASSERT(mResourceId != UINT32_MAX);
    1114             : 
    1115           9 :   uint64_t id = mIdNamespace;
    1116           9 :   id = (id << 32) | mResourceId;
    1117             : 
    1118           9 :   return id;
    1119             : }
    1120             : 
    1121             : wr::MaybeExternalImageId
    1122           9 : CompositorBridgeChild::GetNextExternalImageId()
    1123             : {
    1124           9 :   return Some(wr::ToExternalImageId(GetNextResourceId()));
    1125             : }
    1126             : 
    1127             : wr::PipelineId
    1128           0 : CompositorBridgeChild::GetNextPipelineId()
    1129             : {
    1130           0 :   return wr::AsPipelineId(GetNextResourceId());
    1131             : }
    1132             : 
    1133             : void
    1134           0 : CompositorBridgeChild::NotifyBeginAsyncPaint()
    1135             : {
    1136           0 :   MOZ_ASSERT(NS_IsMainThread());
    1137             : 
    1138           0 :   MonitorAutoLock lock(mPaintLock);
    1139             : 
    1140             :   // We must not be waiting for paints to complete yet. This would imply we
    1141             :   // started a new paint without waiting for a previous one, which could lead to
    1142             :   // incorrect rendering or IPDL deadlocks.
    1143           0 :   MOZ_ASSERT(!mIsWaitingForPaint);
    1144             : 
    1145           0 :   mOutstandingAsyncPaints++;
    1146           0 : }
    1147             : 
    1148             : void
    1149           0 : CompositorBridgeChild::NotifyFinishedAsyncPaint()
    1150             : {
    1151           0 :   MOZ_ASSERT(PaintThread::IsOnPaintThread());
    1152             : 
    1153           0 :   MonitorAutoLock lock(mPaintLock);
    1154             : 
    1155           0 :   mOutstandingAsyncPaints--;
    1156             : 
    1157             :   // It's possible that we painted so fast that the main thread never reached
    1158             :   // the code that starts delaying messages. If so, mIsWaitingForPaint will be
    1159             :   // false, and we can safely return.
    1160           0 :   if (mIsWaitingForPaint && mOutstandingAsyncPaints == 0) {
    1161           0 :     ResumeIPCAfterAsyncPaint();
    1162             : 
    1163             :     // Notify the main thread in case it's blocking. We do this unconditionally
    1164             :     // to avoid deadlocking.
    1165           0 :     lock.Notify();
    1166             :   }
    1167           0 : }
    1168             : 
    1169             : void
    1170          28 : CompositorBridgeChild::PostponeMessagesIfAsyncPainting()
    1171             : {
    1172          28 :   MOZ_ASSERT(NS_IsMainThread());
    1173             : 
    1174          56 :   MonitorAutoLock lock(mPaintLock);
    1175             : 
    1176          28 :   MOZ_ASSERT(!mIsWaitingForPaint);
    1177             : 
    1178          28 :   if (mOutstandingAsyncPaints > 0) {
    1179           0 :     mIsWaitingForPaint = true;
    1180           0 :     GetIPCChannel()->BeginPostponingSends();
    1181             :   }
    1182          28 : }
    1183             : 
    1184             : void
    1185           0 : CompositorBridgeChild::ResumeIPCAfterAsyncPaint()
    1186             : {
    1187             :   // Note: the caller is responsible for holding the lock.
    1188           0 :   mPaintLock.AssertCurrentThreadOwns();
    1189           0 :   MOZ_ASSERT(PaintThread::IsOnPaintThread());
    1190           0 :   MOZ_ASSERT(mOutstandingAsyncPaints == 0);
    1191           0 :   MOZ_ASSERT(mIsWaitingForPaint);
    1192             : 
    1193           0 :   mIsWaitingForPaint = false;
    1194             : 
    1195             :   // It's also possible that the channel has shut down already.
    1196           0 :   if (!mCanSend || mActorDestroyed) {
    1197           0 :     return;
    1198             :   }
    1199             : 
    1200           0 :   GetIPCChannel()->StopPostponingSends();
    1201             : }
    1202             : 
    1203             : void
    1204          29 : CompositorBridgeChild::FlushAsyncPaints()
    1205             : {
    1206          29 :   MOZ_ASSERT(NS_IsMainThread());
    1207             : 
    1208          58 :   MonitorAutoLock lock(mPaintLock);
    1209          29 :   while (mIsWaitingForPaint) {
    1210           0 :     lock.Wait();
    1211             :   }
    1212          29 : }
    1213             : 
    1214             : } // namespace layers
    1215             : } // namespace mozilla

Generated by: LCOV version 1.13