LCOV - code coverage report
Current view: top level - gfx/layers/wr - WebRenderBridgeParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 658 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 82 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 sw=4 ts=8 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/WebRenderBridgeParent.h"
       8             : 
       9             : #include "apz/src/AsyncPanZoomController.h"
      10             : #include "CompositableHost.h"
      11             : #include "gfxPrefs.h"
      12             : #include "GeckoProfiler.h"
      13             : #include "GLContext.h"
      14             : #include "GLContextProvider.h"
      15             : #include "mozilla/Range.h"
      16             : #include "mozilla/layers/AnimationHelper.h"
      17             : #include "mozilla/layers/APZCTreeManager.h"
      18             : #include "mozilla/layers/Compositor.h"
      19             : #include "mozilla/layers/CompositorBridgeParent.h"
      20             : #include "mozilla/layers/CompositorThread.h"
      21             : #include "mozilla/layers/CompositorVsyncScheduler.h"
      22             : #include "mozilla/layers/ImageBridgeParent.h"
      23             : #include "mozilla/layers/ImageDataSerializer.h"
      24             : #include "mozilla/layers/TextureHost.h"
      25             : #include "mozilla/layers/WebRenderCompositableHolder.h"
      26             : #include "mozilla/layers/WebRenderImageHost.h"
      27             : #include "mozilla/layers/WebRenderTextureHost.h"
      28             : #include "mozilla/TimeStamp.h"
      29             : #include "mozilla/Unused.h"
      30             : #include "mozilla/webrender/RenderThread.h"
      31             : #include "mozilla/widget/CompositorWidget.h"
      32             : 
      33           0 : bool is_in_main_thread()
      34             : {
      35           0 :   return NS_IsMainThread();
      36             : }
      37             : 
      38           0 : bool is_in_compositor_thread()
      39             : {
      40           0 :   return mozilla::layers::CompositorThreadHolder::IsInCompositorThread();
      41             : }
      42             : 
      43           0 : bool is_in_render_thread()
      44             : {
      45           0 :   return mozilla::wr::RenderThread::IsInRenderThread();
      46             : }
      47             : 
      48           0 : bool is_glcontext_egl(void* glcontext_ptr)
      49             : {
      50           0 :   MOZ_ASSERT(glcontext_ptr);
      51             : 
      52           0 :   mozilla::gl::GLContext* glcontext = reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
      53           0 :   if (!glcontext) {
      54           0 :     return false;
      55             :   }
      56           0 :   return glcontext->GetContextType() == mozilla::gl::GLContextType::EGL;
      57             : }
      58             : 
      59           0 : void gfx_critical_note(const char* msg)
      60             : {
      61           0 :   gfxCriticalNote << msg;
      62           0 : }
      63             : 
      64           0 : void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
      65             : {
      66           0 :   MOZ_ASSERT(glcontext_ptr);
      67             : 
      68           0 :   mozilla::gl::GLContext* glcontext = reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
      69           0 :   if (!glcontext) {
      70           0 :     return nullptr;
      71             :   }
      72           0 :   PRFuncPtr p = glcontext->LookupSymbol(procname);
      73           0 :   return reinterpret_cast<void*>(p);
      74             : }
      75             : 
      76             : namespace mozilla {
      77             : namespace layers {
      78             : 
      79             : using namespace mozilla::gfx;
      80             : 
      81             : class MOZ_STACK_CLASS AutoWebRenderBridgeParentAsyncMessageSender
      82             : {
      83             : public:
      84           0 :   explicit AutoWebRenderBridgeParentAsyncMessageSender(WebRenderBridgeParent* aWebRenderBridgeParent,
      85             :                                                        InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
      86           0 :     : mWebRenderBridgeParent(aWebRenderBridgeParent)
      87           0 :     , mActorsToDestroy(aDestroyActors)
      88             :   {
      89           0 :     mWebRenderBridgeParent->SetAboutToSendAsyncMessages();
      90           0 :   }
      91             : 
      92           0 :   ~AutoWebRenderBridgeParentAsyncMessageSender()
      93           0 :   {
      94           0 :     mWebRenderBridgeParent->SendPendingAsyncMessages();
      95           0 :     if (mActorsToDestroy) {
      96             :       // Destroy the actors after sending the async messages because the latter may contain
      97             :       // references to some actors.
      98           0 :       for (const auto& op : *mActorsToDestroy) {
      99           0 :         mWebRenderBridgeParent->DestroyActor(op);
     100             :       }
     101             :     }
     102           0 :   }
     103             : private:
     104             :   WebRenderBridgeParent* mWebRenderBridgeParent;
     105             :   InfallibleTArray<OpDestroy>* mActorsToDestroy;
     106             : };
     107             : 
     108             : /* static */ uint32_t WebRenderBridgeParent::sIdNameSpace = 0;
     109             : 
     110           0 : WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompositorBridge,
     111             :                                              const wr::PipelineId& aPipelineId,
     112             :                                              widget::CompositorWidget* aWidget,
     113             :                                              CompositorVsyncScheduler* aScheduler,
     114             :                                              RefPtr<wr::WebRenderAPI>&& aApi,
     115             :                                              RefPtr<WebRenderCompositableHolder>&& aHolder,
     116           0 :                                              RefPtr<CompositorAnimationStorage>&& aAnimStorage)
     117             :   : mCompositorBridge(aCompositorBridge)
     118             :   , mPipelineId(aPipelineId)
     119             :   , mWidget(aWidget)
     120             :   , mApi(aApi)
     121             :   , mCompositableHolder(aHolder)
     122             :   , mCompositorScheduler(aScheduler)
     123             :   , mAnimStorage(aAnimStorage)
     124             :   , mChildLayerObserverEpoch(0)
     125             :   , mParentLayerObserverEpoch(0)
     126             :   , mWrEpoch(0)
     127           0 :   , mIdNameSpace(AllocIdNameSpace())
     128             :   , mPaused(false)
     129             :   , mDestroyed(false)
     130           0 :   , mForceRendering(false)
     131             : {
     132           0 :   MOZ_ASSERT(mCompositableHolder);
     133           0 :   MOZ_ASSERT(mAnimStorage);
     134           0 :   mCompositableHolder->AddPipeline(mPipelineId);
     135           0 :   if (mWidget) {
     136           0 :     MOZ_ASSERT(!mCompositorScheduler);
     137           0 :     mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
     138             :   }
     139           0 : }
     140             : 
     141           0 : WebRenderBridgeParent::WebRenderBridgeParent()
     142             :   : mCompositorBridge(nullptr)
     143             :   , mChildLayerObserverEpoch(0)
     144             :   , mParentLayerObserverEpoch(0)
     145             :   , mWrEpoch(0)
     146           0 :   , mIdNameSpace(AllocIdNameSpace())
     147             :   , mPaused(false)
     148             :   , mDestroyed(true)
     149           0 :   , mForceRendering(false)
     150             : {
     151           0 : }
     152             : 
     153             : /* static */ WebRenderBridgeParent*
     154           0 : WebRenderBridgeParent::CeateDestroyed()
     155             : {
     156           0 :   return new WebRenderBridgeParent();
     157             : }
     158             : 
     159           0 : WebRenderBridgeParent::~WebRenderBridgeParent()
     160             : {
     161           0 : }
     162             : 
     163             : mozilla::ipc::IPCResult
     164           0 : WebRenderBridgeParent::RecvCreate(const gfx::IntSize& aSize)
     165             : {
     166           0 :   if (mDestroyed) {
     167           0 :     return IPC_OK();
     168             :   }
     169             : 
     170           0 :   MOZ_ASSERT(mApi);
     171             : 
     172             : #ifdef MOZ_WIDGET_ANDROID
     173             :   // XXX temporary hack.
     174             :   // XXX Remove it when APZ is supported.
     175             :   // XXX Broken by Dynamic Toolbar v3. See: Bug 1335895
     176             : //  RefPtr<UiCompositorControllerParent> uiController = UiCompositorControllerParent::GetFromRootLayerTreeId(/* Root Layer Tree ID */);
     177             : //  if (uiController) {
     178             : //    uiController->ToolbarAnimatorMessageFromCompositor(/*FIRST_PAINT*/ 5);
     179             : //  }
     180             : #endif
     181             : 
     182           0 :   return IPC_OK();
     183             : }
     184             : 
     185             : mozilla::ipc::IPCResult
     186           0 : WebRenderBridgeParent::RecvShutdown()
     187             : {
     188           0 :   return HandleShutdown();
     189             : }
     190             : 
     191             : mozilla::ipc::IPCResult
     192           0 : WebRenderBridgeParent::RecvShutdownSync()
     193             : {
     194           0 :   return HandleShutdown();
     195             : }
     196             : 
     197             : mozilla::ipc::IPCResult
     198           0 : WebRenderBridgeParent::HandleShutdown()
     199             : {
     200           0 :   Destroy();
     201           0 :   IProtocol* mgr = Manager();
     202           0 :   if (!Send__delete__(this)) {
     203           0 :     return IPC_FAIL_NO_REASON(mgr);
     204             :   }
     205           0 :   return IPC_OK();
     206             : }
     207             : 
     208             : void
     209           0 : WebRenderBridgeParent::Destroy()
     210             : {
     211           0 :   if (mDestroyed) {
     212           0 :     return;
     213             :   }
     214           0 :   mDestroyed = true;
     215           0 :   ClearResources();
     216             : }
     217             : 
     218             : mozilla::ipc::IPCResult
     219           0 : WebRenderBridgeParent::RecvAddImage(const wr::ImageKey& aImageKey,
     220             :                                     const gfx::IntSize& aSize,
     221             :                                     const uint32_t& aStride,
     222             :                                     const gfx::SurfaceFormat& aFormat,
     223             :                                     const ByteBuffer& aBuffer)
     224             : {
     225           0 :   if (mDestroyed) {
     226           0 :     return IPC_OK();
     227             :   }
     228             : 
     229             :   // Check if key is obsoleted.
     230           0 :   if (aImageKey.mNamespace != mIdNameSpace) {
     231           0 :     return IPC_OK();
     232             :   }
     233             : 
     234           0 :   MOZ_ASSERT(mApi);
     235           0 :   MOZ_ASSERT(mActiveImageKeys.find(wr::AsUint64(aImageKey)) == mActiveImageKeys.end());
     236             : 
     237           0 :   wr::ImageDescriptor descriptor(aSize, aStride, aFormat);
     238           0 :   mActiveImageKeys.insert(wr::AsUint64(aImageKey));
     239           0 :   mApi->AddImage(aImageKey, descriptor,
     240           0 :                  aBuffer.AsSlice());
     241             : 
     242           0 :   return IPC_OK();
     243             : }
     244             : 
     245             : mozilla::ipc::IPCResult
     246           0 : WebRenderBridgeParent::RecvAddBlobImage(const wr::ImageKey& aImageKey,
     247             :                                         const gfx::IntSize& aSize,
     248             :                                         const uint32_t& aStride,
     249             :                                         const gfx::SurfaceFormat& aFormat,
     250             :                                         const ByteBuffer& aBuffer)
     251             : {
     252           0 :   if (mDestroyed) {
     253           0 :     return IPC_OK();
     254             :   }
     255             : 
     256             :   // Check if key is obsoleted.
     257           0 :   if (aImageKey.mNamespace != mIdNameSpace) {
     258           0 :     return IPC_OK();
     259             :   }
     260             : 
     261           0 :   MOZ_ASSERT(mApi);
     262           0 :   MOZ_ASSERT(mActiveImageKeys.find(wr::AsUint64(aImageKey)) == mActiveImageKeys.end());
     263             : 
     264           0 :   wr::ImageDescriptor descriptor(aSize, aStride, aFormat);
     265           0 :   mActiveImageKeys.insert(wr::AsUint64(aImageKey));
     266           0 :   mApi->AddBlobImage(aImageKey, descriptor,
     267           0 :                      aBuffer.AsSlice());
     268             : 
     269           0 :   return IPC_OK();
     270             : }
     271             : 
     272             : mozilla::ipc::IPCResult
     273           0 : WebRenderBridgeParent::RecvAddRawFont(const wr::FontKey& aFontKey,
     274             :                                       const ByteBuffer& aBuffer,
     275             :                                       const uint32_t& aFontIndex)
     276             : {
     277           0 :   if (mDestroyed) {
     278           0 :     return IPC_OK();
     279             :   }
     280             : 
     281             :   // Check if key is obsoleted.
     282           0 :   if (aFontKey.mNamespace != mIdNameSpace) {
     283           0 :     return IPC_OK();
     284             :   }
     285             : 
     286           0 :   MOZ_ASSERT(mApi);
     287           0 :   MOZ_ASSERT(mFontKeys.find(wr::AsUint64(aFontKey)) == mFontKeys.end());
     288             : 
     289           0 :   auto slice = aBuffer.AsSlice();
     290           0 :   mFontKeys.insert(wr::AsUint64(aFontKey));
     291           0 :   mApi->AddRawFont(aFontKey, slice, aFontIndex);
     292             : 
     293           0 :   return IPC_OK();
     294             : }
     295             : 
     296             : mozilla::ipc::IPCResult
     297           0 : WebRenderBridgeParent::RecvDeleteFont(const wr::FontKey& aFontKey)
     298             : {
     299           0 :   if (mDestroyed) {
     300           0 :     return IPC_OK();
     301             :   }
     302           0 :   MOZ_ASSERT(mApi);
     303             : 
     304             :   // Check if key is obsoleted.
     305           0 :   if (aFontKey.mNamespace != mIdNameSpace) {
     306           0 :     return IPC_OK();
     307             :   }
     308             : 
     309           0 :   if (mFontKeys.find(wr::AsUint64(aFontKey)) != mFontKeys.end()) {
     310           0 :     mFontKeys.erase(wr::AsUint64(aFontKey));
     311           0 :     mApi->DeleteFont(aFontKey);
     312             :   } else {
     313           0 :     MOZ_ASSERT_UNREACHABLE("invalid FontKey");
     314             :   }
     315             : 
     316           0 :   return IPC_OK();
     317             : }
     318             : 
     319             : mozilla::ipc::IPCResult
     320           0 : WebRenderBridgeParent::RecvUpdateImage(const wr::ImageKey& aImageKey,
     321             :                                        const gfx::IntSize& aSize,
     322             :                                        const gfx::SurfaceFormat& aFormat,
     323             :                                        const ByteBuffer& aBuffer)
     324             : {
     325           0 :   if (mDestroyed) {
     326           0 :     return IPC_OK();
     327             :   }
     328           0 :   MOZ_ASSERT(mApi);
     329             : 
     330             :   // Check if key is obsoleted.
     331           0 :   if (aImageKey.mNamespace != mIdNameSpace) {
     332           0 :     return IPC_OK();
     333             :   }
     334             : 
     335           0 :   wr::ImageDescriptor descriptor(aSize, aFormat);
     336           0 :   mApi->UpdateImageBuffer(aImageKey, descriptor, aBuffer.AsSlice());
     337             : 
     338           0 :   return IPC_OK();
     339             : }
     340             : 
     341             : mozilla::ipc::IPCResult
     342           0 : WebRenderBridgeParent::RecvDeleteImage(const wr::ImageKey& aImageKey)
     343             : {
     344           0 :   if (mDestroyed) {
     345           0 :     return IPC_OK();
     346             :   }
     347           0 :   MOZ_ASSERT(mApi);
     348             : 
     349             :   // Check if key is obsoleted.
     350           0 :   if (aImageKey.mNamespace != mIdNameSpace) {
     351           0 :     return IPC_OK();
     352             :   }
     353             : 
     354           0 :   if (mActiveImageKeys.find(wr::AsUint64(aImageKey)) != mActiveImageKeys.end()) {
     355           0 :     mActiveImageKeys.erase(wr::AsUint64(aImageKey));
     356           0 :     mKeysToDelete.push_back(aImageKey);
     357             :   } else {
     358           0 :     MOZ_ASSERT_UNREACHABLE("invalid ImageKey");
     359             :   }
     360           0 :   return IPC_OK();
     361             : }
     362             : 
     363             : mozilla::ipc::IPCResult
     364           0 : WebRenderBridgeParent::RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds)
     365             : {
     366           0 :   if (mDestroyed) {
     367           0 :     return IPC_OK();
     368             :   }
     369             : 
     370           0 :   for (uint32_t i = 0; i < aIds.Length(); i++) {
     371           0 :     if (mActiveAnimations.find(aIds[i]) != mActiveAnimations.end()) {
     372           0 :       mAnimStorage->ClearById(aIds[i]);
     373           0 :       mActiveAnimations.erase(aIds[i]);
     374             :     } else {
     375           0 :       NS_ERROR("Tried to delete invalid animation");
     376             :     }
     377             :   }
     378             : 
     379           0 :   return IPC_OK();
     380             : }
     381             : 
     382             : 
     383             : mozilla::ipc::IPCResult
     384           0 : WebRenderBridgeParent::RecvDPBegin(const gfx::IntSize& aSize)
     385             : {
     386           0 :   if (mDestroyed) {
     387           0 :     return IPC_OK();
     388             :   }
     389           0 :   return IPC_OK();
     390             : }
     391             : 
     392             : void
     393           0 : WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
     394             :                                  InfallibleTArray<WebRenderParentCommand>&& aCommands,
     395             :                                  InfallibleTArray<OpDestroy>&& aToDestroy,
     396             :                                  const uint64_t& aFwdTransactionId,
     397             :                                  const uint64_t& aTransactionId,
     398             :                                  const WrSize& aContentSize,
     399             :                                  const ByteBuffer& dl,
     400             :                                  const WrBuiltDisplayListDescriptor& dlDesc,
     401             :                                  const WebRenderScrollData& aScrollData,
     402             :                                  const uint32_t& aIdNameSpace)
     403             : {
     404           0 :   AutoProfilerTracing tracing("Paint", "DPTransaction");
     405           0 :   UpdateFwdTransactionId(aFwdTransactionId);
     406           0 :   AutoClearReadLocks clearLocks(mReadLocks);
     407             : 
     408           0 :   if (mDestroyed) {
     409           0 :     for (const auto& op : aToDestroy) {
     410           0 :       DestroyActor(op);
     411             :     }
     412           0 :     return;
     413             :   }
     414             :   // This ensures that destroy operations are always processed. It is not safe
     415             :   // to early-return from RecvDPEnd without doing so.
     416           0 :   AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
     417             : 
     418           0 :   ++mWrEpoch; // Update webrender epoch
     419           0 :   ProcessWebRenderCommands(aSize, aCommands, wr::NewEpoch(mWrEpoch),
     420           0 :                            aContentSize, dl, dlDesc, aIdNameSpace);
     421           0 :   HoldPendingTransactionId(mWrEpoch, aTransactionId);
     422             : 
     423           0 :   mScrollData = aScrollData;
     424           0 :   UpdateAPZ();
     425             : 
     426           0 :   if (mIdNameSpace != aIdNameSpace) {
     427             :     // Pretend we composited since someone is wating for this event,
     428             :     // though DisplayList was not pushed to webrender.
     429           0 :     TimeStamp now = TimeStamp::Now();
     430           0 :     mCompositorBridge->DidComposite(wr::AsUint64(mPipelineId), now, now);
     431             :   }
     432             : }
     433             : 
     434             : CompositorBridgeParent*
     435           0 : WebRenderBridgeParent::GetRootCompositorBridgeParent() const
     436             : {
     437           0 :   if (!mCompositorBridge) {
     438           0 :     return nullptr;
     439             :   }
     440             : 
     441           0 :   if (mWidget) {
     442             :     // This WebRenderBridgeParent is attached to the root
     443             :     // CompositorBridgeParent.
     444           0 :     return static_cast<CompositorBridgeParent*>(mCompositorBridge);
     445             :   }
     446             : 
     447             :   // Otherwise, this WebRenderBridgeParent is attached to a
     448             :   // CrossProcessCompositorBridgeParent so we have an extra level of
     449             :   // indirection to unravel.
     450             :   CompositorBridgeParent::LayerTreeState* lts =
     451           0 :       CompositorBridgeParent::GetIndirectShadowTree(GetLayersId());
     452           0 :   MOZ_ASSERT(lts);
     453           0 :   return lts->mParent;
     454             : }
     455             : 
     456             : void
     457           0 : WebRenderBridgeParent::UpdateAPZ()
     458             : {
     459           0 :   CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
     460           0 :   if (!cbp) {
     461           0 :     return;
     462             :   }
     463           0 :   uint64_t rootLayersId = cbp->RootLayerTreeId();
     464           0 :   RefPtr<WebRenderBridgeParent> rootWrbp = cbp->GetWebRenderBridgeParent();
     465           0 :   if (!rootWrbp) {
     466           0 :     return;
     467             :   }
     468           0 :   if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
     469           0 :     apzc->UpdateFocusState(rootLayersId, GetLayersId(),
     470           0 :                            mScrollData.GetFocusTarget());
     471           0 :     apzc->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(),
     472           0 :         mScrollData.IsFirstPaint(), GetLayersId(),
     473           0 :         mScrollData.GetPaintSequenceNumber());
     474             :   }
     475             : }
     476             : 
     477             : bool
     478           0 : WebRenderBridgeParent::PushAPZStateToWR(nsTArray<WrTransformProperty>& aTransformArray)
     479             : {
     480           0 :   CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
     481           0 :   if (!cbp) {
     482           0 :     return false;
     483             :   }
     484           0 :   if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
     485           0 :     TimeStamp animationTime = cbp->GetTestingTimeStamp().valueOr(
     486           0 :         mCompositorScheduler->GetLastComposeTime());
     487           0 :     TimeDuration frameInterval = cbp->GetVsyncInterval();
     488             :     // As with the non-webrender codepath in AsyncCompositionManager, we want to
     489             :     // use the timestamp for the next vsync when advancing animations.
     490           0 :     if (frameInterval != TimeDuration::Forever()) {
     491           0 :       animationTime += frameInterval;
     492             :     }
     493           0 :     return apzc->PushStateToWR(mApi, animationTime, aTransformArray);
     494             :   }
     495           0 :   return false;
     496             : }
     497             : 
     498             : const WebRenderScrollData&
     499           0 : WebRenderBridgeParent::GetScrollData() const
     500             : {
     501           0 :   MOZ_ASSERT(mozilla::layers::CompositorThreadHolder::IsInCompositorThread());
     502           0 :   return mScrollData;
     503             : }
     504             : 
     505             : mozilla::ipc::IPCResult
     506           0 : WebRenderBridgeParent::RecvDPEnd(const gfx::IntSize& aSize,
     507             :                                  InfallibleTArray<WebRenderParentCommand>&& aCommands,
     508             :                                  InfallibleTArray<OpDestroy>&& aToDestroy,
     509             :                                  const uint64_t& aFwdTransactionId,
     510             :                                  const uint64_t& aTransactionId,
     511             :                                  const WrSize& aContentSize,
     512             :                                  const ByteBuffer& dl,
     513             :                                  const WrBuiltDisplayListDescriptor& dlDesc,
     514             :                                  const WebRenderScrollData& aScrollData,
     515             :                                  const uint32_t& aIdNameSpace)
     516             : {
     517           0 :   if (mDestroyed) {
     518           0 :     return IPC_OK();
     519             :   }
     520           0 :   HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
     521           0 :               aContentSize, dl, dlDesc, aScrollData, aIdNameSpace);
     522           0 :   return IPC_OK();
     523             : }
     524             : 
     525             : mozilla::ipc::IPCResult
     526           0 : WebRenderBridgeParent::RecvDPSyncEnd(const gfx::IntSize &aSize,
     527             :                                      InfallibleTArray<WebRenderParentCommand>&& aCommands,
     528             :                                      InfallibleTArray<OpDestroy>&& aToDestroy,
     529             :                                      const uint64_t& aFwdTransactionId,
     530             :                                      const uint64_t& aTransactionId,
     531             :                                      const WrSize& aContentSize,
     532             :                                      const ByteBuffer& dl,
     533             :                                      const WrBuiltDisplayListDescriptor& dlDesc,
     534             :                                      const WebRenderScrollData& aScrollData,
     535             :                                      const uint32_t& aIdNameSpace)
     536             : {
     537           0 :   if (mDestroyed) {
     538           0 :     return IPC_OK();
     539             :   }
     540           0 :   HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
     541           0 :               aContentSize, dl, dlDesc, aScrollData, aIdNameSpace);
     542           0 :   return IPC_OK();
     543             : }
     544             : 
     545             : mozilla::ipc::IPCResult
     546           0 : WebRenderBridgeParent::RecvParentCommands(nsTArray<WebRenderParentCommand>&& aCommands)
     547             : {
     548           0 :   if (mDestroyed) {
     549           0 :     return IPC_OK();
     550             :   }
     551           0 :   ProcessWebRenderParentCommands(aCommands);
     552           0 :   return IPC_OK();
     553             : }
     554             : 
     555             : void
     556           0 : WebRenderBridgeParent::ProcessWebRenderParentCommands(InfallibleTArray<WebRenderParentCommand>& aCommands)
     557             : {
     558           0 :   for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
     559           0 :     const WebRenderParentCommand& cmd = aCommands[i];
     560           0 :     switch (cmd.type()) {
     561             :       case WebRenderParentCommand::TOpAddExternalImage: {
     562           0 :         const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
     563           0 :         Range<const wr::ImageKey> keys(&op.key(), 1);
     564             :         // Check if key is obsoleted.
     565           0 :         if (keys[0].mNamespace != mIdNameSpace) {
     566           0 :           break;
     567             :         }
     568           0 :         MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(op.externalImageId())).get());
     569           0 :         MOZ_ASSERT(mActiveImageKeys.find(wr::AsUint64(keys[0])) == mActiveImageKeys.end());
     570           0 :         mActiveImageKeys.insert(wr::AsUint64(keys[0]));
     571             : 
     572           0 :         RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(op.externalImageId()));
     573           0 :         if (!host) {
     574           0 :           NS_ERROR("CompositableHost does not exist");
     575           0 :           break;
     576             :         }
     577           0 :         TextureHost* texture = host->GetAsTextureHostForComposite();
     578           0 :         if (!texture) {
     579           0 :           NS_ERROR("TextureHost does not exist");
     580           0 :           break;
     581             :         }
     582           0 :         WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
     583           0 :         if (wrTexture) {
     584           0 :           wrTexture->AddWRImage(mApi, keys, wrTexture->GetExternalImageKey());
     585           0 :           break;
     586             :         }
     587           0 :         RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
     588           0 :         if (!dSurf) {
     589           0 :           NS_ERROR("TextureHost does not return DataSourceSurface");
     590           0 :           break;
     591             :         }
     592             : 
     593             :         DataSourceSurface::MappedSurface map;
     594           0 :         if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
     595           0 :           NS_ERROR("DataSourceSurface failed to map");
     596           0 :           break;
     597             :         }
     598             : 
     599           0 :         IntSize size = dSurf->GetSize();
     600           0 :         wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
     601           0 :         auto slice = Range<uint8_t>(map.mData, size.height * map.mStride);
     602           0 :         mApi->AddImage(keys[0], descriptor, slice);
     603             : 
     604           0 :         dSurf->Unmap();
     605           0 :         break;
     606             :       }
     607             :       case WebRenderParentCommand::TOpUpdateAsyncImagePipeline: {
     608           0 :         const OpUpdateAsyncImagePipeline& op = cmd.get_OpUpdateAsyncImagePipeline();
     609           0 :         mCompositableHolder->UpdateAsyncImagePipeline(op.pipelineId(),
     610           0 :                                                       op.scBounds(),
     611           0 :                                                       op.scTransform(),
     612           0 :                                                       op.scaleToSize(),
     613             :                                                       op.filter(),
     614           0 :                                                       op.mixBlendMode());
     615           0 :         break;
     616             :       }
     617             :       case WebRenderParentCommand::TCompositableOperation: {
     618           0 :         if (!ReceiveCompositableUpdate(cmd.get_CompositableOperation())) {
     619           0 :           NS_ERROR("ReceiveCompositableUpdate failed");
     620             :         }
     621           0 :         break;
     622             :       }
     623             :       case WebRenderParentCommand::TOpAddCompositorAnimations: {
     624           0 :         const OpAddCompositorAnimations& op = cmd.get_OpAddCompositorAnimations();
     625           0 :         CompositorAnimations data(Move(op.data()));
     626           0 :         if (data.animations().Length()) {
     627           0 :           mAnimStorage->SetAnimations(data.id(), data.animations());
     628           0 :           mActiveAnimations.insert(data.id());
     629             :           // Store the default opacity
     630           0 :           if (op.opacity().type() == OptionalOpacity::Tfloat) {
     631           0 :             mAnimStorage->SetAnimatedValue(data.id(), op.opacity().get_float());
     632             :           }
     633             :           // Store the default transform
     634           0 :           if (op.transform().type() == OptionalTransform::TMatrix4x4) {
     635           0 :             Matrix4x4 transform(Move(op.transform().get_Matrix4x4()));
     636           0 :             mAnimStorage->SetAnimatedValue(data.id(), Move(transform));
     637             :           }
     638             :         }
     639           0 :         break;
     640             :       }
     641             :       default: {
     642             :         // other commands are handle on the child
     643           0 :         break;
     644             :       }
     645             :     }
     646             :   }
     647           0 : }
     648             : 
     649             : void
     650           0 : WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
     651             :                                                 InfallibleTArray<WebRenderParentCommand>& aCommands, const wr::Epoch& aEpoch,
     652             :                                                 const WrSize& aContentSize, const ByteBuffer& dl,
     653             :                                                 const WrBuiltDisplayListDescriptor& dlDesc,
     654             :                                                 const uint32_t& aIdNameSpace)
     655             : {
     656           0 :   mCompositableHolder->SetCompositionTime(TimeStamp::Now());
     657           0 :   ProcessWebRenderParentCommands(aCommands);
     658             : 
     659             :   // The command is obsoleted.
     660             :   // Do not set the command to webrender since it causes crash in webrender.
     661           0 :   if (mIdNameSpace != aIdNameSpace) {
     662           0 :     return;
     663             :   }
     664             : 
     665           0 :   if (mWidget) {
     666           0 :     LayoutDeviceIntSize size = mWidget->GetClientSize();
     667           0 :     mApi->SetWindowParameters(size);
     668             :   }
     669           0 :   gfx::Color color = mWidget ? gfx::Color(0.3f, 0.f, 0.f, 1.f) : gfx::Color(0.f, 0.f, 0.f, 0.f);
     670           0 :   mApi->SetRootDisplayList(color, aEpoch, LayerSize(aSize.width, aSize.height),
     671             :                            mPipelineId, aContentSize,
     672           0 :                            dlDesc, dl.mData, dl.mLength);
     673             : 
     674           0 :   ScheduleComposition();
     675           0 :   DeleteOldImages();
     676             : 
     677           0 :   if (ShouldParentObserveEpoch()) {
     678           0 :     mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
     679             :   }
     680             : }
     681             : 
     682             : mozilla::ipc::IPCResult
     683           0 : WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture)
     684             : {
     685           0 :   if (mDestroyed) {
     686           0 :     return IPC_OK();
     687             :   }
     688           0 :   MOZ_ASSERT(!mPaused);
     689             : 
     690           0 :   RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
     691           0 :   if (!texture) {
     692             :     // We kill the content process rather than have it continue with an invalid
     693             :     // snapshot, that may be too harsh and we could decide to return some sort
     694             :     // of error to the child process and let it deal with it...
     695           0 :     return IPC_FAIL_NO_REASON(this);
     696             :   }
     697             : 
     698             :   // XXX Add other TextureHost supports.
     699             :   // Only BufferTextureHost is supported now.
     700           0 :   BufferTextureHost* bufferTexture = texture->AsBufferTextureHost();
     701           0 :   if (!bufferTexture) {
     702             :     // We kill the content process rather than have it continue with an invalid
     703             :     // snapshot, that may be too harsh and we could decide to return some sort
     704             :     // of error to the child process and let it deal with it...
     705           0 :     return IPC_FAIL_NO_REASON(this);
     706             :   }
     707             : 
     708           0 :   MOZ_ASSERT(bufferTexture->GetBufferDescriptor().type() == BufferDescriptor::TRGBDescriptor);
     709           0 :   DebugOnly<uint32_t> stride = ImageDataSerializer::GetRGBStride(bufferTexture->GetBufferDescriptor().get_RGBDescriptor());
     710           0 :   uint8_t* buffer = bufferTexture->GetBuffer();
     711           0 :   IntSize size = bufferTexture->GetSize();
     712             : 
     713             :   // We only support B8G8R8A8 for now.
     714           0 :   MOZ_ASSERT(buffer);
     715           0 :   MOZ_ASSERT(bufferTexture->GetFormat() == SurfaceFormat::B8G8R8A8);
     716           0 :   uint32_t buffer_size = size.width * size.height * 4;
     717             : 
     718             :   // Assert the stride of the buffer is what webrender expects
     719           0 :   MOZ_ASSERT((uint32_t)(size.width * 4) == stride);
     720             : 
     721           0 :   mForceRendering = true;
     722             : 
     723           0 :   if (mCompositorScheduler->NeedsComposite()) {
     724           0 :     mCompositorScheduler->CancelCurrentCompositeTask();
     725           0 :     mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr);
     726             :   }
     727             : 
     728           0 :   mApi->Readback(size, buffer, buffer_size);
     729             : 
     730           0 :   mForceRendering = false;
     731             : 
     732           0 :   return IPC_OK();
     733             : }
     734             : 
     735             : mozilla::ipc::IPCResult
     736           0 : WebRenderBridgeParent::RecvAddPipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId,
     737             :                                                              const CompositableHandle& aHandle)
     738             : {
     739           0 :   if (mDestroyed) {
     740           0 :     return IPC_OK();
     741             :   }
     742             : 
     743           0 :   MOZ_ASSERT(!mAsyncCompositables.Get(wr::AsUint64(aPipelineId)).get());
     744             : 
     745           0 :   RefPtr<ImageBridgeParent> imageBridge = ImageBridgeParent::GetInstance(OtherPid());
     746           0 :   if (!imageBridge) {
     747           0 :      return IPC_FAIL_NO_REASON(this);
     748             :   }
     749           0 :   RefPtr<CompositableHost> host = imageBridge->FindCompositable(aHandle);
     750           0 :   if (!host) {
     751           0 :     return IPC_FAIL_NO_REASON(this);
     752             :   }
     753           0 :   MOZ_ASSERT(host->AsWebRenderImageHost());
     754           0 :   WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
     755           0 :   if (!wrHost) {
     756           0 :     return IPC_OK();
     757             :   }
     758             : 
     759           0 :   wrHost->SetWrBridge(this);
     760           0 :   mAsyncCompositables.Put(wr::AsUint64(aPipelineId), wrHost);
     761           0 :   mCompositableHolder->AddAsyncImagePipeline(aPipelineId, wrHost);
     762             : 
     763           0 :   return IPC_OK();
     764             : }
     765             : 
     766             : mozilla::ipc::IPCResult
     767           0 : WebRenderBridgeParent::RecvRemovePipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId)
     768             : {
     769           0 :   if (mDestroyed) {
     770           0 :     return IPC_OK();
     771             :   }
     772             : 
     773           0 :   WebRenderImageHost* wrHost = mAsyncCompositables.Get(wr::AsUint64(aPipelineId)).get();
     774           0 :   if (!wrHost) {
     775           0 :     return IPC_OK();
     776             :   }
     777             : 
     778           0 :   wrHost->ClearWrBridge();
     779           0 :   mCompositableHolder->RemoveAsyncImagePipeline(mApi, aPipelineId);
     780           0 :   mAsyncCompositables.Remove(wr::AsUint64(aPipelineId));
     781           0 :   return IPC_OK();
     782             : }
     783             : 
     784             : mozilla::ipc::IPCResult
     785           0 : WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const ExternalImageId& aImageId,
     786             :                                                              const CompositableHandle& aHandle)
     787             : {
     788           0 :   if (mDestroyed) {
     789           0 :     return IPC_OK();
     790             :   }
     791           0 :   MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
     792             : 
     793           0 :   RefPtr<CompositableHost> host = FindCompositable(aHandle);
     794           0 :   MOZ_ASSERT(host->AsWebRenderImageHost());
     795           0 :   WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
     796           0 :   if (!wrHost) {
     797           0 :     return IPC_OK();
     798             :   }
     799             : 
     800           0 :   wrHost->SetWrBridge(this);
     801           0 :   mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
     802             : 
     803           0 :   return IPC_OK();
     804             : }
     805             : 
     806             : mozilla::ipc::IPCResult
     807           0 : WebRenderBridgeParent::RecvRemoveExternalImageId(const ExternalImageId& aImageId)
     808             : {
     809           0 :   if (mDestroyed) {
     810           0 :     return IPC_OK();
     811             :   }
     812           0 :   WebRenderImageHost* wrHost = mExternalImageIds.Get(wr::AsUint64(aImageId)).get();
     813           0 :   if (!wrHost) {
     814           0 :     return IPC_OK();
     815             :   }
     816             : 
     817           0 :   wrHost->ClearWrBridge();
     818           0 :   mExternalImageIds.Remove(wr::AsUint64(aImageId));
     819             : 
     820           0 :   return IPC_OK();
     821             : }
     822             : 
     823             : mozilla::ipc::IPCResult
     824           0 : WebRenderBridgeParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch)
     825             : {
     826           0 :   if (mDestroyed) {
     827           0 :     return IPC_OK();
     828             :   }
     829           0 :   mChildLayerObserverEpoch = aLayerObserverEpoch;
     830           0 :   return IPC_OK();
     831             : }
     832             : 
     833             : mozilla::ipc::IPCResult
     834           0 : WebRenderBridgeParent::RecvClearCachedResources()
     835             : {
     836           0 :   if (mDestroyed) {
     837           0 :     return IPC_OK();
     838             :   }
     839           0 :   mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), false);
     840             : 
     841             :   // Clear resources
     842             :   // XXX Can we clear more resources?
     843           0 :   ++mWrEpoch; // Update webrender epoch
     844           0 :   mApi->ClearRootDisplayList(wr::NewEpoch(mWrEpoch), mPipelineId);
     845             :   // Schedule composition to clean up Pipeline
     846           0 :   mCompositorScheduler->ScheduleComposition();
     847             :   // Remove animations.
     848           0 :   for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
     849           0 :     mAnimStorage->ClearById(*iter);
     850             :   }
     851           0 :   mActiveAnimations.clear();
     852           0 :   return IPC_OK();
     853             : }
     854             : 
     855             : void
     856           0 : WebRenderBridgeParent::UpdateWebRender(CompositorVsyncScheduler* aScheduler,
     857             :                                        wr::WebRenderAPI* aApi,
     858             :                                        WebRenderCompositableHolder* aHolder,
     859             :                                        CompositorAnimationStorage* aAnimStorage)
     860             : {
     861           0 :   MOZ_ASSERT(!mWidget);
     862           0 :   MOZ_ASSERT(aScheduler);
     863           0 :   MOZ_ASSERT(aApi);
     864           0 :   MOZ_ASSERT(aHolder);
     865           0 :   MOZ_ASSERT(aAnimStorage);
     866             : 
     867           0 :   if (mDestroyed) {
     868           0 :     return;
     869             :   }
     870             : 
     871             :   // Update id name space to identify obsoleted keys.
     872             :   // Since usage of invalid keys could cause crash in webrender.
     873           0 :   mIdNameSpace = AllocIdNameSpace();
     874             :   // XXX Remove it when webrender supports sharing/moving Keys between different webrender instances.
     875             :   // XXX It requests client to update/reallocate webrender related resources,
     876             :   // but parent side does not wait end of the update.
     877             :   // The code could become simpler if we could serialise old keys deallocation and new keys allocation.
     878             :   // But we do not do it, it is because client side deallocate old layers/webrender keys
     879             :   // after new layers/webrender keys allocation.
     880             :   // Without client side's layout refactoring, we could not finish all old layers/webrender keys removals
     881             :   // before new layer/webrender keys allocation. In future, we could address the problem.
     882           0 :   Unused << SendWrUpdated(mIdNameSpace);
     883           0 :   CompositorBridgeParentBase* cBridge = mCompositorBridge;
     884             :   // XXX Stop to clear resources if webreder supports resources sharing between different webrender instances.
     885           0 :   ClearResources();
     886           0 :   mCompositorBridge = cBridge;
     887           0 :   mCompositorScheduler = aScheduler;
     888           0 :   mApi = aApi;
     889           0 :   mCompositableHolder = aHolder;
     890           0 :   mAnimStorage = aAnimStorage;
     891             : 
     892           0 :   ++mWrEpoch; // Update webrender epoch
     893             :   // Register pipeline to updated CompositableHolder.
     894           0 :   mCompositableHolder->AddPipeline(mPipelineId);
     895             : }
     896             : 
     897             : mozilla::ipc::IPCResult
     898           0 : WebRenderBridgeParent::RecvForceComposite()
     899             : {
     900           0 :   if (mDestroyed) {
     901           0 :     return IPC_OK();
     902             :   }
     903           0 :   ScheduleComposition();
     904           0 :   return IPC_OK();
     905             : }
     906             : 
     907             : already_AddRefed<AsyncPanZoomController>
     908           0 : WebRenderBridgeParent::GetTargetAPZC(const FrameMetrics::ViewID& aScrollId)
     909             : {
     910           0 :   RefPtr<AsyncPanZoomController> apzc;
     911           0 :   if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
     912           0 :     if (RefPtr<APZCTreeManager> apzctm = cbp->GetAPZCTreeManager()) {
     913           0 :       apzc = apzctm->GetTargetAPZC(GetLayersId(), aScrollId);
     914             :     }
     915             :   }
     916           0 :   return apzc.forget();
     917             : }
     918             : 
     919             : mozilla::ipc::IPCResult
     920           0 : WebRenderBridgeParent::RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
     921             :                                                   nsTArray<ScrollableLayerGuid>&& aTargets)
     922             : {
     923           0 :   if (mDestroyed) {
     924           0 :     return IPC_OK();
     925             :   }
     926           0 :   mCompositorBridge->SetConfirmedTargetAPZC(GetLayersId(), aBlockId, aTargets);
     927           0 :   return IPC_OK();
     928             : }
     929             : 
     930             : mozilla::ipc::IPCResult
     931           0 : WebRenderBridgeParent::RecvSetTestSampleTime(const TimeStamp& aTime)
     932             : {
     933           0 :   if (!mCompositorBridge->SetTestSampleTime(GetLayersId(), aTime)) {
     934           0 :     return IPC_FAIL_NO_REASON(this);
     935             :   }
     936           0 :   return IPC_OK();
     937             : }
     938             : 
     939             : mozilla::ipc::IPCResult
     940           0 : WebRenderBridgeParent::RecvLeaveTestMode()
     941             : {
     942           0 :   mCompositorBridge->LeaveTestMode(GetLayersId());
     943           0 :   return IPC_OK();
     944             : }
     945             : 
     946             : mozilla::ipc::IPCResult
     947           0 : WebRenderBridgeParent::RecvGetAnimationOpacity(const uint64_t& aCompositorAnimationsId,
     948             :                                                float* aOpacity,
     949             :                                                bool* aHasAnimationOpacity)
     950             : {
     951           0 :   if (mDestroyed) {
     952           0 :     return IPC_FAIL_NO_REASON(this);
     953             :   }
     954             : 
     955           0 :   MOZ_ASSERT(mAnimStorage);
     956           0 :   AdvanceAnimations();
     957             : 
     958           0 :   Maybe<float> opacity = mAnimStorage->GetAnimationOpacity(aCompositorAnimationsId);
     959           0 :   if (opacity) {
     960           0 :     *aOpacity = *opacity;
     961           0 :     *aHasAnimationOpacity = true;
     962             :   } else {
     963           0 :     *aHasAnimationOpacity = false;
     964             :   }
     965           0 :   return IPC_OK();
     966             : }
     967             : 
     968             : mozilla::ipc::IPCResult
     969           0 : WebRenderBridgeParent::RecvGetAnimationTransform(const uint64_t& aCompositorAnimationsId,
     970             :                                                  MaybeTransform* aTransform)
     971             : {
     972           0 :   if (mDestroyed) {
     973           0 :     return IPC_FAIL_NO_REASON(this);
     974             :   }
     975             : 
     976           0 :   MOZ_ASSERT(mAnimStorage);
     977           0 :   AdvanceAnimations();
     978             : 
     979           0 :   Maybe<Matrix4x4> transform = mAnimStorage->GetAnimationTransform(aCompositorAnimationsId);
     980           0 :   if (transform) {
     981           0 :     *aTransform = *transform;
     982             :   } else {
     983           0 :     *aTransform = mozilla::void_t();
     984             :   }
     985           0 :   return IPC_OK();
     986             : }
     987             : 
     988             : mozilla::ipc::IPCResult
     989           0 : WebRenderBridgeParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
     990             :                                                 const float& aX,
     991             :                                                 const float& aY)
     992             : {
     993           0 :   if (mDestroyed) {
     994           0 :     return IPC_OK();
     995             :   }
     996           0 :   RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
     997           0 :   if (!apzc) {
     998           0 :     return IPC_FAIL_NO_REASON(this);
     999             :   }
    1000           0 :   apzc->SetTestAsyncScrollOffset(CSSPoint(aX, aY));
    1001           0 :   return IPC_OK();
    1002             : }
    1003             : 
    1004             : mozilla::ipc::IPCResult
    1005           0 : WebRenderBridgeParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
    1006             :                                         const float& aZoom)
    1007             : {
    1008           0 :   if (mDestroyed) {
    1009           0 :     return IPC_OK();
    1010             :   }
    1011           0 :   RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
    1012           0 :   if (!apzc) {
    1013           0 :     return IPC_FAIL_NO_REASON(this);
    1014             :   }
    1015           0 :   apzc->SetTestAsyncZoom(LayerToParentLayerScale(aZoom));
    1016           0 :   return IPC_OK();
    1017             : }
    1018             : 
    1019             : mozilla::ipc::IPCResult
    1020           0 : WebRenderBridgeParent::RecvFlushApzRepaints()
    1021             : {
    1022           0 :   if (mDestroyed) {
    1023           0 :     return IPC_OK();
    1024             :   }
    1025           0 :   mCompositorBridge->FlushApzRepaints(GetLayersId());
    1026           0 :   return IPC_OK();
    1027             : }
    1028             : 
    1029             : mozilla::ipc::IPCResult
    1030           0 : WebRenderBridgeParent::RecvGetAPZTestData(APZTestData* aOutData)
    1031             : {
    1032           0 :   mCompositorBridge->GetAPZTestData(GetLayersId(), aOutData);
    1033           0 :   return IPC_OK();
    1034             : }
    1035             : 
    1036             : void
    1037           0 : WebRenderBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
    1038             : {
    1039           0 :   Destroy();
    1040           0 : }
    1041             : 
    1042             : void
    1043           0 : WebRenderBridgeParent::AdvanceAnimations()
    1044             : {
    1045           0 :   TimeStamp animTime = mCompositorScheduler->GetLastComposeTime();
    1046           0 :   if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
    1047           0 :     animTime = cbp->GetTestingTimeStamp().valueOr(animTime);
    1048             :   }
    1049           0 :   AnimationHelper::SampleAnimations(mAnimStorage, animTime);
    1050           0 : }
    1051             : 
    1052             : void
    1053           0 : WebRenderBridgeParent::SampleAnimations(nsTArray<WrOpacityProperty>& aOpacityArray,
    1054             :                                         nsTArray<WrTransformProperty>& aTransformArray)
    1055             : {
    1056           0 :   AdvanceAnimations();
    1057             : 
    1058             :   // return the animated data if has
    1059           0 :   if (mAnimStorage->AnimatedValueCount()) {
    1060           0 :     for(auto iter = mAnimStorage->ConstAnimatedValueTableIter();
    1061           0 :         !iter.Done(); iter.Next()) {
    1062           0 :       AnimatedValue * value = iter.UserData();
    1063           0 :       if (value->mType == AnimatedValue::TRANSFORM) {
    1064           0 :         aTransformArray.AppendElement(
    1065           0 :           wr::ToWrTransformProperty(iter.Key(), value->mTransform.mTransformInDevSpace));
    1066           0 :       } else if (value->mType == AnimatedValue::OPACITY) {
    1067           0 :         aOpacityArray.AppendElement(
    1068           0 :           wr::ToWrOpacityProperty(iter.Key(), value->mOpacity));
    1069             :       }
    1070             :     }
    1071             :   }
    1072           0 : }
    1073             : 
    1074             : void
    1075           0 : WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
    1076             : {
    1077           0 :   AutoProfilerTracing tracing("Paint", "CompositeToTraget");
    1078           0 :   if (mPaused) {
    1079           0 :     return;
    1080             :   }
    1081             : 
    1082           0 :   const uint32_t maxPendingFrameCount = 2;
    1083             : 
    1084           0 :   if (!mForceRendering &&
    1085           0 :       wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) > maxPendingFrameCount) {
    1086             :     // Render thread is busy, try next time.
    1087           0 :     ScheduleComposition();
    1088           0 :     return;
    1089             :   }
    1090             : 
    1091           0 :   bool scheduleComposite = false;
    1092           0 :   nsTArray<WrOpacityProperty> opacityArray;
    1093           0 :   nsTArray<WrTransformProperty> transformArray;
    1094             : 
    1095           0 :   mCompositableHolder->SetCompositionTime(TimeStamp::Now());
    1096           0 :   mCompositableHolder->ApplyAsyncImages(mApi);
    1097             : 
    1098           0 :   if (gfxPrefs::WebRenderOMTAEnabled()) {
    1099           0 :     SampleAnimations(opacityArray, transformArray);
    1100             : 
    1101           0 :     if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) {
    1102           0 :       scheduleComposite = true;
    1103             :     }
    1104             :   }
    1105             : 
    1106           0 :   if (PushAPZStateToWR(transformArray)) {
    1107           0 :     scheduleComposite = true;
    1108             :   }
    1109             : 
    1110           0 :   if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) {
    1111           0 :     mApi->GenerateFrame(opacityArray, transformArray);
    1112             :   } else {
    1113           0 :     mApi->GenerateFrame();
    1114             :   }
    1115             : 
    1116           0 :   if (!mCompositableHolder->GetCompositeUntilTime().IsNull()) {
    1117           0 :     scheduleComposite = true;
    1118             :   }
    1119             : 
    1120           0 :   if (scheduleComposite) {
    1121           0 :     ScheduleComposition();
    1122             :   }
    1123             : }
    1124             : 
    1125             : void
    1126           0 : WebRenderBridgeParent::HoldPendingTransactionId(uint32_t aWrEpoch, uint64_t aTransactionId)
    1127             : {
    1128             :   // The transaction ID might get reset to 1 if the page gets reloaded, see
    1129             :   // https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
    1130             :   // Otherwise, it should be continually increasing.
    1131           0 :   MOZ_ASSERT(aTransactionId == 1 || aTransactionId > LastPendingTransactionId());
    1132             :   // Handle TransactionIdAllocator(RefreshDriver) change.
    1133           0 :   if (aTransactionId == 1) {
    1134           0 :     FlushPendingTransactionIds();
    1135             :   }
    1136           0 :   mPendingTransactionIds.push(PendingTransactionId(wr::NewEpoch(aWrEpoch), aTransactionId));
    1137           0 : }
    1138             : 
    1139             : uint64_t
    1140           0 : WebRenderBridgeParent::LastPendingTransactionId()
    1141             : {
    1142           0 :   uint64_t id = 0;
    1143           0 :   if (!mPendingTransactionIds.empty()) {
    1144           0 :     id = mPendingTransactionIds.back().mId;
    1145             :   }
    1146           0 :   return id;
    1147             : }
    1148             : 
    1149             : uint64_t
    1150           0 : WebRenderBridgeParent::FlushPendingTransactionIds()
    1151             : {
    1152           0 :   uint64_t id = 0;
    1153           0 :   while (!mPendingTransactionIds.empty()) {
    1154           0 :     id = mPendingTransactionIds.front().mId;
    1155           0 :     mPendingTransactionIds.pop();
    1156             :   }
    1157           0 :   return id;
    1158             : }
    1159             : 
    1160             : uint64_t
    1161           0 : WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
    1162             : {
    1163           0 :   uint64_t id = 0;
    1164           0 :   while (!mPendingTransactionIds.empty()) {
    1165           0 :     id = mPendingTransactionIds.front().mId;
    1166           0 :     if (mPendingTransactionIds.front().mEpoch == aEpoch) {
    1167           0 :       mPendingTransactionIds.pop();
    1168           0 :       break;
    1169             :     }
    1170           0 :     mPendingTransactionIds.pop();
    1171             :   }
    1172           0 :   return id;
    1173             : }
    1174             : 
    1175             : uint64_t
    1176           0 : WebRenderBridgeParent::GetLayersId() const
    1177             : {
    1178           0 :   return wr::AsUint64(mPipelineId);
    1179             : }
    1180             : 
    1181             : void
    1182           0 : WebRenderBridgeParent::DeleteOldImages()
    1183             : {
    1184           0 :   for (wr::ImageKey key : mKeysToDelete) {
    1185           0 :     mApi->DeleteImage(key);
    1186             :   }
    1187           0 :   mKeysToDelete.clear();
    1188           0 : }
    1189             : 
    1190             : void
    1191           0 : WebRenderBridgeParent::ScheduleComposition()
    1192             : {
    1193           0 :   if (mCompositorScheduler) {
    1194           0 :     mCompositorScheduler->ScheduleComposition();
    1195             :   }
    1196           0 : }
    1197             : 
    1198             : void
    1199           0 : WebRenderBridgeParent::FlushRendering(bool aIsSync)
    1200             : {
    1201           0 :   if (mDestroyed) {
    1202           0 :     return;
    1203             :   }
    1204             : 
    1205           0 :   if (!mCompositorScheduler->NeedsComposite()) {
    1206           0 :     return;
    1207             :   }
    1208             : 
    1209           0 :   mForceRendering = true;
    1210           0 :   mCompositorScheduler->CancelCurrentCompositeTask();
    1211           0 :   mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr);
    1212           0 :   if (aIsSync) {
    1213           0 :     mApi->WaitFlushed();
    1214             :   }
    1215           0 :   mForceRendering = false;
    1216             : }
    1217             : 
    1218             : void
    1219           0 : WebRenderBridgeParent::Pause()
    1220             : {
    1221           0 :   MOZ_ASSERT(mWidget);
    1222             : #ifdef MOZ_WIDGET_ANDROID
    1223             :   if (!mWidget || mDestroyed) {
    1224             :     return;
    1225             :   }
    1226             :   mApi->Pause();
    1227             : #endif
    1228           0 :   mPaused = true;
    1229           0 : }
    1230             : 
    1231             : bool
    1232           0 : WebRenderBridgeParent::Resume()
    1233             : {
    1234           0 :   MOZ_ASSERT(mWidget);
    1235             : #ifdef MOZ_WIDGET_ANDROID
    1236             :   if (!mWidget || mDestroyed) {
    1237             :     return false;
    1238             :   }
    1239             : 
    1240             :   if (!mApi->Resume()) {
    1241             :     return false;
    1242             :   }
    1243             : #endif
    1244           0 :   mPaused = false;
    1245           0 :   return true;
    1246             : }
    1247             : 
    1248             : void
    1249           0 : WebRenderBridgeParent::ClearResources()
    1250             : {
    1251           0 :   if (!mApi) {
    1252           0 :     return;
    1253             :   }
    1254             : 
    1255           0 :   ++mWrEpoch; // Update webrender epoch
    1256           0 :   mApi->ClearRootDisplayList(wr::NewEpoch(mWrEpoch), mPipelineId);
    1257             :   // Schedule composition to clean up Pipeline
    1258           0 :   mCompositorScheduler->ScheduleComposition();
    1259             :   // XXX webrender does not hava a way to delete a group of resources/keys,
    1260             :   // then delete keys one by one.
    1261           0 :   for (std::unordered_set<uint64_t>::iterator iter = mFontKeys.begin(); iter != mFontKeys.end(); iter++) {
    1262           0 :     mApi->DeleteFont(wr::AsFontKey(*iter));
    1263             :   }
    1264           0 :   mFontKeys.clear();
    1265           0 :   for (std::unordered_set<uint64_t>::iterator iter = mActiveImageKeys.begin(); iter != mActiveImageKeys.end(); iter++) {
    1266           0 :     mKeysToDelete.push_back(wr::AsImageKey(*iter));
    1267             :   }
    1268           0 :   mActiveImageKeys.clear();
    1269           0 :   DeleteOldImages();
    1270           0 :   for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
    1271           0 :     iter.Data()->ClearWrBridge();
    1272             :   }
    1273           0 :   mExternalImageIds.Clear();
    1274           0 :   for (auto iter = mAsyncCompositables.Iter(); !iter.Done(); iter.Next()) {
    1275           0 :     wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
    1276           0 :     RefPtr<WebRenderImageHost> host = iter.Data();
    1277           0 :     MOZ_ASSERT(host->GetAsyncRef());
    1278           0 :     host->ClearWrBridge();
    1279           0 :     mCompositableHolder->RemoveAsyncImagePipeline(mApi, pipelineId);
    1280             :   }
    1281           0 :   mAsyncCompositables.Clear();
    1282             : 
    1283           0 :   mCompositableHolder->RemovePipeline(mPipelineId, wr::NewEpoch(mWrEpoch));
    1284             : 
    1285           0 :   for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
    1286           0 :     mAnimStorage->ClearById(*iter);
    1287             :   }
    1288           0 :   mActiveAnimations.clear();
    1289             : 
    1290           0 :   if (mWidget) {
    1291           0 :     mCompositorScheduler->Destroy();
    1292             :   }
    1293           0 :   mAnimStorage = nullptr;
    1294           0 :   mCompositorScheduler = nullptr;
    1295           0 :   mApi = nullptr;
    1296           0 :   mCompositorBridge = nullptr;
    1297             : }
    1298             : 
    1299             : bool
    1300           0 : WebRenderBridgeParent::ShouldParentObserveEpoch()
    1301             : {
    1302           0 :   if (mParentLayerObserverEpoch == mChildLayerObserverEpoch) {
    1303           0 :     return false;
    1304             :   }
    1305             : 
    1306           0 :   mParentLayerObserverEpoch = mChildLayerObserverEpoch;
    1307           0 :   return true;
    1308             : }
    1309             : 
    1310             : void
    1311           0 : WebRenderBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
    1312             : {
    1313           0 :   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
    1314             : }
    1315             : 
    1316             : void
    1317           0 : WebRenderBridgeParent::SendPendingAsyncMessages()
    1318             : {
    1319           0 :   MOZ_ASSERT(mCompositorBridge);
    1320           0 :   mCompositorBridge->SendPendingAsyncMessages();
    1321           0 : }
    1322             : 
    1323             : void
    1324           0 : WebRenderBridgeParent::SetAboutToSendAsyncMessages()
    1325             : {
    1326           0 :   MOZ_ASSERT(mCompositorBridge);
    1327           0 :   mCompositorBridge->SetAboutToSendAsyncMessages();
    1328           0 : }
    1329             : 
    1330             : void
    1331           0 : WebRenderBridgeParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
    1332             : {
    1333           0 :   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
    1334             : }
    1335             : 
    1336             : base::ProcessId
    1337           0 : WebRenderBridgeParent::GetChildProcessId()
    1338             : {
    1339           0 :   return OtherPid();
    1340             : }
    1341             : 
    1342             : bool
    1343           0 : WebRenderBridgeParent::IsSameProcess() const
    1344             : {
    1345           0 :   return OtherPid() == base::GetCurrentProcId();
    1346             : }
    1347             : 
    1348             : mozilla::ipc::IPCResult
    1349           0 : WebRenderBridgeParent::RecvNewCompositable(const CompositableHandle& aHandle,
    1350             :                                            const TextureInfo& aInfo)
    1351             : {
    1352           0 :   if (mDestroyed) {
    1353           0 :     return IPC_OK();
    1354             :   }
    1355           0 :   if (!AddCompositable(aHandle, aInfo)) {
    1356           0 :     return IPC_FAIL_NO_REASON(this);
    1357             :   }
    1358           0 :   return IPC_OK();
    1359             : }
    1360             : 
    1361             : mozilla::ipc::IPCResult
    1362           0 : WebRenderBridgeParent::RecvReleaseCompositable(const CompositableHandle& aHandle)
    1363             : {
    1364           0 :   if (mDestroyed) {
    1365           0 :     return IPC_OK();
    1366             :   }
    1367           0 :   ReleaseCompositable(aHandle);
    1368           0 :   return IPC_OK();
    1369             : }
    1370             : 
    1371             : mozilla::ipc::IPCResult
    1372           0 : WebRenderBridgeParent::RecvInitReadLocks(ReadLockArray&& aReadLocks)
    1373             : {
    1374           0 :   if (mDestroyed) {
    1375           0 :     return IPC_OK();
    1376             :   }
    1377           0 :   if (!AddReadLocks(Move(aReadLocks))) {
    1378           0 :     return IPC_FAIL_NO_REASON(this);
    1379             :   }
    1380           0 :   return IPC_OK();
    1381             : }
    1382             : 
    1383             : void
    1384           0 : WebRenderBridgeParent::SetWebRenderProfilerEnabled(bool aEnabled)
    1385             : {
    1386           0 :   if (mWidget) {
    1387             :     // Only set the flag to "root" WebRenderBridgeParent.
    1388           0 :     mApi->SetProfilerEnabled(aEnabled);
    1389             :   }
    1390           0 : }
    1391             : 
    1392             : TextureFactoryIdentifier
    1393           0 : WebRenderBridgeParent::GetTextureFactoryIdentifier()
    1394             : {
    1395           0 :   MOZ_ASSERT(mApi);
    1396             : 
    1397             :   return TextureFactoryIdentifier(LayersBackend::LAYERS_WR,
    1398             :                                   XRE_GetProcessType(),
    1399             :                                   mApi->GetMaxTextureSize(),
    1400           0 :                                   mApi->GetUseANGLE());
    1401             : }
    1402             : 
    1403             : } // namespace layers
    1404             : } // namespace mozilla

Generated by: LCOV version 1.13