LCOV - code coverage report
Current view: top level - layout/painting - DisplayListClipState.h (source / functions) Hit Total Coverage
Test: output.info Lines: 74 80 92.5 %
Date: 2017-07-14 16:53:18 Functions: 18 19 94.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; 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             : #ifndef DISPLAYLISTCLIPSTATE_H_
       7             : #define DISPLAYLISTCLIPSTATE_H_
       8             : 
       9             : #include "DisplayItemClip.h"
      10             : #include "DisplayItemClipChain.h"
      11             : 
      12             : #include "mozilla/DebugOnly.h"
      13             : 
      14             : class nsIFrame;
      15             : class nsIScrollableFrame;
      16             : class nsDisplayListBuilder;
      17             : 
      18             : namespace mozilla {
      19             : 
      20             : /**
      21             :  * All clip coordinates are in appunits relative to the reference frame
      22             :  * for the display item we're building.
      23             :  */
      24             : class DisplayListClipState {
      25             : public:
      26          53 :   DisplayListClipState()
      27          53 :     : mClipChainContentDescendants(nullptr)
      28             :     , mClipChainContainingBlockDescendants(nullptr)
      29             :     , mCurrentCombinedClipChain(nullptr)
      30          53 :     , mCurrentCombinedClipChainIsValid(false)
      31          53 :   {}
      32             : 
      33             :   /**
      34             :    * Returns intersection of mClipChainContainingBlockDescendants and
      35             :    * mClipChainContentDescendants, allocated on aBuilder's arena.
      36             :    */
      37             :   const DisplayItemClipChain* GetCurrentCombinedClipChain(nsDisplayListBuilder* aBuilder);
      38             : 
      39         138 :   const DisplayItemClipChain* GetClipChainForContainingBlockDescendants() const
      40             :   {
      41         138 :     return mClipChainContainingBlockDescendants;
      42             :   }
      43             :   const DisplayItemClipChain* GetClipChainForContentDescendants() const
      44             :   {
      45             :     return mClipChainContentDescendants;
      46             :   }
      47             : 
      48        2937 :   const ActiveScrolledRoot* GetContentClipASR() const
      49             :   {
      50        2937 :     return mClipChainContentDescendants ? mClipChainContentDescendants->mASR : nullptr;
      51             :   }
      52             : 
      53             :   class AutoSaveRestore;
      54             :   friend class AutoSaveRestore;
      55             : 
      56             :   class AutoClipContainingBlockDescendantsToContentBox;
      57             :   friend class AutoClipContainingBlockDescendantsToContentBox;
      58             : 
      59             :   class AutoClipMultiple;
      60             :   friend class AutoClipMultiple;
      61             : 
      62             :   enum {
      63             :     ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT = 0x01
      64             :   };
      65             : 
      66             : private:
      67             : 
      68          24 :   void Clear()
      69             :   {
      70          24 :     mClipChainContentDescendants = nullptr;
      71          24 :     mClipChainContainingBlockDescendants = nullptr;
      72          24 :     mCurrentCombinedClipChain = nullptr;
      73          24 :     mCurrentCombinedClipChainIsValid = false;
      74          24 :   }
      75             : 
      76             :   void ClearUpToASR(const ActiveScrolledRoot* aASR);
      77             : 
      78          85 :   void SetClipChainForContainingBlockDescendants(const DisplayItemClipChain* aClipChain)
      79             :   {
      80          85 :     mClipChainContainingBlockDescendants = aClipChain;
      81          85 :     InvalidateCurrentCombinedClipChain(aClipChain ? aClipChain->mASR : nullptr);
      82          85 :   }
      83             : 
      84             :   /**
      85             :    * Intersects the given clip rect (with optional aRadii) with the current
      86             :    * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
      87             :    * the result, stored in aClipOnStack.
      88             :    */
      89             :   void ClipContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
      90             :                                       const nsRect& aRect,
      91             :                                       const nscoord* aRadii,
      92             :                                       DisplayItemClipChain& aClipChainOnStack);
      93             : 
      94             :   void ClipContentDescendants(nsDisplayListBuilder* aBuilder,
      95             :                               const nsRect& aRect,
      96             :                               const nscoord* aRadii,
      97             :                               DisplayItemClipChain& aClipChainOnStack);
      98             :   void ClipContentDescendants(nsDisplayListBuilder* aBuilder,
      99             :                               const nsRect& aRect,
     100             :                               const nsRect& aRoundedRect,
     101             :                               const nscoord* aRadii,
     102             :                               DisplayItemClipChain& aClipChainOnStack);
     103             : 
     104             :   void InvalidateCurrentCombinedClipChain(const ActiveScrolledRoot* aInvalidateUpTo);
     105             : 
     106             :   /**
     107             :    * Clips containing-block descendants to the frame's content-box,
     108             :    * taking border-radius into account.
     109             :    * If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
     110             :    * we assume display items will not draw outside the content rect, so
     111             :    * clipping is only required if there is a border-radius. This is an
     112             :    * optimization to reduce the amount of clipping required.
     113             :    */
     114             :   void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
     115             :                                                   nsIFrame* aFrame,
     116             :                                                   DisplayItemClipChain& aClipChainOnStack,
     117             :                                                   uint32_t aFlags);
     118             : 
     119             :   /**
     120             :    * All content descendants (i.e. following placeholder frames to their
     121             :    * out-of-flows if necessary) should be clipped by mClipChainContentDescendants.
     122             :    * Null if no clipping applies.
     123             :    */
     124             :   const DisplayItemClipChain* mClipChainContentDescendants;
     125             :   /**
     126             :    * All containing-block descendants (i.e. frame descendants), including
     127             :    * display items for the current frame, should be clipped by
     128             :    * mClipChainContainingBlockDescendants.
     129             :    * Null if no clipping applies.
     130             :    */
     131             :   const DisplayItemClipChain* mClipChainContainingBlockDescendants;
     132             :   /**
     133             :    * The intersection of mClipChainContentDescendants and
     134             :    * mClipChainContainingBlockDescendants.
     135             :    * Allocated in the nsDisplayListBuilder arena. Null if none has been
     136             :    * allocated or both mClipChainContentDescendants and mClipChainContainingBlockDescendants
     137             :    * are null.
     138             :    */
     139             :   const DisplayItemClipChain* mCurrentCombinedClipChain;
     140             :   bool mCurrentCombinedClipChainIsValid;
     141             : };
     142             : 
     143             : /**
     144             :  * A class to automatically save and restore the current clip state. Also
     145             :  * offers methods for modifying the clip state. Only one modification is allowed
     146             :  * to be in scope at a time using one of these objects; multiple modifications
     147             :  * require nested objects. The interface is written this way to prevent
     148             :  * dangling pointers to DisplayItemClips.
     149             :  */
     150             : class DisplayListClipState::AutoSaveRestore {
     151             : public:
     152             :   explicit AutoSaveRestore(nsDisplayListBuilder* aBuilder);
     153        4136 :   void Restore()
     154             :   {
     155        4136 :     mState = mSavedState;
     156             : #ifdef DEBUG
     157        4136 :     mRestored = true;
     158             : #endif
     159        4136 :   }
     160        4112 :   ~AutoSaveRestore()
     161        4112 :   {
     162        4112 :     Restore();
     163        4112 :   }
     164             : 
     165          24 :   void Clear()
     166             :   {
     167          24 :     NS_ASSERTION(!mRestored, "Already restored!");
     168          24 :     mState.Clear();
     169             : #ifdef DEBUG
     170          24 :     mClipUsed = false;
     171             : #endif
     172          24 :   }
     173             : 
     174         871 :   void ClearUpToASR(const ActiveScrolledRoot* aASR)
     175             :   {
     176         871 :     NS_ASSERTION(!mRestored, "Already restored!");
     177         871 :     mState.ClearUpToASR(aASR);
     178             : #ifdef DEBUG
     179         871 :     mClipUsed = false;
     180             : #endif
     181         871 :   }
     182             : 
     183          85 :   void SetClipChainForContainingBlockDescendants(const DisplayItemClipChain* aClipChain)
     184             :   {
     185          85 :     mState.SetClipChainForContainingBlockDescendants(aClipChain);
     186          85 :   }
     187             : 
     188             :   /**
     189             :    * Intersects the given clip rect (with optional aRadii) with the current
     190             :    * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
     191             :    * the result, stored in aClipOnStack.
     192             :    */
     193         460 :   void ClipContainingBlockDescendants(const nsRect& aRect,
     194             :                                       const nscoord* aRadii = nullptr)
     195             :   {
     196         460 :     NS_ASSERTION(!mRestored, "Already restored!");
     197         460 :     NS_ASSERTION(!mClipUsed, "mClip already used");
     198             : #ifdef DEBUG
     199         460 :     mClipUsed = true;
     200             : #endif
     201         460 :     mState.ClipContainingBlockDescendants(mBuilder, aRect, aRadii, mClipChain);
     202         460 :   }
     203             : 
     204         388 :   void ClipContentDescendants(const nsRect& aRect,
     205             :                               const nscoord* aRadii = nullptr)
     206             :   {
     207         388 :     NS_ASSERTION(!mRestored, "Already restored!");
     208         388 :     NS_ASSERTION(!mClipUsed, "mClip already used");
     209             : #ifdef DEBUG
     210         388 :     mClipUsed = true;
     211             : #endif
     212         388 :     mState.ClipContentDescendants(mBuilder, aRect, aRadii, mClipChain);
     213         388 :   }
     214             : 
     215           0 :   void ClipContentDescendants(const nsRect& aRect,
     216             :                               const nsRect& aRoundedRect,
     217             :                               const nscoord* aRadii = nullptr)
     218             :   {
     219           0 :     NS_ASSERTION(!mRestored, "Already restored!");
     220           0 :     NS_ASSERTION(!mClipUsed, "mClip already used");
     221             : #ifdef DEBUG
     222           0 :     mClipUsed = true;
     223             : #endif
     224           0 :     mState.ClipContentDescendants(mBuilder, aRect, aRoundedRect, aRadii, mClipChain);
     225           0 :   }
     226             : 
     227             :   /**
     228             :    * Clips containing-block descendants to the frame's content-box,
     229             :    * taking border-radius into account.
     230             :    * If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
     231             :    * we assume display items will not draw outside the content rect, so
     232             :    * clipping is only required if there is a border-radius. This is an
     233             :    * optimization to reduce the amount of clipping required.
     234             :    */
     235          18 :   void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
     236             :                                                   nsIFrame* aFrame,
     237             :                                                   uint32_t aFlags = 0)
     238             :   {
     239          18 :     NS_ASSERTION(!mRestored, "Already restored!");
     240          18 :     NS_ASSERTION(!mClipUsed, "mClip already used");
     241             : #ifdef DEBUG
     242          18 :     mClipUsed = true;
     243             : #endif
     244          18 :     mState.ClipContainingBlockDescendantsToContentBox(aBuilder, aFrame, mClipChain, aFlags);
     245          18 :   }
     246             : 
     247             : protected:
     248             :   nsDisplayListBuilder* mBuilder;
     249             :   DisplayListClipState& mState;
     250             :   DisplayListClipState mSavedState;
     251             :   DisplayItemClipChain mClipChain;
     252             : #ifdef DEBUG
     253             :   bool mClipUsed;
     254             :   bool mRestored;
     255             : #endif
     256             : };
     257             : 
     258         341 : class DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox : public AutoSaveRestore {
     259             : public:
     260         341 :   AutoClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
     261             :                                                  nsIFrame* aFrame,
     262             :                                                  uint32_t aFlags = 0)
     263         341 :     : AutoSaveRestore(aBuilder)
     264             :   {
     265             : #ifdef DEBUG
     266         341 :     mClipUsed = true;
     267             : #endif
     268         341 :     mState.ClipContainingBlockDescendantsToContentBox(aBuilder, aFrame, mClipChain, aFlags);
     269         341 :   }
     270             : };
     271             : 
     272             : /**
     273             :  * Do not use this outside of nsFrame::BuildDisplayListForChild, use
     274             :  * multiple AutoSaveRestores instead. We provide this class just to ensure
     275             :  * BuildDisplayListForChild is as efficient as possible.
     276             :  */
     277        1364 : class DisplayListClipState::AutoClipMultiple : public AutoSaveRestore {
     278             : public:
     279        1364 :   explicit AutoClipMultiple(nsDisplayListBuilder* aBuilder)
     280        1364 :     : AutoSaveRestore(aBuilder)
     281             : #ifdef DEBUG
     282        1364 :     , mExtraClipUsed(false)
     283             : #endif
     284        1364 :   {}
     285             : 
     286             :   /**
     287             :    * Intersects the given clip rect (with optional aRadii) with the current
     288             :    * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
     289             :    * the result, stored in aClipOnStack.
     290             :    */
     291          59 :   void ClipContainingBlockDescendantsExtra(const nsRect& aRect,
     292             :                                            const nscoord* aRadii)
     293             :   {
     294          59 :     NS_ASSERTION(!mRestored, "Already restored!");
     295          59 :     NS_ASSERTION(!mExtraClipUsed, "mExtraClip already used");
     296             : #ifdef DEBUG
     297          59 :     mExtraClipUsed = true;
     298             : #endif
     299          59 :     mState.ClipContainingBlockDescendants(mBuilder, aRect, aRadii, mExtraClipChain);
     300          59 :   }
     301             : 
     302             : protected:
     303             :   DisplayItemClipChain mExtraClipChain;
     304             : #ifdef DEBUG
     305             :   bool mExtraClipUsed;
     306             : #endif
     307             : };
     308             : 
     309             : } // namespace mozilla
     310             : 
     311             : #endif /* DISPLAYLISTCLIPSTATE_H_ */

Generated by: LCOV version 1.13