LCOV - code coverage report
Current view: top level - gfx/layers/apz/src - APZSampler.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 11 126 8.7 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/layers/APZSampler.h"
       8             : 
       9             : #include "APZCTreeManager.h"
      10             : #include "AsyncPanZoomController.h"
      11             : #include "mozilla/ClearOnShutdown.h"
      12             : #include "mozilla/layers/APZThreadUtils.h"
      13             : #include "mozilla/layers/CompositorThread.h"
      14             : #include "mozilla/layers/LayerMetricsWrapper.h"
      15             : #include "mozilla/layers/SynchronousTask.h"
      16             : #include "TreeTraversal.h"
      17             : #include "mozilla/webrender/WebRenderAPI.h"
      18             : 
      19             : namespace mozilla {
      20             : namespace layers {
      21             : 
      22           0 : StaticMutex APZSampler::sWindowIdLock;
      23           0 : StaticAutoPtr<std::unordered_map<uint64_t, APZSampler*>> APZSampler::sWindowIdMap;
      24             : 
      25             : 
      26           0 : APZSampler::APZSampler(const RefPtr<APZCTreeManager>& aApz,
      27           0 :                        bool aIsUsingWebRender)
      28             :   : mApz(aApz)
      29             :   , mIsUsingWebRender(aIsUsingWebRender)
      30             :   , mThreadIdLock("APZSampler::mThreadIdLock")
      31           0 :   , mSampleTimeLock("APZSampler::mSampleTimeLock")
      32             : {
      33           0 :   MOZ_ASSERT(aApz);
      34           0 :   mApz->SetSampler(this);
      35           0 : }
      36             : 
      37           0 : APZSampler::~APZSampler()
      38             : {
      39           0 :   mApz->SetSampler(nullptr);
      40             : 
      41           0 :   StaticMutexAutoLock lock(sWindowIdLock);
      42           0 :   if (mWindowId) {
      43           0 :     MOZ_ASSERT(sWindowIdMap);
      44           0 :     sWindowIdMap->erase(wr::AsUint64(*mWindowId));
      45             :   }
      46           0 : }
      47             : 
      48             : void
      49           0 : APZSampler::SetWebRenderWindowId(const wr::WindowId& aWindowId)
      50             : {
      51           0 :   StaticMutexAutoLock lock(sWindowIdLock);
      52           0 :   MOZ_ASSERT(!mWindowId);
      53           0 :   mWindowId = Some(aWindowId);
      54           0 :   if (!sWindowIdMap) {
      55           0 :     sWindowIdMap = new std::unordered_map<uint64_t, APZSampler*>();
      56           0 :     NS_DispatchToMainThread(
      57           0 :       NS_NewRunnableFunction("APZUpdater::ClearOnShutdown", [] {
      58           0 :         ClearOnShutdown(&sWindowIdMap);
      59           0 :       }
      60           0 :     ));
      61             :   }
      62           0 :   (*sWindowIdMap)[wr::AsUint64(aWindowId)] = this;
      63           0 : }
      64             : 
      65             : /*static*/ void
      66           0 : APZSampler::SetSamplerThread(const wr::WrWindowId& aWindowId)
      67             : {
      68           0 :   if (RefPtr<APZSampler> sampler = GetSampler(aWindowId)) {
      69           0 :     MutexAutoLock lock(sampler->mThreadIdLock);
      70           0 :     sampler->mSamplerThreadId = Some(PlatformThread::CurrentId());
      71             :   }
      72           0 : }
      73             : 
      74             : /*static*/ void
      75           0 : APZSampler::SampleForWebRender(const wr::WrWindowId& aWindowId,
      76             :                                wr::Transaction* aTransaction)
      77             : {
      78           0 :   if (RefPtr<APZSampler> sampler = GetSampler(aWindowId)) {
      79           0 :     wr::TransactionWrapper txn(aTransaction);
      80           0 :     sampler->SampleForWebRender(txn);
      81             :   }
      82           0 : }
      83             : 
      84             : void
      85           0 : APZSampler::SetSampleTime(const TimeStamp& aSampleTime)
      86             : {
      87           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
      88           0 :   MutexAutoLock lock(mSampleTimeLock);
      89           0 :   mSampleTime = aSampleTime;
      90           0 : }
      91             : 
      92             : void
      93           0 : APZSampler::SampleForWebRender(wr::TransactionWrapper& aTxn)
      94             : {
      95           0 :   AssertOnSamplerThread();
      96           0 :   TimeStamp sampleTime;
      97             :   { // scope lock
      98           0 :     MutexAutoLock lock(mSampleTimeLock);
      99             : 
     100             :     // If mSampleTime is null we're in a startup phase where the
     101             :     // WebRenderBridgeParent hasn't yet provided us with a sample time.
     102             :     // If we're that early there probably aren't any APZ animations happening
     103             :     // anyway, so using Timestamp::Now() should be fine.
     104           0 :     sampleTime = mSampleTime.IsNull() ? TimeStamp::Now() : mSampleTime;
     105             :   }
     106           0 :   mApz->SampleForWebRender(aTxn, sampleTime);
     107           0 : }
     108             : 
     109             : bool
     110           0 : APZSampler::SampleAnimations(const LayerMetricsWrapper& aLayer,
     111             :                              const TimeStamp& aSampleTime)
     112             : {
     113           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     114           0 :   AssertOnSamplerThread();
     115             : 
     116             :   // TODO: eventually we can drop the aLayer argument and just walk the APZ
     117             :   // tree directly in mApz.
     118             : 
     119           0 :   bool activeAnimations = false;
     120             : 
     121           0 :   ForEachNodePostOrder<ForwardIterator>(aLayer,
     122           0 :       [&activeAnimations, &aSampleTime](LayerMetricsWrapper aLayerMetrics)
     123           0 :       {
     124           0 :         if (AsyncPanZoomController* apzc = aLayerMetrics.GetApzc()) {
     125           0 :           apzc->ReportCheckerboard(aSampleTime);
     126           0 :           activeAnimations |= apzc->AdvanceAnimations(aSampleTime);
     127             :         }
     128           0 :       }
     129           0 :   );
     130             : 
     131           0 :   return activeAnimations;
     132             : }
     133             : 
     134             : LayerToParentLayerMatrix4x4
     135           0 : APZSampler::ComputeTransformForScrollThumb(const LayerToParentLayerMatrix4x4& aCurrentTransform,
     136             :                                            const LayerMetricsWrapper& aContent,
     137             :                                            const ScrollbarData& aThumbData,
     138             :                                            bool aScrollbarIsDescendant,
     139             :                                            AsyncTransformComponentMatrix* aOutClipTransform)
     140             : {
     141           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     142           0 :   AssertOnSamplerThread();
     143             : 
     144           0 :   return mApz->ComputeTransformForScrollThumb(aCurrentTransform,
     145           0 :                                               aContent.GetTransform(),
     146             :                                               aContent.GetApzc(),
     147             :                                               aContent.Metrics(),
     148             :                                               aThumbData,
     149             :                                               aScrollbarIsDescendant,
     150           0 :                                               aOutClipTransform);
     151             : }
     152             : 
     153             : CSSRect
     154           0 : APZSampler::GetCurrentAsyncLayoutViewport(const LayerMetricsWrapper& aLayer)
     155             : {
     156           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     157           0 :   AssertOnSamplerThread();
     158             : 
     159           0 :   MOZ_ASSERT(aLayer.GetApzc());
     160           0 :   return aLayer.GetApzc()->GetCurrentAsyncLayoutViewport(AsyncPanZoomController::eForCompositing);
     161             : }
     162             : 
     163             : ParentLayerPoint
     164           0 : APZSampler::GetCurrentAsyncScrollOffset(const LayerMetricsWrapper& aLayer)
     165             : {
     166           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     167           0 :   AssertOnSamplerThread();
     168             : 
     169           0 :   MOZ_ASSERT(aLayer.GetApzc());
     170           0 :   return aLayer.GetApzc()->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForCompositing);
     171             : }
     172             : 
     173             : AsyncTransform
     174           0 : APZSampler::GetCurrentAsyncTransform(const LayerMetricsWrapper& aLayer)
     175             : {
     176           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     177           0 :   AssertOnSamplerThread();
     178             : 
     179           0 :   MOZ_ASSERT(aLayer.GetApzc());
     180           0 :   return aLayer.GetApzc()->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing);
     181             : }
     182             : 
     183             : AsyncTransformComponentMatrix
     184           0 : APZSampler::GetOverscrollTransform(const LayerMetricsWrapper& aLayer)
     185             : {
     186           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     187           0 :   AssertOnSamplerThread();
     188             : 
     189           0 :   MOZ_ASSERT(aLayer.GetApzc());
     190           0 :   return aLayer.GetApzc()->GetOverscrollTransform(AsyncPanZoomController::eForCompositing);
     191             : }
     192             : 
     193             : AsyncTransformComponentMatrix
     194           0 : APZSampler::GetCurrentAsyncTransformWithOverscroll(const LayerMetricsWrapper& aLayer)
     195             : {
     196           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     197           0 :   AssertOnSamplerThread();
     198             : 
     199           0 :   MOZ_ASSERT(aLayer.GetApzc());
     200           0 :   return aLayer.GetApzc()->GetCurrentAsyncTransformWithOverscroll(AsyncPanZoomController::eForCompositing);
     201             : }
     202             : 
     203             : void
     204           1 : APZSampler::MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer)
     205             : {
     206           1 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     207           1 :   AssertOnSamplerThread();
     208             : 
     209           1 :   MOZ_ASSERT(aLayer.GetApzc());
     210          16 :   aLayer.GetApzc()->MarkAsyncTransformAppliedToContent();
     211           1 : }
     212             : 
     213             : bool
     214           0 : APZSampler::HasUnusedAsyncTransform(const LayerMetricsWrapper& aLayer)
     215             : {
     216           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     217           0 :   AssertOnSamplerThread();
     218             : 
     219           0 :   AsyncPanZoomController* apzc = aLayer.GetApzc();
     220             :   return apzc
     221           0 :       && !apzc->GetAsyncTransformAppliedToContent()
     222           0 :       && !AsyncTransformComponentMatrix(apzc->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing)).IsIdentity();
     223             : }
     224             : 
     225             : void
     226           0 : APZSampler::AssertOnSamplerThread() const
     227             : {
     228          48 :   if (APZThreadUtils::GetThreadAssertionsEnabled()) {
     229          48 :     MOZ_ASSERT(IsSamplerThread());
     230             :   }
     231           1 : }
     232             : 
     233             : bool
     234           0 : APZSampler::IsSamplerThread() const
     235             : {
     236          48 :   if (mIsUsingWebRender) {
     237             :     // If the sampler thread id isn't set yet then we cannot be running on the
     238             :     // sampler thread (because we will have the thread id before we run any
     239             :     // other C++ code on it, and this function is only ever invoked from C++
     240             :     // code), so return false in that scenario.
     241           0 :     MutexAutoLock lock(mThreadIdLock);
     242           0 :     return mSamplerThreadId && PlatformThread::CurrentId() == *mSamplerThreadId;
     243             :   }
     244           1 :   return CompositorThreadHolder::IsInCompositorThread();
     245             : }
     246             : 
     247             : /*static*/ already_AddRefed<APZSampler>
     248           0 : APZSampler::GetSampler(const wr::WrWindowId& aWindowId)
     249             : {
     250           0 :   RefPtr<APZSampler> sampler;
     251           0 :   StaticMutexAutoLock lock(sWindowIdLock);
     252           0 :   if (sWindowIdMap) {
     253           0 :     auto it = sWindowIdMap->find(wr::AsUint64(aWindowId));
     254           0 :     if (it != sWindowIdMap->end()) {
     255           0 :       sampler = it->second;
     256             :     }
     257             :   }
     258           0 :   return sampler.forget();
     259             : }
     260             : 
     261             : } // namespace layers
     262             : } // namespace mozilla
     263             : 
     264             : void
     265           0 : apz_register_sampler(mozilla::wr::WrWindowId aWindowId)
     266             : {
     267           0 :   mozilla::layers::APZSampler::SetSamplerThread(aWindowId);
     268           0 : }
     269             : 
     270             : void
     271             : apz_sample_transforms(mozilla::wr::WrWindowId aWindowId,
     272             :                       mozilla::wr::Transaction *aTransaction)
     273             : {
     274             :   mozilla::layers::APZSampler::SampleForWebRender(aWindowId, aTransaction);
     275             : }
     276             : 
     277             : void
     278             : apz_deregister_sampler(mozilla::wr::WrWindowId aWindowId)
     279             : {
     280             : }

Generated by: LCOV version 1.13-14-ga5dd952