LCOV - code coverage report
Current view: top level - gfx/layers/apz/src - FocusState.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 11 54 20.4 %
Date: 2017-07-14 16:53:18 Functions: 3 8 37.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "mozilla/layers/FocusState.h"
       7             : 
       8             : // #define FS_LOG(...) printf_stderr("FS: " __VA_ARGS__)
       9             : #define FS_LOG(...)
      10             : 
      11             : namespace mozilla {
      12             : namespace layers {
      13             : 
      14           1 : FocusState::FocusState()
      15             :   : mLastAPZProcessedEvent(1)
      16             :   , mLastContentProcessedEvent(0)
      17             :   , mFocusHasKeyEventListeners(false)
      18             :   , mFocusLayersId(0)
      19             :   , mFocusHorizontalTarget(FrameMetrics::NULL_SCROLL_ID)
      20           1 :   , mFocusVerticalTarget(FrameMetrics::NULL_SCROLL_ID)
      21             : {
      22           1 : }
      23             : 
      24             : bool
      25           0 : FocusState::IsCurrent() const
      26             : {
      27             :   FS_LOG("Checking IsCurrent() with cseq=%" PRIu64 ", aseq=%" PRIu64 "\n",
      28             :          mLastContentProcessedEvent,
      29             :          mLastAPZProcessedEvent);
      30             : 
      31           0 :   MOZ_ASSERT(mLastContentProcessedEvent <= mLastAPZProcessedEvent);
      32           0 :   return mLastContentProcessedEvent == mLastAPZProcessedEvent;
      33             : }
      34             : 
      35             : void
      36           6 : FocusState::ReceiveFocusChangingEvent()
      37             : {
      38           6 :   mLastAPZProcessedEvent += 1;
      39           6 : }
      40             : 
      41             : void
      42           0 : FocusState::Update(uint64_t aRootLayerTreeId,
      43             :                    uint64_t aOriginatingLayersId,
      44             :                    const FocusTarget& aState)
      45             : {
      46             :   FS_LOG("Update with rlt=%" PRIu64 ", olt=%" PRIu64 ", ft=(%d, %" PRIu64 ")\n",
      47             :          aRootLayerTreeId,
      48             :          aOriginatingLayersId,
      49             :          (int)aState.mType,
      50             :          aState.mSequenceNumber);
      51             : 
      52             :   // Update the focus tree with the latest target
      53           0 :   mFocusTree[aOriginatingLayersId] = aState;
      54             : 
      55             :   // Reset our internal state so we can recalculate it
      56           0 :   mFocusHasKeyEventListeners = false;
      57           0 :   mFocusLayersId = aRootLayerTreeId;
      58           0 :   mFocusHorizontalTarget = FrameMetrics::NULL_SCROLL_ID;
      59           0 :   mFocusVerticalTarget = FrameMetrics::NULL_SCROLL_ID;
      60             : 
      61             :   // To update the focus state for the entire APZCTreeManager, we need
      62             :   // to traverse the focus tree to find the current leaf which is the global
      63             :   // focus target we can use for async keyboard scrolling
      64             :   while (true) {
      65           0 :     auto currentNode = mFocusTree.find(mFocusLayersId);
      66           0 :     if (currentNode == mFocusTree.end()) {
      67             :       FS_LOG("Setting target to nil (cannot find lt=%" PRIu64 ")\n",
      68             :              mFocusLayersId);
      69           0 :       return;
      70             :     }
      71             : 
      72           0 :     const FocusTarget& target = currentNode->second;
      73             : 
      74             :     // Accumulate event listener flags on the path to the focus target
      75           0 :     mFocusHasKeyEventListeners |= target.mFocusHasKeyEventListeners;
      76             : 
      77           0 :     switch (target.mType) {
      78             :       case FocusTarget::eRefLayer: {
      79             :         // Guard against infinite loops
      80           0 :         MOZ_ASSERT(mFocusLayersId != target.mData.mRefLayerId);
      81           0 :         if (mFocusLayersId == target.mData.mRefLayerId) {
      82             :           FS_LOG("Setting target to nil (bailing out of infinite loop, lt=%" PRIu64 ")\n",
      83             :                  mFocusLayersId);
      84           0 :           return;
      85             :         }
      86             : 
      87             :         FS_LOG("Looking for target in lt=%" PRIu64 "\n", target.mData.mRefLayerId);
      88             : 
      89             :         // The focus target is in a child layer tree
      90           0 :         mFocusLayersId = target.mData.mRefLayerId;
      91           0 :         break;
      92             :       }
      93             :       case FocusTarget::eScrollLayer: {
      94             :         FS_LOG("Setting target to h=%" PRIu64 ", v=%" PRIu64 ", and seq=%" PRIu64 "\n",
      95             :                target.mData.mScrollTargets.mHorizontal,
      96             :                target.mData.mScrollTargets.mVertical,
      97             :                target.mSequenceNumber);
      98             : 
      99             :         // This is the global focus target
     100           0 :         mFocusHorizontalTarget = target.mData.mScrollTargets.mHorizontal;
     101           0 :         mFocusVerticalTarget = target.mData.mScrollTargets.mVertical;
     102             : 
     103             :         // Mark what sequence number this target has so we can determine whether
     104             :         // it is stale or not
     105           0 :         mLastContentProcessedEvent = target.mSequenceNumber;
     106           0 :         return;
     107             :       }
     108             :       case FocusTarget::eNone: {
     109             :         FS_LOG("Setting target to nil (reached a nil target)\n");
     110             : 
     111             :         // Mark what sequence number this target has for debugging purposes so
     112             :         // we can always accurately report on whether we are stale or not
     113           0 :         mLastContentProcessedEvent = target.mSequenceNumber;
     114           0 :         return;
     115             :       }
     116             :     }
     117           0 :   }
     118             : }
     119             : 
     120             : std::unordered_set<uint64_t>
     121          28 : FocusState::GetFocusTargetLayerIds() const
     122             : {
     123          28 :   std::unordered_set<uint64_t> layersIds;
     124          28 :   layersIds.reserve(mFocusTree.size());
     125             : 
     126          28 :   for (const auto& focusNode : mFocusTree) {
     127           0 :     layersIds.insert(focusNode.first);
     128             :   }
     129             : 
     130          28 :   return layersIds;
     131             : }
     132             : 
     133             : void
     134           0 : FocusState::RemoveFocusTarget(uint64_t aLayersId)
     135             : {
     136           0 :   mFocusTree.erase(aLayersId);
     137           0 : }
     138             : 
     139             : Maybe<ScrollableLayerGuid>
     140           0 : FocusState::GetHorizontalTarget() const
     141             : {
     142             :   // There is not a scrollable layer to async scroll if
     143             :   //   1. We aren't current
     144             :   //   2. There are event listeners that could change the focus
     145             :   //   3. The target has not been layerized
     146           0 :   if (!IsCurrent() ||
     147           0 :       mFocusHasKeyEventListeners ||
     148           0 :       mFocusHorizontalTarget == FrameMetrics::NULL_SCROLL_ID) {
     149           0 :     return Nothing();
     150             :   }
     151           0 :   return Some(ScrollableLayerGuid(mFocusLayersId, 0, mFocusHorizontalTarget));
     152             : }
     153             : 
     154             : Maybe<ScrollableLayerGuid>
     155           0 : FocusState::GetVerticalTarget() const
     156             : {
     157             :   // There is not a scrollable layer to async scroll if:
     158             :   //   1. We aren't current
     159             :   //   2. There are event listeners that could change the focus
     160             :   //   3. The target has not been layerized
     161           0 :   if (!IsCurrent() ||
     162           0 :       mFocusHasKeyEventListeners ||
     163           0 :       mFocusVerticalTarget == FrameMetrics::NULL_SCROLL_ID) {
     164           0 :     return Nothing();
     165             :   }
     166           0 :   return Some(ScrollableLayerGuid(mFocusLayersId, 0, mFocusVerticalTarget));
     167             : }
     168             : 
     169             : } // namespace layers
     170             : } // namespace mozilla

Generated by: LCOV version 1.13