LCOV - code coverage report
Current view: top level - layout/painting - nsDisplayList.h (source / functions) Hit Total Coverage
Test: output.info Lines: 625 1038 60.2 %
Date: 2017-07-14 16:53:18 Functions: 249 458 54.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * vim: set ts=2 sw=2 et tw=78:
       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             : 
       8             : /*
       9             :  * structures that represent things to be painted (ordered in z-order),
      10             :  * used during painting and hit testing
      11             :  */
      12             : 
      13             : #ifndef NSDISPLAYLIST_H_
      14             : #define NSDISPLAYLIST_H_
      15             : 
      16             : #include "gfxContext.h"
      17             : #include "mozilla/ArenaAllocator.h"
      18             : #include "mozilla/Attributes.h"
      19             : #include "mozilla/Array.h"
      20             : #include "mozilla/DebugOnly.h"
      21             : #include "mozilla/EnumSet.h"
      22             : #include "mozilla/Maybe.h"
      23             : #include "mozilla/TemplateLib.h" // mozilla::tl::Max
      24             : #include "nsCOMPtr.h"
      25             : #include "nsContainerFrame.h"
      26             : #include "nsPoint.h"
      27             : #include "nsRect.h"
      28             : #include "nsRegion.h"
      29             : #include "nsDisplayListInvalidation.h"
      30             : #include "DisplayListClipState.h"
      31             : #include "LayerState.h"
      32             : #include "FrameMetrics.h"
      33             : #include "mozilla/EnumeratedArray.h"
      34             : #include "mozilla/Maybe.h"
      35             : #include "mozilla/UniquePtr.h"
      36             : #include "mozilla/TimeStamp.h"
      37             : #include "mozilla/gfx/UserData.h"
      38             : #include "mozilla/layers/LayerAttributes.h"
      39             : #include "nsCSSRenderingBorders.h"
      40             : 
      41             : #include <stdint.h>
      42             : #include "nsTHashtable.h"
      43             : 
      44             : #include <stdlib.h>
      45             : #include <algorithm>
      46             : 
      47             : class gfxContext;
      48             : class nsIContent;
      49             : class nsDisplayList;
      50             : class nsDisplayTableItem;
      51             : class nsISelection;
      52             : class nsIScrollableFrame;
      53             : class nsDisplayLayerEventRegions;
      54             : class nsDisplayScrollInfoLayer;
      55             : class nsCaret;
      56             : 
      57             : namespace mozilla {
      58             : class FrameLayerBuilder;
      59             : namespace layers {
      60             : class Layer;
      61             : class ImageLayer;
      62             : class ImageContainer;
      63             : class StackingContextHelper;
      64             : class WebRenderCommand;
      65             : class WebRenderParentCommand;
      66             : class WebRenderDisplayItemLayer;
      67             : } // namespace layers
      68             : namespace wr {
      69             : class DisplayListBuilder;
      70             : } // namespace wr
      71             : } // namespace mozilla
      72             : 
      73             : // A set of blend modes, that never includes OP_OVER (since it's
      74             : // considered the default, rather than a specific blend mode).
      75             : typedef mozilla::EnumSet<mozilla::gfx::CompositionOp> BlendModeSet;
      76             : 
      77             : /*
      78             :  * An nsIFrame can have many different visual parts. For example an image frame
      79             :  * can have a background, border, and outline, the image itself, and a
      80             :  * translucent selection overlay. In general these parts can be drawn at
      81             :  * discontiguous z-levels; see CSS2.1 appendix E:
      82             :  * http://www.w3.org/TR/CSS21/zindex.html
      83             :  *
      84             :  * We construct a display list for a frame tree that contains one item
      85             :  * for each visual part. The display list is itself a tree since some items
      86             :  * are containers for other items; however, its structure does not match
      87             :  * the structure of its source frame tree. The display list items are sorted
      88             :  * by z-order. A display list can be used to paint the frames, to determine
      89             :  * which frame is the target of a mouse event, and to determine what areas
      90             :  * need to be repainted when scrolling. The display lists built for each task
      91             :  * may be different for efficiency; in particular some frames need special
      92             :  * display list items only for event handling, and do not create these items
      93             :  * when the display list will be used for painting (the common case). For
      94             :  * example, when painting we avoid creating nsDisplayBackground items for
      95             :  * frames that don't display a visible background, but for event handling
      96             :  * we need those backgrounds because they are not transparent to events.
      97             :  *
      98             :  * We could avoid constructing an explicit display list by traversing the
      99             :  * frame tree multiple times in clever ways. However, reifying the display list
     100             :  * reduces code complexity and reduces the number of times each frame must be
     101             :  * traversed to one, which seems to be good for performance. It also means
     102             :  * we can share code for painting, event handling and scroll analysis.
     103             :  *
     104             :  * Display lists are short-lived; content and frame trees cannot change
     105             :  * between a display list being created and destroyed. Display lists should
     106             :  * not be created during reflow because the frame tree may be in an
     107             :  * inconsistent state (e.g., a frame's stored overflow-area may not include
     108             :  * the bounds of all its children). However, it should be fine to create
     109             :  * a display list while a reflow is pending, before it starts.
     110             :  *
     111             :  * A display list covers the "extended" frame tree; the display list for a frame
     112             :  * tree containing FRAME/IFRAME elements can include frames from the subdocuments.
     113             :  *
     114             :  * Display item's coordinates are relative to their nearest reference frame ancestor.
     115             :  * Both the display root and any frame with a transform act as a reference frame
     116             :  * for their frame subtrees.
     117             :  */
     118             : 
     119             : // All types are defined in nsDisplayItemTypes.h
     120             : #define NS_DISPLAY_DECL_NAME(n, e) \
     121             :   virtual const char* Name() override { return n; } \
     122             :   virtual Type GetType() override { return e; }
     123             : 
     124             : 
     125             : /**
     126             :  * Represents a frame that is considered to have (or will have) "animated geometry"
     127             :  * for itself and descendant frames.
     128             :  *
     129             :  * For example the scrolled frames of scrollframes which are actively being scrolled
     130             :  * fall into this category. Frames with certain CSS properties that are being animated
     131             :  * (e.g. 'left'/'top' etc) are also placed in this category. Frames with different
     132             :  * active geometry roots are in different PaintedLayers, so that we can animate the
     133             :  * geometry root by changing its transform (either on the main thread or in the
     134             :  * compositor).
     135             :  *
     136             :  * nsDisplayListBuilder constructs a tree of these (for fast traversals) and assigns
     137             :  * one for each display item.
     138             :  *
     139             :  * The animated geometry root for a display item is required to be a descendant (or
     140             :  * equal to) the item's ReferenceFrame(), which means that we will fall back to
     141             :  * returning aItem->ReferenceFrame() when we can't find another animated geometry root.
     142             :  *
     143             :  * The animated geometry root isn't strongly defined for a frame as transforms and
     144             :  * background-attachment:fixed can cause it to vary between display items for a given
     145             :  * frame.
     146             :  */
     147             : struct AnimatedGeometryRoot
     148             : {
     149          55 :   AnimatedGeometryRoot(nsIFrame* aFrame, AnimatedGeometryRoot* aParent)
     150          55 :     : mFrame(aFrame)
     151          55 :     , mParentAGR(aParent)
     152          55 :   {}
     153             : 
     154        7446 :   operator nsIFrame*() { return mFrame; }
     155             : 
     156        2351 :   nsIFrame* operator ->() const { return mFrame; }
     157             : 
     158             :   void* operator new(size_t aSize,
     159             :                      nsDisplayListBuilder* aBuilder);
     160             : 
     161             :   nsIFrame* mFrame;
     162             :   AnimatedGeometryRoot* mParentAGR;
     163             : };
     164             : 
     165             : namespace mozilla {
     166             : 
     167             : /**
     168             :  * An active scrolled root (ASR) is similar to an animated geometry root (AGR).
     169             :  * The differences are:
     170             :  *  - ASRs are only created for async-scrollable scroll frames. This is a
     171             :  *    (hopefully) temporary restriction. In the future we will want to create
     172             :  *    ASRs for all the things that are currently creating AGRs, and then
     173             :  *    replace AGRs with ASRs and rename them from "active scrolled root" to
     174             :  *    "animated geometry root".
     175             :  *  - ASR objects are created during display list construction by the nsIFrames
     176             :  *    that induce ASRs. This is done using AutoCurrentActiveScrolledRootSetter.
     177             :  *    The current ASR is returned by nsDisplayListBuilder::CurrentActiveScrolledRoot().
     178             :  *  - There is no way to go from an nsIFrame pointer to the ASR of that frame.
     179             :  *    If you need to look up an ASR after display list construction, you need
     180             :  *    to store it while the AutoCurrentActiveScrolledRootSetter that creates it
     181             :  *    is on the stack.
     182             :  */
     183             : struct ActiveScrolledRoot {
     184           2 :   ActiveScrolledRoot(const ActiveScrolledRoot* aParent,
     185             :                      nsIScrollableFrame* aScrollableFrame)
     186           2 :     : mParent(aParent)
     187             :     , mScrollableFrame(aScrollableFrame)
     188           2 :     , mDepth(mParent ? mParent->mDepth + 1 : 1)
     189             :   {
     190           2 :   }
     191             : 
     192        1409 :   static const ActiveScrolledRoot* PickAncestor(const ActiveScrolledRoot* aOne,
     193             :                                                 const ActiveScrolledRoot* aTwo)
     194             :   {
     195        1409 :     MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
     196        1409 :     return Depth(aOne) <= Depth(aTwo) ? aOne : aTwo;
     197             :   }
     198             : 
     199        2731 :   static const ActiveScrolledRoot* PickDescendant(const ActiveScrolledRoot* aOne,
     200             :                                                   const ActiveScrolledRoot* aTwo)
     201             :   {
     202        2731 :     MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
     203        2731 :     return Depth(aOne) >= Depth(aTwo) ? aOne : aTwo;
     204             :   }
     205             : 
     206             :   static bool IsAncestor(const ActiveScrolledRoot* aAncestor,
     207             :                          const ActiveScrolledRoot* aDescendant);
     208             : 
     209             :   static nsCString ToString(const mozilla::ActiveScrolledRoot* aActiveScrolledRoot);
     210             : 
     211             :   // Call this when inserting an ancestor.
     212           0 :   void IncrementDepth() { mDepth++; }
     213             : 
     214             :   const ActiveScrolledRoot* mParent;
     215             :   nsIScrollableFrame* mScrollableFrame;
     216             : 
     217             : private:
     218        8328 :   static uint32_t Depth(const ActiveScrolledRoot* aActiveScrolledRoot) {
     219        8328 :     return aActiveScrolledRoot ? aActiveScrolledRoot->mDepth : 0;
     220             :   }
     221             : 
     222             :   uint32_t mDepth;
     223             : };
     224             : 
     225             : }
     226             : 
     227             : enum class nsDisplayListBuilderMode : uint8_t {
     228             :   PAINTING,
     229             :   EVENT_DELIVERY,
     230             :   PLUGIN_GEOMETRY,
     231             :   FRAME_VISIBILITY,
     232             :   TRANSFORM_COMPUTATION,
     233             :   GENERATE_GLYPH,
     234             :   PAINTING_SELECTION_BACKGROUND
     235             : };
     236             : 
     237             : /**
     238             :  * This manages a display list and is passed as a parameter to
     239             :  * nsIFrame::BuildDisplayList.
     240             :  * It contains the parameters that don't change from frame to frame and manages
     241             :  * the display list memory using an arena. It also establishes the reference
     242             :  * coordinate system for all display list items. Some of the parameters are
     243             :  * available from the prescontext/presshell, but we copy them into the builder
     244             :  * for faster/more convenient access.
     245             :  */
     246             : class nsDisplayListBuilder {
     247             :   typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
     248             :   typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
     249             : 
     250             :   /**
     251             :    * This manages status of a 3d context to collect visible rects of
     252             :    * descendants and passing a dirty rect.
     253             :    *
     254             :    * Since some transforms maybe singular, passing visible rects or
     255             :    * the dirty rect level by level from parent to children may get a
     256             :    * wrong result, being different from the result of appling with
     257             :    * effective transform directly.
     258             :    *
     259             :    * nsFrame::BuildDisplayListForStackingContext() uses
     260             :    * AutoPreserves3DContext to install an instance on the builder.
     261             :    *
     262             :    * \see AutoAccumulateTransform, AutoAccumulateRect,
     263             :    *      AutoPreserves3DContext, Accumulate, GetCurrentTransform,
     264             :    *      StartRoot.
     265             :    */
     266          53 :   class Preserves3DContext {
     267             :   public:
     268             :     typedef mozilla::gfx::Matrix4x4 Matrix4x4;
     269             : 
     270          53 :     Preserves3DContext()
     271          53 :       : mAccumulatedRectLevels(0)
     272          53 :     {}
     273           0 :     Preserves3DContext(const Preserves3DContext &aOther)
     274           0 :       : mAccumulatedTransform()
     275             :       , mAccumulatedRect()
     276             :       , mAccumulatedRectLevels(0)
     277           0 :       , mDirtyRect(aOther.mDirtyRect) {}
     278             : 
     279             :     // Accmulate transforms of ancestors on the preserves-3d chain.
     280             :     Matrix4x4 mAccumulatedTransform;
     281             :     // Accmulate visible rect of descendants in the preserves-3d context.
     282             :     nsRect mAccumulatedRect;
     283             :     // How far this frame is from the root of the current 3d context.
     284             :     int mAccumulatedRectLevels;
     285             :     nsRect mDirtyRect;
     286             :   };
     287             : 
     288             :   /**
     289             :    * A frame can be in one of three states of AGR.
     290             :    * AGR_NO     means the frame is not an AGR for now.
     291             :    * AGR_YES    means the frame is an AGR for now.
     292             :    * AGR_MAYBE  means the frame is not an AGR for now, but a transition
     293             :    *            to AGR_YES without restyling is possible.
     294             :    */
     295             :   enum AGRState { AGR_NO, AGR_YES, AGR_MAYBE };
     296             : 
     297             : public:
     298             :   typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
     299             :   typedef mozilla::DisplayItemClip DisplayItemClip;
     300             :   typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
     301             :   typedef mozilla::DisplayListClipState DisplayListClipState;
     302             :   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
     303             :   typedef nsIWidget::ThemeGeometry ThemeGeometry;
     304             :   typedef mozilla::layers::Layer Layer;
     305             :   typedef mozilla::layers::FrameMetrics FrameMetrics;
     306             :   typedef mozilla::layers::FrameMetrics::ViewID ViewID;
     307             :   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
     308             : 
     309             :   /**
     310             :    * @param aReferenceFrame the frame at the root of the subtree; its origin
     311             :    * is the origin of the reference coordinate system for this display list
     312             :    * @param aMode encodes what the builder is being used for.
     313             :    * @param aBuildCaret whether or not we should include the caret in any
     314             :    * display lists that we make.
     315             :    */
     316             :   nsDisplayListBuilder(nsIFrame* aReferenceFrame,
     317             :                        nsDisplayListBuilderMode aMode,
     318             :                        bool aBuildCaret);
     319             :   ~nsDisplayListBuilder();
     320             : 
     321           0 :   void SetWillComputePluginGeometry(bool aWillComputePluginGeometry)
     322             :   {
     323           0 :     mWillComputePluginGeometry = aWillComputePluginGeometry;
     324           0 :   }
     325           0 :   void SetForPluginGeometry()
     326             :   {
     327           0 :     NS_ASSERTION(mMode == nsDisplayListBuilderMode::PAINTING, "Can only switch from PAINTING to PLUGIN_GEOMETRY");
     328           0 :     NS_ASSERTION(mWillComputePluginGeometry, "Should have signalled this in advance");
     329           0 :     mMode = nsDisplayListBuilderMode::PLUGIN_GEOMETRY;
     330           0 :   }
     331             : 
     332             :   mozilla::layers::LayerManager* GetWidgetLayerManager(nsView** aView = nullptr);
     333             : 
     334             :   /**
     335             :    * @return true if the display is being built in order to determine which
     336             :    * frame is under the mouse position.
     337             :    */
     338        4705 :   bool IsForEventDelivery()
     339             :   {
     340        4705 :     return mMode == nsDisplayListBuilderMode::EVENT_DELIVERY;
     341             :   }
     342             : 
     343             :   /**
     344             :    * Be careful with this. The display list will be built in PAINTING mode
     345             :    * first and then switched to PLUGIN_GEOMETRY before a second call to
     346             :    * ComputeVisibility.
     347             :    * @return true if the display list is being built to compute geometry
     348             :    * for plugins.
     349             :    */
     350         349 :   bool IsForPluginGeometry()
     351             :   {
     352         349 :     return mMode == nsDisplayListBuilderMode::PLUGIN_GEOMETRY;
     353             :   }
     354             : 
     355             :   /**
     356             :    * @return true if the display list is being built for painting.
     357             :    */
     358        2878 :   bool IsForPainting()
     359             :   {
     360        2878 :     return mMode == nsDisplayListBuilderMode::PAINTING;
     361             :   }
     362             : 
     363             :   /**
     364             :    * @return true if the display list is being built for determining frame
     365             :    * visibility.
     366             :    */
     367         697 :   bool IsForFrameVisibility()
     368             :   {
     369         697 :     return mMode == nsDisplayListBuilderMode::FRAME_VISIBILITY;
     370             :   }
     371             : 
     372             :   /**
     373             :    * @return true if the display list is being built for creating the glyph
     374             :    * mask from text items.
     375             :    */
     376        4775 :   bool IsForGenerateGlyphMask()
     377             :   {
     378        4775 :     return mMode == nsDisplayListBuilderMode::GENERATE_GLYPH;
     379             :   }
     380             : 
     381             :   /**
     382             :    * @return true if the display list is being built for painting selection
     383             :    * background.
     384             :    */
     385        4775 :   bool IsForPaintingSelectionBG()
     386             :   {
     387        4775 :     return mMode == nsDisplayListBuilderMode::PAINTING_SELECTION_BACKGROUND;
     388             :   }
     389             : 
     390          74 :   bool WillComputePluginGeometry() { return mWillComputePluginGeometry; }
     391             :   /**
     392             :    * @return true if "painting is suppressed" during page load and we
     393             :    * should paint only the background of the document.
     394             :    */
     395        5451 :   bool IsBackgroundOnly() {
     396        5451 :     NS_ASSERTION(mPresShellStates.Length() > 0,
     397             :                  "don't call this if we're not in a presshell");
     398        5451 :     return CurrentPresShellState()->mIsBackgroundOnly;
     399             :   }
     400             :   /**
     401             :    * @return true if the currently active BuildDisplayList call is being
     402             :    * applied to a frame at the root of a pseudo stacking context. A pseudo
     403             :    * stacking context is either a real stacking context or basically what
     404             :    * CSS2.1 appendix E refers to with "treat the element as if it created
     405             :    * a new stacking context
     406             :    */
     407             :   bool IsAtRootOfPseudoStackingContext() { return mIsAtRootOfPseudoStackingContext; }
     408             : 
     409             :   /**
     410             :    * @return the selection that painting should be restricted to (or nullptr
     411             :    * in the normal unrestricted case)
     412             :    */
     413        3751 :   nsISelection* GetBoundingSelection() { return mBoundingSelection; }
     414             : 
     415             :   /**
     416             :    * @return the root of given frame's (sub)tree, whose origin
     417             :    * establishes the coordinate system for the child display items.
     418             :    */
     419             :   const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame,
     420             :                                         nsPoint* aOffset = nullptr);
     421             : 
     422             :   /**
     423             :    * @return the root of the display list's frame (sub)tree, whose origin
     424             :    * establishes the coordinate system for the display list
     425             :    */
     426        8186 :   nsIFrame* RootReferenceFrame()
     427             :   {
     428        8186 :     return mReferenceFrame;
     429             :   }
     430             : 
     431             :   /**
     432             :    * @return a point pt such that adding pt to a coordinate relative to aFrame
     433             :    * makes it relative to ReferenceFrame(), i.e., returns
     434             :    * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
     435             :    * the appunits of aFrame.
     436             :    */
     437        4559 :   const nsPoint ToReferenceFrame(const nsIFrame* aFrame) {
     438        4559 :     nsPoint result;
     439        4559 :     FindReferenceFrameFor(aFrame, &result);
     440        4559 :     return result;
     441             :   }
     442             :   /**
     443             :    * When building the display list, the scrollframe aFrame will be "ignored"
     444             :    * for the purposes of clipping, and its scrollbars will be hidden. We use
     445             :    * this to allow RenderOffscreen to render a whole document without beign
     446             :    * clipped by the viewport or drawing the viewport scrollbars.
     447             :    */
     448          18 :   void SetIgnoreScrollFrame(nsIFrame* aFrame) { mIgnoreScrollFrame = aFrame; }
     449             :   /**
     450             :    * Get the scrollframe to ignore, if any.
     451             :    */
     452        3762 :   nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
     453             :   /**
     454             :    * Get the ViewID of the nearest scrolling ancestor frame.
     455             :    */
     456         460 :   ViewID GetCurrentScrollParentId() const { return mCurrentScrollParentId; }
     457             :   /**
     458             :    * Get and set the flag that indicates if scroll parents should have layers
     459             :    * forcibly created. This flag is set when a deeply nested scrollframe has
     460             :    * a displayport, and for scroll handoff to work properly the ancestor
     461             :    * scrollframes should also get their own scrollable layers.
     462             :    */
     463           2 :   void ForceLayerForScrollParent() { mForceLayerForScrollParent = true; }
     464             :   /**
     465             :    * Get the ViewID and the scrollbar flags corresponding to the scrollbar for
     466             :    * which we are building display items at the moment.
     467             :    */
     468           0 :   ViewID GetCurrentScrollbarTarget() const { return mCurrentScrollbarTarget; }
     469           0 :   uint32_t GetCurrentScrollbarFlags() const { return mCurrentScrollbarFlags; }
     470             :   /**
     471             :    * Returns true if building a scrollbar, and the scrollbar will not be
     472             :    * layerized.
     473             :    */
     474        2125 :   bool IsBuildingNonLayerizedScrollbar() const {
     475        2125 :     return mIsBuildingScrollbar && !mCurrentScrollbarWillHaveLayer;
     476             :   }
     477             :   /**
     478             :    * Calling this setter makes us include all out-of-flow descendant
     479             :    * frames in the display list, wherever they may be positioned (even
     480             :    * outside the dirty rects).
     481             :    */
     482           0 :   void SetIncludeAllOutOfFlows() { mIncludeAllOutOfFlows = true; }
     483        4384 :   bool GetIncludeAllOutOfFlows() const { return mIncludeAllOutOfFlows; }
     484             :   /**
     485             :    * Calling this setter makes us exclude all leaf frames that aren't
     486             :    * selected.
     487             :    */
     488           0 :   void SetSelectedFramesOnly() { mSelectedFramesOnly = true; }
     489        4147 :   bool GetSelectedFramesOnly() { return mSelectedFramesOnly; }
     490             :   /**
     491             :    * Calling this setter makes us compute accurate visible regions at the cost
     492             :    * of performance if regions get very complex.
     493             :    */
     494           0 :   void SetAccurateVisibleRegions() { mAccurateVisibleRegions = true; }
     495          52 :   bool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; }
     496             :   /**
     497             :    * @return Returns true if we should include the caret in any display lists
     498             :    * that we make.
     499             :    */
     500         112 :   bool IsBuildingCaret() { return mBuildCaret; }
     501             :   /**
     502             :    * Allows callers to selectively override the regular paint suppression checks,
     503             :    * so that methods like GetFrameForPoint work when painting is suppressed.
     504             :    */
     505          18 :   void IgnorePaintSuppression() { mIgnoreSuppression = true; }
     506             :   /**
     507             :    * @return Returns if this builder will ignore paint suppression.
     508             :    */
     509           0 :   bool IsIgnoringPaintSuppression() { return mIgnoreSuppression; }
     510             :   /**
     511             :    * Call this if we're doing normal painting to the window.
     512             :    */
     513          26 :   void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; }
     514       16074 :   bool IsPaintingToWindow() const { return mIsPaintingToWindow; }
     515             :   /**
     516             :    * Call this to prevent descending into subdocuments.
     517             :    */
     518           0 :   void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; }
     519          33 :   bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
     520             : 
     521             :   /**
     522             :    * Get dirty rect relative to current frame (the frame that we're calling
     523             :    * BuildDisplayList on right now).
     524             :    */
     525        5226 :   const nsRect& GetDirtyRect() { return mDirtyRect; }
     526             :   const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
     527           0 :   const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
     528        2613 :   const nsPoint& GetCurrentFrameOffsetToReferenceFrame() { return mCurrentOffsetToReferenceFrame; }
     529             :   AnimatedGeometryRoot* GetCurrentAnimatedGeometryRoot() {
     530             :     return mCurrentAGR;
     531             :   }
     532          44 :   AnimatedGeometryRoot* GetRootAnimatedGeometryRoot() {
     533          44 :     return &mRootAGR;
     534             :   }
     535             : 
     536             :   void RecomputeCurrentAnimatedGeometryRoot();
     537             : 
     538             :   /**
     539             :    * Returns true if merging and flattening of display lists should be
     540             :    * performed while computing visibility.
     541             :    */
     542             :   bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; }
     543           0 :   void SetAllowMergingAndFlattening(bool aAllow) { mAllowMergingAndFlattening = aAllow; }
     544             : 
     545        2167 :   nsDisplayLayerEventRegions* GetLayerEventRegions() { return mLayerEventRegions; }
     546         785 :   void SetLayerEventRegions(nsDisplayLayerEventRegions* aItem)
     547             :   {
     548         785 :     mLayerEventRegions = aItem;
     549         785 :   }
     550             :   bool IsBuildingLayerEventRegions();
     551             :   static bool LayerEventRegionsEnabled();
     552        2838 :   bool IsInsidePointerEventsNoneDoc()
     553             :   {
     554        2838 :     return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
     555             :   }
     556             : 
     557        2125 :   bool GetAncestorHasApzAwareEventHandler() { return mAncestorHasApzAwareEventHandler; }
     558          72 :   void SetAncestorHasApzAwareEventHandler(bool aValue)
     559             :   {
     560          72 :     mAncestorHasApzAwareEventHandler = aValue;
     561          72 :   }
     562             : 
     563         231 :   bool HaveScrollableDisplayPort() const { return mHaveScrollableDisplayPort; }
     564           0 :   void SetHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = true; }
     565             : 
     566          88 :   bool SetIsCompositingCheap(bool aCompositingCheap) {
     567          88 :     bool temp = mIsCompositingCheap;
     568          88 :     mIsCompositingCheap = aCompositingCheap;
     569          88 :     return temp;
     570             :   }
     571           0 :   bool IsCompositingCheap() const { return mIsCompositingCheap; }
     572             :   /**
     573             :    * Display the caret if needed.
     574             :    */
     575        3083 :   void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect,
     576             :                     nsDisplayList* aList) {
     577        3083 :     nsIFrame* frame = GetCaretFrame();
     578        3083 :     if (aFrame == frame) {
     579           0 :       frame->DisplayCaret(this, aDirtyRect, aList);
     580             :     }
     581        3083 :   }
     582             :   /**
     583             :    * Get the frame that the caret is supposed to draw in.
     584             :    * If the caret is currently invisible, this will be null.
     585             :    */
     586        3083 :   nsIFrame* GetCaretFrame() {
     587        3083 :     return CurrentPresShellState()->mCaretFrame;
     588             :   }
     589             :   /**
     590             :    * Get the rectangle we're supposed to draw the caret into.
     591             :    */
     592           0 :   const nsRect& GetCaretRect() {
     593           0 :     return CurrentPresShellState()->mCaretRect;
     594             :   }
     595             :   /**
     596             :    * Get the caret associated with the current presshell.
     597             :    */
     598             :   nsCaret* GetCaret();
     599             :   /**
     600             :    * Notify the display list builder that we're entering a presshell.
     601             :    * aReferenceFrame should be a frame in the new presshell.
     602             :    * aPointerEventsNoneDoc should be set to true if the frame generating this
     603             :    * document is pointer-events:none.
     604             :    */
     605             :   void EnterPresShell(nsIFrame* aReferenceFrame,
     606             :                       bool aPointerEventsNoneDoc = false);
     607             :   /**
     608             :    * For print-preview documents, we sometimes need to build display items for
     609             :    * the same frames multiple times in the same presentation, with different
     610             :    * clipping. Between each such batch of items, call
     611             :    * ResetMarkedFramesForDisplayList to make sure that the results of
     612             :    * MarkFramesForDisplayList do not carry over between batches.
     613             :    */
     614             :   void ResetMarkedFramesForDisplayList();
     615             :   /**
     616             :    * Notify the display list builder that we're leaving a presshell.
     617             :    */
     618             :   void LeavePresShell(nsIFrame* aReferenceFrame, nsDisplayList* aPaintedContents);
     619             : 
     620             :   /**
     621             :    * Returns true if we're currently building a display list that's
     622             :    * directly or indirectly under an nsDisplayTransform.
     623             :    */
     624        1118 :   bool IsInTransform() const { return mInTransform; }
     625             :   /**
     626             :    * Indicate whether or not we're directly or indirectly under and
     627             :    * nsDisplayTransform or SVG foreignObject.
     628             :    */
     629           3 :   void SetInTransform(bool aInTransform) { mInTransform = aInTransform; }
     630             : 
     631             :   /**
     632             :    * Return true if we're currently building a display list for a
     633             :    * nested presshell.
     634             :    */
     635          53 :   bool IsInSubdocument() { return mPresShellStates.Length() > 1; }
     636             : 
     637             :   /**
     638             :    * Return true if we're currently building a display list for the presshell
     639             :    * of a chrome document, or if we're building the display list for a popup.
     640             :    */
     641           0 :   bool IsInChromeDocumentOrPopup() {
     642           0 :     return mIsInChromePresContext || mIsBuildingForPopup;
     643             :   }
     644             : 
     645             :   /**
     646             :    * @return true if images have been set to decode synchronously.
     647             :    */
     648         960 :   bool ShouldSyncDecodeImages() { return mSyncDecodeImages; }
     649             : 
     650             :   /**
     651             :    * Indicates whether we should synchronously decode images. If true, we decode
     652             :    * and draw whatever image data has been loaded. If false, we just draw
     653             :    * whatever has already been decoded.
     654             :    */
     655           0 :   void SetSyncDecodeImages(bool aSyncDecodeImages) {
     656           0 :     mSyncDecodeImages = aSyncDecodeImages;
     657           0 :   }
     658             : 
     659             :   /**
     660             :    * Helper method to generate background painting flags based on the
     661             :    * information available in the display list builder. Currently only
     662             :    * accounts for mSyncDecodeImages.
     663             :    */
     664             :   uint32_t GetBackgroundPaintFlags();
     665             : 
     666             :   /**
     667             :    * Subtracts aRegion from *aVisibleRegion. We avoid letting
     668             :    * aVisibleRegion become overcomplex by simplifying it if necessary ---
     669             :    * unless mAccurateVisibleRegions is set, in which case we let it
     670             :    * get arbitrarily complex.
     671             :    */
     672             :   void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
     673             :                                  const nsRegion& aRegion);
     674             : 
     675             :   /**
     676             :    * Mark the frames in aFrames to be displayed if they intersect aDirtyRect
     677             :    * (which is relative to aDirtyFrame). If the frames have placeholders
     678             :    * that might not be displayed, we mark the placeholders and their ancestors
     679             :    * to ensure that display list construction descends into them
     680             :    * anyway. nsDisplayListBuilder will take care of unmarking them when it is
     681             :    * destroyed.
     682             :    */
     683             :   void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
     684             :                                 const nsFrameList& aFrames,
     685             :                                 const nsRect& aDirtyRect);
     686             :   /**
     687             :    * Mark all child frames that Preserve3D() as needing display.
     688             :    * Because these frames include transforms set on their parent, dirty rects
     689             :    * for intermediate frames may be empty, yet child frames could still be visible.
     690             :    */
     691             :   void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame);
     692             : 
     693          26 :   const nsTArray<ThemeGeometry>& GetThemeGeometries() { return mThemeGeometries; }
     694             : 
     695             :   /**
     696             :    * Returns true if we need to descend into this frame when building
     697             :    * the display list, even though it doesn't intersect the dirty
     698             :    * rect, because it may have out-of-flows that do so.
     699             :    */
     700         272 :   bool ShouldDescendIntoFrame(nsIFrame* aFrame) const {
     701             :     return
     702         509 :       (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) ||
     703         509 :       GetIncludeAllOutOfFlows();
     704             :   }
     705             : 
     706             :   /**
     707             :    * Notifies the builder that a particular themed widget exists
     708             :    * at the given rectangle within the currently built display list.
     709             :    * For certain appearance values (currently only NS_THEME_TOOLBAR and
     710             :    * NS_THEME_WINDOW_TITLEBAR) this gets called during every display list
     711             :    * construction, for every themed widget of the right type within the
     712             :    * display list, except for themed widgets which are transformed or have
     713             :    * effects applied to them (e.g. CSS opacity or filters).
     714             :    *
     715             :    * @param aWidgetType the -moz-appearance value for the themed widget
     716             :    * @param aRect the device-pixel rect relative to the widget's displayRoot
     717             :    * for the themed widget
     718             :    */
     719           0 :   void RegisterThemeGeometry(uint8_t aWidgetType,
     720             :                              const mozilla::LayoutDeviceIntRect& aRect) {
     721           0 :     if (mIsPaintingToWindow) {
     722           0 :       mThemeGeometries.AppendElement(ThemeGeometry(aWidgetType, aRect));
     723             :     }
     724           0 :   }
     725             : 
     726             :   /**
     727             :    * Adjusts mWindowDraggingRegion to take into account aFrame. If aFrame's
     728             :    * -moz-window-dragging value is |drag|, its border box is added to the
     729             :    * collected dragging region; if the value is |no-drag|, the border box is
     730             :    * subtracted from the region; if the value is |default|, that frame does
     731             :    * not influence the window dragging region.
     732             :    */
     733             :   void AdjustWindowDraggingRegion(nsIFrame* aFrame);
     734             : 
     735             :   LayoutDeviceIntRegion GetWindowDraggingRegion() const;
     736             : 
     737             :   /**
     738             :    * Allocate memory in our arena. It will only be freed when this display list
     739             :    * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem
     740             :    * destructors are called as soon as the item is no longer used.
     741             :    */
     742             :   void* Allocate(size_t aSize);
     743             : 
     744             :   /**
     745             :    * Allocate a new ActiveScrolledRoot in the arena. Will be cleaned up
     746             :    * automatically when the arena goes away.
     747             :    */
     748             :   ActiveScrolledRoot* AllocateActiveScrolledRoot(const ActiveScrolledRoot* aParent,
     749             :                                                  nsIScrollableFrame* aScrollableFrame);
     750             : 
     751             :   /**
     752             :    * Allocate a new DisplayItemClipChain object in the arena. Will be cleaned
     753             :    * up automatically when the arena goes away.
     754             :    */
     755             :   const DisplayItemClipChain* AllocateDisplayItemClipChain(const DisplayItemClip& aClip,
     756             :                                                            const ActiveScrolledRoot* aASR,
     757             :                                                            const DisplayItemClipChain* aParent);
     758             : 
     759             :   /**
     760             :    * Intersect two clip chains, allocating the new clip chain items in this
     761             :    * builder's arena. The result is parented to aAncestor, and no intersections
     762             :    * happen past aAncestor's ASR.
     763             :    * That means aAncestor has to be living in this builder's arena already.
     764             :    * aLeafClip1 and aLeafClip2 only need to outlive the call to this function,
     765             :    * their values are copied into the newly-allocated intersected clip chain
     766             :    * and this function does not hold on to any pointers to them.
     767             :    */
     768             :   const DisplayItemClipChain* CreateClipChainIntersection(const DisplayItemClipChain* aAncestor,
     769             :                                                           const DisplayItemClipChain* aLeafClip1,
     770             :                                                           const DisplayItemClipChain* aLeafClip2);
     771             : 
     772             :   /**
     773             :    * Clone the supplied clip chain's chain items into this builder's arena.
     774             :    */
     775             :   const DisplayItemClipChain* CopyWholeChain(const DisplayItemClipChain* aClipChain);
     776             : 
     777             :   /**
     778             :    * Only used for containerful root scrolling. This is a workaround.
     779             :    */
     780           0 :   void SetActiveScrolledRootForRootScrollframe(const ActiveScrolledRoot* aASR)
     781           0 :   { mActiveScrolledRootForRootScrollframe = aASR; }
     782           0 :   const ActiveScrolledRoot* ActiveScrolledRootForRootScrollframe() const
     783           0 :   { return mActiveScrolledRootForRootScrollframe; }
     784             : 
     785             :   /**
     786             :    * Transfer off main thread animations to the layer.  May be called
     787             :    * with aBuilder and aItem both null, but only if the caller has
     788             :    * already checked that off main thread animations should be sent to
     789             :    * the layer.  When they are both null, the animations are added to
     790             :    * the layer as pending animations.
     791             :    */
     792             :   static void AddAnimationsAndTransitionsToLayer(Layer* aLayer,
     793             :                                                  nsDisplayListBuilder* aBuilder,
     794             :                                                  nsDisplayItem* aItem,
     795             :                                                  nsIFrame* aFrame,
     796             :                                                  nsCSSPropertyID aProperty);
     797             : 
     798             :   /**
     799             :    * A helper class to temporarily set the value of
     800             :    * mIsAtRootOfPseudoStackingContext, and temporarily
     801             :    * set mCurrentFrame and related state. Also temporarily sets mDirtyRect.
     802             :    * aDirtyRect is relative to aForChild.
     803             :    */
     804             :   class AutoBuildingDisplayList;
     805             :   friend class AutoBuildingDisplayList;
     806             :   class AutoBuildingDisplayList {
     807             :   public:
     808        3746 :     AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
     809             :                             nsIFrame* aForChild,
     810             :                             const nsRect& aDirtyRect, bool aIsRoot)
     811        3746 :       : mBuilder(aBuilder),
     812        3746 :         mPrevFrame(aBuilder->mCurrentFrame),
     813        3746 :         mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
     814        3746 :         mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
     815             :         mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
     816             :         mPrevDirtyRect(aBuilder->mDirtyRect),
     817        3746 :         mPrevAGR(aBuilder->mCurrentAGR),
     818        3746 :         mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
     819        3746 :         mPrevAncestorHasApzAwareEventHandler(aBuilder->mAncestorHasApzAwareEventHandler),
     820       26222 :         mPrevBuildingInvisibleItems(aBuilder->mBuildingInvisibleItems)
     821             :     {
     822        3746 :       if (aForChild->IsTransformed()) {
     823          48 :         aBuilder->mCurrentOffsetToReferenceFrame = nsPoint();
     824          48 :         aBuilder->mCurrentReferenceFrame = aForChild;
     825        3698 :       } else if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
     826        2980 :         aBuilder->mCurrentOffsetToReferenceFrame += aForChild->GetPosition();
     827             :       } else {
     828         718 :         aBuilder->mCurrentReferenceFrame =
     829         718 :           aBuilder->FindReferenceFrameFor(aForChild,
     830             :               &aBuilder->mCurrentOffsetToReferenceFrame);
     831             :       }
     832        3746 :       mCurrentAGRState = aBuilder->IsAnimatedGeometryRoot(aForChild);
     833        3746 :       if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
     834        3004 :         if (mCurrentAGRState == AGR_YES) {
     835           2 :           aBuilder->mCurrentAGR = aBuilder->WrapAGRForFrame(aForChild, aBuilder->mCurrentAGR);
     836             :         }
     837         742 :       } else if (aForChild != aBuilder->mCurrentFrame) {
     838          85 :         aBuilder->mCurrentAGR = aBuilder->FindAnimatedGeometryRootFor(aForChild);
     839             :       }
     840        3746 :       MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR));
     841        3746 :       aBuilder->mCurrentFrame = aForChild;
     842        3746 :       aBuilder->mDirtyRect = aDirtyRect;
     843        3746 :       aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
     844        3746 :     }
     845          31 :     void SetDirtyRect(const nsRect& aRect) {
     846          31 :       mBuilder->mDirtyRect = aRect;
     847          31 :     }
     848          24 :     void SetReferenceFrameAndCurrentOffset(const nsIFrame* aFrame, const nsPoint& aOffset) {
     849          24 :       mBuilder->mCurrentReferenceFrame = aFrame;
     850          24 :       mBuilder->mCurrentOffsetToReferenceFrame = aOffset;
     851          24 :     }
     852             :     // Return the previous frame's animated geometry root, whether or not the
     853             :     // current frame is an immediate descendant.
     854             :     const nsIFrame* GetPrevAnimatedGeometryRoot() const {
     855             :       return mPrevAnimatedGeometryRoot;
     856             :     }
     857         544 :     bool IsAnimatedGeometryRoot() const {
     858         544 :       return mCurrentAGRState == AGR_YES;
     859             :     }
     860         386 :     bool MaybeAnimatedGeometryRoot() const {
     861         386 :       return mCurrentAGRState == AGR_MAYBE;
     862             :     }
     863         691 :     void RestoreBuildingInvisibleItemsValue() {
     864         691 :       mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
     865         691 :     }
     866        7492 :     ~AutoBuildingDisplayList() {
     867        3746 :       mBuilder->mCurrentFrame = mPrevFrame;
     868        3746 :       mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
     869        3746 :       mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
     870        3746 :       mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
     871        3746 :       mBuilder->mDirtyRect = mPrevDirtyRect;
     872        3746 :       mBuilder->mCurrentAGR = mPrevAGR;
     873        3746 :       mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
     874        3746 :       mBuilder->mAncestorHasApzAwareEventHandler = mPrevAncestorHasApzAwareEventHandler;
     875        3746 :       mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
     876        3746 :     }
     877             :   private:
     878             :     nsDisplayListBuilder* mBuilder;
     879             :     AGRState              mCurrentAGRState;
     880             :     const nsIFrame*       mPrevFrame;
     881             :     const nsIFrame*       mPrevReferenceFrame;
     882             :     nsIFrame*             mPrevAnimatedGeometryRoot;
     883             :     nsDisplayLayerEventRegions* mPrevLayerEventRegions;
     884             :     nsPoint               mPrevOffset;
     885             :     nsRect                mPrevDirtyRect;
     886             :     AnimatedGeometryRoot* mPrevAGR;
     887             :     bool                  mPrevIsAtRootOfPseudoStackingContext;
     888             :     bool                  mPrevAncestorHasApzAwareEventHandler;
     889             :     bool                  mPrevBuildingInvisibleItems;
     890             :   };
     891             : 
     892             :   /**
     893             :    * A helper class to temporarily set the value of mInTransform.
     894             :    */
     895             :   class AutoInTransformSetter;
     896             :   friend class AutoInTransformSetter;
     897             :   class AutoInTransformSetter {
     898             :   public:
     899         613 :     AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform)
     900         613 :       : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) {
     901         613 :       aBuilder->mInTransform = aInTransform;
     902         613 :     }
     903        1226 :     ~AutoInTransformSetter() {
     904         613 :       mBuilder->mInTransform = mOldValue;
     905         613 :     }
     906             :   private:
     907             :     nsDisplayListBuilder* mBuilder;
     908             :     bool                  mOldValue;
     909             :   };
     910             : 
     911             :   class AutoSaveRestorePerspectiveIndex;
     912             :   friend class AutoSaveRestorePerspectiveIndex;
     913             :   class AutoSaveRestorePerspectiveIndex {
     914             :   public:
     915         613 :     AutoSaveRestorePerspectiveIndex(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     916         613 :       : mBuilder(nullptr)
     917             :     {
     918         613 :       if (aFrame->ChildrenHavePerspective()) {
     919           0 :         mBuilder = aBuilder;
     920           0 :         mCachedItemIndex = aBuilder->mPerspectiveItemIndex;
     921           0 :         aBuilder->mPerspectiveItemIndex = 0;
     922             :       }
     923         613 :     }
     924             : 
     925         613 :     ~AutoSaveRestorePerspectiveIndex()
     926         613 :     {
     927         613 :       if (mBuilder) {
     928           0 :         mBuilder->mPerspectiveItemIndex = mCachedItemIndex;
     929             :       }
     930         613 :     }
     931             : 
     932             :   private:
     933             :     nsDisplayListBuilder* mBuilder;
     934             :     uint32_t mCachedItemIndex;
     935             :   };
     936             : 
     937             :   /**
     938             :    * A helper class to temporarily set the value of mCurrentScrollParentId.
     939             :    */
     940             :   class AutoCurrentScrollParentIdSetter;
     941             :   friend class AutoCurrentScrollParentIdSetter;
     942             :   class AutoCurrentScrollParentIdSetter {
     943             :   public:
     944         275 :     AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollId)
     945         275 :       : mBuilder(aBuilder)
     946         275 :       , mOldValue(aBuilder->mCurrentScrollParentId)
     947         550 :       , mOldForceLayer(aBuilder->mForceLayerForScrollParent) {
     948             :       // If this AutoCurrentScrollParentIdSetter has the same scrollId as the
     949             :       // previous one on the stack, then that means the scrollframe that
     950             :       // created this isn't actually scrollable and cannot participate in
     951             :       // scroll handoff. We set mCanBeScrollParent to false to indicate this.
     952         275 :       mCanBeScrollParent = (mOldValue != aScrollId);
     953         275 :       aBuilder->mCurrentScrollParentId = aScrollId;
     954         275 :       aBuilder->mForceLayerForScrollParent = false;
     955         275 :     }
     956         462 :     bool ShouldForceLayerForScrollParent() const {
     957             :       // Only scrollframes participating in scroll handoff can be forced to
     958             :       // layerize
     959         462 :       return mCanBeScrollParent && mBuilder->mForceLayerForScrollParent;
     960             :     };
     961         550 :     ~AutoCurrentScrollParentIdSetter() {
     962         275 :       mBuilder->mCurrentScrollParentId = mOldValue;
     963         275 :       if (mCanBeScrollParent) {
     964             :         // If this flag is set, caller code is responsible for having dealt
     965             :         // with the current value of mBuilder->mForceLayerForScrollParent, so
     966             :         // we can just restore the old value.
     967          26 :         mBuilder->mForceLayerForScrollParent = mOldForceLayer;
     968             :       } else {
     969             :         // Otherwise we need to keep propagating the force-layerization flag
     970             :         // upwards to the next ancestor scrollframe that does participate in
     971             :         // scroll handoff.
     972         249 :         mBuilder->mForceLayerForScrollParent |= mOldForceLayer;
     973             :       }
     974         275 :     }
     975             :   private:
     976             :     nsDisplayListBuilder* mBuilder;
     977             :     ViewID                mOldValue;
     978             :     bool                  mOldForceLayer;
     979             :     bool                  mCanBeScrollParent;
     980             :   };
     981             : 
     982             :   /**
     983             :    * Used to update the current active scrolled root on the display list
     984             :    * builder, and to create new active scrolled roots.
     985             :    */
     986             :   class AutoCurrentActiveScrolledRootSetter;
     987             :   friend class AutoCurrentActiveScrolledRootSetter;
     988             :   class AutoCurrentActiveScrolledRootSetter {
     989             :   public:
     990        1613 :     explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
     991        1613 :       : mBuilder(aBuilder)
     992        1613 :       , mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot)
     993        1613 :       , mContentClipASR(aBuilder->ClipState().GetContentClipASR())
     994        1613 :       , mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length())
     995        6452 :       , mUsed(false)
     996             :     {
     997        1613 :     }
     998             : 
     999        1613 :     ~AutoCurrentActiveScrolledRootSetter()
    1000        1613 :     {
    1001        1613 :       mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
    1002        1613 :     }
    1003             : 
    1004          85 :     void SetCurrentActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot)
    1005             :     {
    1006          85 :       MOZ_ASSERT(!mUsed);
    1007             : 
    1008             :       // Set the builder's mCurrentActiveScrolledRoot.
    1009          85 :       mBuilder->mCurrentActiveScrolledRoot = aActiveScrolledRoot;
    1010             : 
    1011             :       // We also need to adjust the builder's mCurrentContainerASR.
    1012             :       // mCurrentContainerASR needs to be an ASR that all the container's
    1013             :       // contents have finite bounds with respect to. If aActiveScrolledRoot
    1014             :       // is an ancestor ASR of mCurrentContainerASR, that means we need to
    1015             :       // set mCurrentContainerASR to aActiveScrolledRoot, because otherwise
    1016             :       // the items that will be created with aActiveScrolledRoot wouldn't
    1017             :       // have finite bounds with respect to mCurrentContainerASR. There's one
    1018             :       // exception, in the case where there's a content clip on the builder
    1019             :       // that is scrolled by a descendant ASR of aActiveScrolledRoot. This
    1020             :       // content clip will clip all items that are created while this
    1021             :       // AutoCurrentActiveScrolledRootSetter exists. This means that the items
    1022             :       // created during our lifetime will have finite bounds with respect to
    1023             :       // the content clip's ASR, even if the items' actual ASR is an ancestor
    1024             :       // of that. And it also means that mCurrentContainerASR only needs to be
    1025             :       // set to the content clip's ASR and not all the way to aActiveScrolledRoot.
    1026             :       // This case is tested by fixed-pos-scrolled-clip-opacity-layerize.html
    1027             :       // and fixed-pos-scrolled-clip-opacity-inside-layerize.html.
    1028             : 
    1029             :       // finiteBoundsASR is the leafmost ASR that all items created during
    1030             :       // object's lifetime have finite bounds with respect to.
    1031          85 :       const ActiveScrolledRoot* finiteBoundsASR = ActiveScrolledRoot::PickDescendant(
    1032          85 :         mContentClipASR, aActiveScrolledRoot);
    1033             : 
    1034             :       // mCurrentContainerASR is adjusted so that it's still an ancestor of
    1035             :       // finiteBoundsASR.
    1036         170 :       mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickAncestor(
    1037          85 :         mBuilder->mCurrentContainerASR, finiteBoundsASR);
    1038             : 
    1039          85 :       mUsed = true;
    1040          85 :     }
    1041             : 
    1042           2 :     void EnterScrollFrame(nsIScrollableFrame* aScrollableFrame)
    1043             :     {
    1044           2 :       MOZ_ASSERT(!mUsed);
    1045           2 :       ActiveScrolledRoot* asr = mBuilder->AllocateActiveScrolledRoot(
    1046           4 :         mBuilder->mCurrentActiveScrolledRoot, aScrollableFrame);
    1047           2 :       mBuilder->mCurrentActiveScrolledRoot = asr;
    1048           2 :       mUsed = true;
    1049           2 :     }
    1050             : 
    1051             :     void InsertScrollFrame(nsIScrollableFrame* aScrollableFrame);
    1052             : 
    1053             :   private:
    1054             :     nsDisplayListBuilder* mBuilder;
    1055             :     /**
    1056             :      * The builder's mCurrentActiveScrolledRoot at construction time which
    1057             :      * needs to be restored at destruction time.
    1058             :      */
    1059             :     const ActiveScrolledRoot* mSavedActiveScrolledRoot;
    1060             :     /**
    1061             :      * If there's a content clip on the builder at construction time, then
    1062             :      * mContentClipASR is that content clip's ASR, otherwise null. The
    1063             :      * assumption is that the content clip doesn't get relaxed while this
    1064             :      * object is on the stack.
    1065             :      */
    1066             :     const ActiveScrolledRoot* mContentClipASR;
    1067             :     /**
    1068             :      * InsertScrollFrame needs to mutate existing ASRs (those that were
    1069             :      * created while this object was on the stack), and mDescendantsStartIndex
    1070             :      * makes it easier to skip ASRs that were created in the past.
    1071             :      */
    1072             :     size_t mDescendantsStartIndex;
    1073             :     /**
    1074             :      * Flag to make sure that only one of SetCurrentActiveScrolledRoot /
    1075             :      * EnterScrollFrame / InsertScrollFrame is called per instance of this
    1076             :      * class.
    1077             :      */
    1078             :     bool mUsed;
    1079             :   };
    1080             : 
    1081             :   /**
    1082             :    * Keeps track of the innermost ASR that can be used as the ASR for a
    1083             :    * container item that wraps all items that were created while this
    1084             :    * object was on the stack.
    1085             :    * The rule is: all child items of the container item need to have
    1086             :    * clipped bounds with respect to the container ASR.
    1087             :    */
    1088             :   class AutoContainerASRTracker;
    1089             :   friend class AutoContainerASRTracker;
    1090             :   class AutoContainerASRTracker {
    1091             :   public:
    1092        1324 :     explicit AutoContainerASRTracker(nsDisplayListBuilder* aBuilder)
    1093        1324 :       : mBuilder(aBuilder)
    1094        1324 :       , mSavedContainerASR(aBuilder->mCurrentContainerASR)
    1095             :     {
    1096        3972 :       mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickDescendant(
    1097        1324 :         mBuilder->ClipState().GetContentClipASR(),
    1098        1324 :         mBuilder->mCurrentActiveScrolledRoot);
    1099        1324 :     }
    1100             : 
    1101        1304 :     const ActiveScrolledRoot* GetContainerASR()
    1102             :     {
    1103        1304 :       return mBuilder->mCurrentContainerASR;
    1104             :     }
    1105             : 
    1106        1324 :     ~AutoContainerASRTracker()
    1107        1324 :     {
    1108        2648 :       mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickAncestor(
    1109        1324 :         mBuilder->mCurrentContainerASR, mSavedContainerASR);
    1110        1324 :     }
    1111             : 
    1112             :   private:
    1113             :     nsDisplayListBuilder* mBuilder;
    1114             :     const ActiveScrolledRoot* mSavedContainerASR;
    1115             :   };
    1116             : 
    1117             :   /**
    1118             :    * A helper class to temporarily set the value of mCurrentScrollbarTarget
    1119             :    * and mCurrentScrollbarFlags.
    1120             :    */
    1121             :   class AutoCurrentScrollbarInfoSetter;
    1122             :   friend class AutoCurrentScrollbarInfoSetter;
    1123             :   class AutoCurrentScrollbarInfoSetter {
    1124             :   public:
    1125           6 :     AutoCurrentScrollbarInfoSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollTargetID,
    1126             :                                    uint32_t aScrollbarFlags, bool aWillHaveLayer)
    1127           6 :      : mBuilder(aBuilder) {
    1128           6 :       aBuilder->mIsBuildingScrollbar = true;
    1129           6 :       aBuilder->mCurrentScrollbarTarget = aScrollTargetID;
    1130           6 :       aBuilder->mCurrentScrollbarFlags = aScrollbarFlags;
    1131           6 :       aBuilder->mCurrentScrollbarWillHaveLayer = aWillHaveLayer;
    1132           6 :     }
    1133          12 :     ~AutoCurrentScrollbarInfoSetter() {
    1134             :       // No need to restore old values because scrollbars cannot be nested.
    1135           6 :       mBuilder->mIsBuildingScrollbar = false;
    1136           6 :       mBuilder->mCurrentScrollbarTarget = FrameMetrics::NULL_SCROLL_ID;
    1137           6 :       mBuilder->mCurrentScrollbarFlags = 0;
    1138           6 :       mBuilder->mCurrentScrollbarWillHaveLayer = false;
    1139           6 :     }
    1140             :   private:
    1141             :     nsDisplayListBuilder* mBuilder;
    1142             :   };
    1143             : 
    1144             :   /**
    1145             :    * A helper class to track current effective transform for items.
    1146             :    *
    1147             :    * For frames that is Combines3DTransformWithAncestors(), we need to
    1148             :    * apply all transforms of ancestors on the same preserves3D chain
    1149             :    * on the bounds of current frame to the coordination of the 3D
    1150             :    * context root.  The 3D context root computes it's bounds from
    1151             :    * these transformed bounds.
    1152             :    */
    1153             :   class AutoAccumulateTransform;
    1154             :   friend class AutoAccumulateTransform;
    1155             :   class AutoAccumulateTransform {
    1156             :   public:
    1157             :     typedef mozilla::gfx::Matrix4x4 Matrix4x4;
    1158             : 
    1159           0 :     explicit AutoAccumulateTransform(nsDisplayListBuilder* aBuilder)
    1160           0 :       : mBuilder(aBuilder)
    1161           0 :       , mSavedTransform(aBuilder->mPreserves3DCtx.mAccumulatedTransform) {}
    1162             : 
    1163           0 :     ~AutoAccumulateTransform() {
    1164           0 :       mBuilder->mPreserves3DCtx.mAccumulatedTransform = mSavedTransform;
    1165           0 :     }
    1166             : 
    1167           0 :     void Accumulate(const Matrix4x4& aTransform) {
    1168           0 :       mBuilder->mPreserves3DCtx.mAccumulatedTransform =
    1169           0 :         aTransform * mBuilder->mPreserves3DCtx.mAccumulatedTransform;
    1170           0 :     }
    1171             : 
    1172           0 :     const Matrix4x4& GetCurrentTransform() {
    1173           0 :       return mBuilder->mPreserves3DCtx.mAccumulatedTransform;
    1174             :     }
    1175             : 
    1176           0 :     void StartRoot() {
    1177           0 :       mBuilder->mPreserves3DCtx.mAccumulatedTransform = Matrix4x4();
    1178           0 :     }
    1179             : 
    1180             :   private:
    1181             :     nsDisplayListBuilder* mBuilder;
    1182             :     Matrix4x4 mSavedTransform;
    1183             :   };
    1184             : 
    1185             :   /**
    1186             :    * A helper class to collect bounds rects of descendants.
    1187             :    *
    1188             :    * For a 3D context root, it's bounds is computed from the bounds of
    1189             :    * descendants.  If we transform bounds frame by frame applying
    1190             :    * transforms, the bounds may turn to empty for any singular
    1191             :    * transform on the path, but it is not empty for the accumulated
    1192             :    * transform.
    1193             :    */
    1194             :   class AutoAccumulateRect;
    1195             :   friend class AutoAccumulateRect;
    1196             :   class AutoAccumulateRect {
    1197             :   public:
    1198           0 :     explicit AutoAccumulateRect(nsDisplayListBuilder* aBuilder)
    1199           0 :       : mBuilder(aBuilder)
    1200           0 :       , mSavedRect(aBuilder->mPreserves3DCtx.mAccumulatedRect) {
    1201           0 :       aBuilder->mPreserves3DCtx.mAccumulatedRect = nsRect();
    1202           0 :       aBuilder->mPreserves3DCtx.mAccumulatedRectLevels++;
    1203           0 :     }
    1204           0 :     ~AutoAccumulateRect() {
    1205           0 :       mBuilder->mPreserves3DCtx.mAccumulatedRect = mSavedRect;
    1206           0 :       mBuilder->mPreserves3DCtx.mAccumulatedRectLevels--;
    1207           0 :     }
    1208             : 
    1209             :   private:
    1210             :     nsDisplayListBuilder* mBuilder;
    1211             :     nsRect mSavedRect;
    1212             :   };
    1213             : 
    1214           0 :   void AccumulateRect(const nsRect& aRect) {
    1215           0 :     mPreserves3DCtx.mAccumulatedRect.UnionRect(mPreserves3DCtx.mAccumulatedRect, aRect);
    1216           0 :   }
    1217           0 :   const nsRect& GetAccumulatedRect() {
    1218           0 :     return mPreserves3DCtx.mAccumulatedRect;
    1219             :   }
    1220             :   /**
    1221             :    * The level is increased by one for items establishing 3D rendering
    1222             :    * context and starting a new accumulation.
    1223             :    */
    1224             :   int GetAccumulatedRectLevels() {
    1225             :     return mPreserves3DCtx.mAccumulatedRectLevels;
    1226             :   }
    1227             : 
    1228             :   // Helpers for tables
    1229           0 :   nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
    1230           0 :   void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
    1231             : 
    1232         138 :   struct OutOfFlowDisplayData {
    1233         138 :     OutOfFlowDisplayData(const DisplayItemClipChain* aContainingBlockClipChain,
    1234             :                          const DisplayItemClipChain* aCombinedClipChain,
    1235             :                          const ActiveScrolledRoot* aContainingBlockActiveScrolledRoot,
    1236             :                          const nsRect &aDirtyRect)
    1237         138 :       : mContainingBlockClipChain(aContainingBlockClipChain)
    1238             :       , mCombinedClipChain(aCombinedClipChain)
    1239             :       , mContainingBlockActiveScrolledRoot(aContainingBlockActiveScrolledRoot)
    1240         138 :       , mDirtyRect(aDirtyRect)
    1241         138 :     {}
    1242             :     const DisplayItemClipChain* mContainingBlockClipChain;
    1243             :     const DisplayItemClipChain* mCombinedClipChain; // only necessary for the special case of top layer
    1244             :     const ActiveScrolledRoot* mContainingBlockActiveScrolledRoot;
    1245             :     nsRect mDirtyRect;
    1246             :   };
    1247             : 
    1248         282 :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(OutOfFlowDisplayDataProperty,
    1249             :                                       OutOfFlowDisplayData)
    1250             : 
    1251          85 :   static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)
    1252             :   {
    1253          85 :     return aFrame->GetProperty(OutOfFlowDisplayDataProperty());
    1254             :   }
    1255             : 
    1256           0 :   nsPresContext* CurrentPresContext() {
    1257           0 :     return CurrentPresShellState()->mPresShell->GetPresContext();
    1258             :   }
    1259             : 
    1260           0 :   OutOfFlowDisplayData* GetCurrentFixedBackgroundDisplayData()
    1261             :   {
    1262           0 :     auto& displayData = CurrentPresShellState()->mFixedBackgroundDisplayData;
    1263           0 :     return displayData ? displayData.ptr() : nullptr;
    1264             :   }
    1265             : 
    1266             :   /**
    1267             :    * Accumulates the bounds of box frames that have moz-appearance
    1268             :    * -moz-win-exclude-glass style. Used in setting glass margins on
    1269             :    * Windows.
    1270             :    *
    1271             :    * We set the window opaque region (from which glass margins are computed)
    1272             :    * to the intersection of the glass region specified here and the opaque
    1273             :    * region computed during painting. So the excluded glass region actually
    1274             :    * *limits* the extent of the opaque area reported to Windows. We limit it
    1275             :    * so that changes to the computed opaque region (which can vary based on
    1276             :    * region optimizations and the placement of UI elements) outside the
    1277             :    * -moz-win-exclude-glass area don't affect the glass margins reported to
    1278             :    * Windows; changing those margins willy-nilly can cause the Windows 7 glass
    1279             :    * haze effect to jump around disconcertingly.
    1280             :    */
    1281           0 :   void AddWindowExcludeGlassRegion(const nsRegion& bounds) {
    1282           0 :     mWindowExcludeGlassRegion.Or(mWindowExcludeGlassRegion, bounds);
    1283           0 :   }
    1284          26 :   const nsRegion& GetWindowExcludeGlassRegion() {
    1285          26 :     return mWindowExcludeGlassRegion;
    1286             :   }
    1287             :   /**
    1288             :    * Accumulates opaque stuff into the window opaque region.
    1289             :    */
    1290         172 :   void AddWindowOpaqueRegion(const nsRegion& bounds) {
    1291         172 :     mWindowOpaqueRegion.Or(mWindowOpaqueRegion, bounds);
    1292         172 :   }
    1293             :   /**
    1294             :    * Returns the window opaque region built so far. This may be incomplete
    1295             :    * since the opaque region is built during layer construction.
    1296             :    */
    1297          31 :   const nsRegion& GetWindowOpaqueRegion() {
    1298          31 :     return mWindowOpaqueRegion;
    1299             :   }
    1300           0 :   void SetGlassDisplayItem(nsDisplayItem* aItem) {
    1301           0 :     if (mGlassDisplayItem) {
    1302             :       // Web pages or extensions could trigger this by using
    1303             :       // -moz-appearance:win-borderless-glass etc on their own elements.
    1304             :       // Keep the first one, since that will be the background of the root
    1305             :       // window
    1306           0 :       NS_WARNING("Multiple glass backgrounds found?");
    1307             :     } else {
    1308           0 :       mGlassDisplayItem = aItem;
    1309             :     }
    1310           0 :   }
    1311             :   bool NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem);
    1312             : 
    1313           0 :   void SetContainsPluginItem() { mContainsPluginItem = true; }
    1314           0 :   bool ContainsPluginItem() { return mContainsPluginItem; }
    1315             : 
    1316             :   /**
    1317             :    * mContainsBlendMode is true if we processed a display item that
    1318             :    * has a blend mode attached. We do this so we can insert a
    1319             :    * nsDisplayBlendContainer in the parent stacking context.
    1320             :    */
    1321        1226 :   void SetContainsBlendMode(bool aContainsBlendMode) { mContainsBlendMode = aContainsBlendMode; }
    1322        1226 :   bool ContainsBlendMode() const { return mContainsBlendMode; }
    1323             : 
    1324           0 :   uint32_t AllocatePerspectiveItemIndex() { return mPerspectiveItemIndex++; }
    1325             : 
    1326       16487 :   DisplayListClipState& ClipState() { return mClipState; }
    1327        6973 :   const ActiveScrolledRoot* CurrentActiveScrolledRoot() { return mCurrentActiveScrolledRoot; }
    1328             :   const ActiveScrolledRoot* CurrentAncestorASRStackingContextContents() { return mCurrentContainerASR; }
    1329             : 
    1330             :   /**
    1331             :    * Add the current frame to the will-change budget if possible and
    1332             :    * remeber the outcome. Subsequent calls to IsInWillChangeBudget
    1333             :    * will return the same value as return here.
    1334             :    */
    1335             :   bool AddToWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
    1336             : 
    1337             :   /**
    1338             :    * This will add the current frame to the will-change budget the first
    1339             :    * time it is seen. On subsequent calls this will return the same
    1340             :    * answer. This effectively implements a first-come, first-served
    1341             :    * allocation of the will-change budget.
    1342             :    */
    1343             :   bool IsInWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
    1344             : 
    1345             :   void EnterSVGEffectsContents(nsDisplayList* aHoistedItemsStorage);
    1346             :   void ExitSVGEffectsContents();
    1347             : 
    1348             :   /**
    1349             :    * Note: if changing the conditions under which scroll info layers
    1350             :    * are created, make a corresponding change to
    1351             :    * ScrollFrameWillBuildScrollInfoLayer() in nsSliderFrame.cpp.
    1352             :    */
    1353           2 :   bool ShouldBuildScrollInfoItemsForHoisting() const
    1354           2 :   { return mSVGEffectsBuildingDepth > 0; }
    1355             : 
    1356             :   void AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem);
    1357             : 
    1358             :   /**
    1359             :    * A helper class to install/restore nsDisplayListBuilder::mPreserves3DCtx.
    1360             :    *
    1361             :    * mPreserves3DCtx is used by class AutoAccumulateTransform &
    1362             :    * AutoAccumulateRect to passing data between frames in the 3D
    1363             :    * context.  If a frame create a new 3D context, it should restore
    1364             :    * the value of mPreserves3DCtx before returning back to the parent.
    1365             :    * This class do it for the users.
    1366             :    */
    1367             :   class AutoPreserves3DContext;
    1368             :   friend class AutoPreserves3DContext;
    1369             :   class AutoPreserves3DContext {
    1370             :   public:
    1371           0 :     explicit AutoPreserves3DContext(nsDisplayListBuilder* aBuilder)
    1372           0 :       : mBuilder(aBuilder)
    1373           0 :       , mSavedCtx(aBuilder->mPreserves3DCtx) {}
    1374           0 :     ~AutoPreserves3DContext() {
    1375           0 :       mBuilder->mPreserves3DCtx = mSavedCtx;
    1376           0 :     }
    1377             : 
    1378             :   private:
    1379             :     nsDisplayListBuilder* mBuilder;
    1380             :     Preserves3DContext mSavedCtx;
    1381             :   };
    1382             : 
    1383           0 :   const nsRect GetPreserves3DDirtyRect(const nsIFrame *aFrame) const {
    1384           0 :     return mPreserves3DCtx.mDirtyRect;
    1385             :   }
    1386           0 :   void SetPreserves3DDirtyRect(const nsRect &aDirtyRect) {
    1387           0 :     mPreserves3DCtx.mDirtyRect = aDirtyRect;
    1388           0 :   }
    1389             : 
    1390        2589 :   bool IsBuildingInvisibleItems() const { return mBuildingInvisibleItems; }
    1391          85 :   void SetBuildingInvisibleItems(bool aBuildingInvisibleItems) {
    1392          85 :     mBuildingInvisibleItems = aBuildingInvisibleItems;
    1393          85 :   }
    1394             : 
    1395             :   /**
    1396             :    * This is a convenience function to ease the transition until AGRs and ASRs
    1397             :    * are unified.
    1398             :    */
    1399             :   AnimatedGeometryRoot* AnimatedGeometryRootForASR(const ActiveScrolledRoot* aASR);
    1400             : 
    1401         171 :   bool HitTestShouldStopAtFirstOpaque() const {
    1402         171 :     return mHitTestShouldStopAtFirstOpaque;
    1403             :   }
    1404           9 :   void SetHitTestShouldStopAtFirstOpaque(bool aHitTestShouldStopAtFirstOpaque) {
    1405           9 :     mHitTestShouldStopAtFirstOpaque = aHitTestShouldStopAtFirstOpaque;
    1406           9 :   }
    1407             : 
    1408             : private:
    1409             :   void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
    1410             :                                     const nsRect& aDirtyRect);
    1411             : 
    1412             :   /**
    1413             :    * Returns whether a frame acts as an animated geometry root, optionally
    1414             :    * returning the next ancestor to check.
    1415             :    */
    1416             :   AGRState IsAnimatedGeometryRoot(nsIFrame* aFrame,
    1417             :                                   nsIFrame** aParent = nullptr);
    1418             : 
    1419             :   /**
    1420             :    * Returns the nearest ancestor frame to aFrame that is considered to have
    1421             :    * (or will have) animated geometry. This can return aFrame.
    1422             :    */
    1423             :   nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame);
    1424             : 
    1425             :   friend class nsDisplayCanvasBackgroundImage;
    1426             :   friend class nsDisplayBackgroundImage;
    1427             :   friend class nsDisplayFixedPosition;
    1428             :   AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
    1429             : 
    1430             :   friend class nsDisplayItem;
    1431             :   friend class nsDisplayOwnLayer;
    1432             :   AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
    1433             : 
    1434             :   AnimatedGeometryRoot* WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
    1435             :                                         AnimatedGeometryRoot* aParent = nullptr);
    1436             : 
    1437             :   nsDataHashtable<nsPtrHashKey<nsIFrame>, AnimatedGeometryRoot*> mFrameToAnimatedGeometryRootMap;
    1438             : 
    1439             :   /**
    1440             :    * Add the current frame to the AGR budget if possible and remember
    1441             :    * the outcome. Subsequent calls will return the same value as
    1442             :    * returned here.
    1443             :    */
    1444             :   bool AddToAGRBudget(nsIFrame* aFrame);
    1445             : 
    1446         106 :   struct PresShellState {
    1447             :     nsIPresShell* mPresShell;
    1448             :     nsIFrame*     mCaretFrame;
    1449             :     nsRect        mCaretRect;
    1450             :     mozilla::Maybe<OutOfFlowDisplayData> mFixedBackgroundDisplayData;
    1451             :     uint32_t      mFirstFrameMarkedForDisplay;
    1452             :     bool          mIsBackgroundOnly;
    1453             :     // This is a per-document flag turning off event handling for all content
    1454             :     // in the document, and is set when we enter a subdocument for a pointer-
    1455             :     // events:none frame.
    1456             :     bool          mInsidePointerEventsNoneDoc;
    1457             :   };
    1458             : 
    1459       11639 :   PresShellState* CurrentPresShellState() {
    1460       11639 :     NS_ASSERTION(mPresShellStates.Length() > 0,
    1461             :                  "Someone forgot to enter a presshell");
    1462       11639 :     return &mPresShellStates[mPresShellStates.Length() - 1];
    1463             :   }
    1464             : 
    1465             :   struct DocumentWillChangeBudget {
    1466           0 :     DocumentWillChangeBudget()
    1467           0 :       : mBudget(0)
    1468           0 :     {}
    1469             : 
    1470             :     uint32_t mBudget;
    1471             :   };
    1472             : 
    1473             :   nsIFrame* const                mReferenceFrame;
    1474             :   nsIFrame*                      mIgnoreScrollFrame;
    1475             :   nsDisplayLayerEventRegions*    mLayerEventRegions;
    1476             : 
    1477             :   static const size_t kArenaAlignment =
    1478             :       mozilla::tl::Max<NS_ALIGNMENT_OF(void*), NS_ALIGNMENT_OF(double)>::value;
    1479             :   mozilla::ArenaAllocator<4096, kArenaAlignment> mPool;
    1480             : 
    1481             :   nsCOMPtr<nsISelection>         mBoundingSelection;
    1482             :   AutoTArray<PresShellState,8> mPresShellStates;
    1483             :   AutoTArray<nsIFrame*,100>    mFramesMarkedForDisplay;
    1484             :   AutoTArray<ThemeGeometry,2>  mThemeGeometries;
    1485             :   nsDisplayTableItem*            mCurrentTableItem;
    1486             :   DisplayListClipState           mClipState;
    1487             :   const ActiveScrolledRoot*      mCurrentActiveScrolledRoot;
    1488             :   const ActiveScrolledRoot*      mCurrentContainerASR;
    1489             :   // mCurrentFrame is the frame that we're currently calling (or about to call)
    1490             :   // BuildDisplayList on.
    1491             :   const nsIFrame*                mCurrentFrame;
    1492             :   // The reference frame for mCurrentFrame.
    1493             :   const nsIFrame*                mCurrentReferenceFrame;
    1494             :   // The offset from mCurrentFrame to mCurrentReferenceFrame.
    1495             :   nsPoint                        mCurrentOffsetToReferenceFrame;
    1496             : 
    1497             :   AnimatedGeometryRoot*          mCurrentAGR;
    1498             :   AnimatedGeometryRoot           mRootAGR;
    1499             : 
    1500             :   // will-change budget tracker
    1501             :   nsDataHashtable<nsPtrHashKey<nsPresContext>, DocumentWillChangeBudget>
    1502             :                                  mWillChangeBudget;
    1503             : 
    1504             :   // Any frame listed in this set is already counted in the budget
    1505             :   // and thus is in-budget.
    1506             :   nsTHashtable<nsPtrHashKey<nsIFrame> > mWillChangeBudgetSet;
    1507             : 
    1508             :   // Area of animated geometry root budget already allocated
    1509             :   uint32_t mUsedAGRBudget;
    1510             :   // Set of frames already counted in budget
    1511             :   nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet;
    1512             : 
    1513             :   // Relative to mCurrentFrame.
    1514             :   nsRect                         mDirtyRect;
    1515             :   nsRegion                       mWindowExcludeGlassRegion;
    1516             :   nsRegion                       mWindowOpaqueRegion;
    1517             :   LayoutDeviceIntRegion          mWindowDraggingRegion;
    1518             :   LayoutDeviceIntRegion          mWindowNoDraggingRegion;
    1519             :   // The display item for the Windows window glass background, if any
    1520             :   nsDisplayItem*                 mGlassDisplayItem;
    1521             :   // A temporary list that we append scroll info items to while building
    1522             :   // display items for the contents of frames with SVG effects.
    1523             :   // Only non-null when ShouldBuildScrollInfoItemsForHoisting() is true.
    1524             :   // This is a pointer and not a real nsDisplayList value because the
    1525             :   // nsDisplayList class is defined below this class, so we can't use it here.
    1526             :   nsDisplayList*                 mScrollInfoItemsForHoisting;
    1527             :   nsTArray<ActiveScrolledRoot*>  mActiveScrolledRoots;
    1528             :   nsTArray<DisplayItemClipChain*> mClipChainsToDestroy;
    1529             :   const ActiveScrolledRoot*      mActiveScrolledRootForRootScrollframe;
    1530             :   nsDisplayListBuilderMode       mMode;
    1531             :   ViewID                         mCurrentScrollParentId;
    1532             :   ViewID                         mCurrentScrollbarTarget;
    1533             :   uint32_t                       mCurrentScrollbarFlags;
    1534             :   Preserves3DContext             mPreserves3DCtx;
    1535             :   uint32_t                       mPerspectiveItemIndex;
    1536             :   int32_t                        mSVGEffectsBuildingDepth;
    1537             :   bool                           mContainsBlendMode;
    1538             :   bool                           mIsBuildingScrollbar;
    1539             :   bool                           mCurrentScrollbarWillHaveLayer;
    1540             :   bool                           mBuildCaret;
    1541             :   bool                           mIgnoreSuppression;
    1542             :   bool                           mIsAtRootOfPseudoStackingContext;
    1543             :   bool                           mIncludeAllOutOfFlows;
    1544             :   bool                           mDescendIntoSubdocuments;
    1545             :   bool                           mSelectedFramesOnly;
    1546             :   bool                           mAccurateVisibleRegions;
    1547             :   bool                           mAllowMergingAndFlattening;
    1548             :   bool                           mWillComputePluginGeometry;
    1549             :   // True when we're building a display list that's directly or indirectly
    1550             :   // under an nsDisplayTransform
    1551             :   bool                           mInTransform;
    1552             :   bool                           mIsInChromePresContext;
    1553             :   bool                           mSyncDecodeImages;
    1554             :   bool                           mIsPaintingToWindow;
    1555             :   bool                           mIsCompositingCheap;
    1556             :   bool                           mContainsPluginItem;
    1557             :   bool                           mAncestorHasApzAwareEventHandler;
    1558             :   // True when the first async-scrollable scroll frame for which we build a
    1559             :   // display list has a display port. An async-scrollable scroll frame is one
    1560             :   // which WantsAsyncScroll().
    1561             :   bool                           mHaveScrollableDisplayPort;
    1562             :   bool                           mWindowDraggingAllowed;
    1563             :   bool                           mIsBuildingForPopup;
    1564             :   bool                           mForceLayerForScrollParent;
    1565             :   bool                           mAsyncPanZoomEnabled;
    1566             :   bool                           mBuildingInvisibleItems;
    1567             :   bool                           mHitTestShouldStopAtFirstOpaque;
    1568             : };
    1569             : 
    1570             : class nsDisplayItem;
    1571             : class nsDisplayList;
    1572             : /**
    1573             :  * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
    1574             :  * nsDisplayItemLink holds the link. The lists are linked from lowest to
    1575             :  * highest in z-order.
    1576             :  */
    1577             : class nsDisplayItemLink {
    1578             :   // This is never instantiated directly, so no need to count constructors and
    1579             :   // destructors.
    1580             : protected:
    1581       27915 :   nsDisplayItemLink() : mAbove(nullptr) {}
    1582             :   nsDisplayItem* mAbove;
    1583             : 
    1584             :   friend class nsDisplayList;
    1585             : };
    1586             : 
    1587             : /**
    1588             :  * This is the unit of rendering and event testing. Each instance of this
    1589             :  * class represents an entity that can be drawn on the screen, e.g., a
    1590             :  * frame's CSS background, or a frame's text string.
    1591             :  *
    1592             :  * nsDisplayItems can be containers --- i.e., they can perform hit testing
    1593             :  * and painting by recursively traversing a list of child items.
    1594             :  *
    1595             :  * These are arena-allocated during display list construction. A typical
    1596             :  * subclass would just have a frame pointer, so its object would be just three
    1597             :  * pointers (vtable, next-item, frame).
    1598             :  *
    1599             :  * Display items belong to a list at all times (except temporarily as they
    1600             :  * move from one list to another).
    1601             :  */
    1602             : class nsDisplayItem : public nsDisplayItemLink {
    1603             : public:
    1604             :   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
    1605             :   typedef mozilla::DisplayItemClip DisplayItemClip;
    1606             :   typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
    1607             :   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
    1608             :   typedef mozilla::layers::FrameMetrics FrameMetrics;
    1609             :   typedef mozilla::layers::ScrollMetadata ScrollMetadata;
    1610             :   typedef mozilla::layers::FrameMetrics::ViewID ViewID;
    1611             :   typedef mozilla::layers::Layer Layer;
    1612             :   typedef mozilla::layers::LayerManager LayerManager;
    1613             :   typedef mozilla::layers::StackingContextHelper StackingContextHelper;
    1614             :   typedef mozilla::layers::WebRenderCommand WebRenderCommand;
    1615             :   typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
    1616             :   typedef mozilla::layers::WebRenderDisplayItemLayer WebRenderDisplayItemLayer;
    1617             :   typedef mozilla::LayerState LayerState;
    1618             :   typedef mozilla::image::imgDrawingParams imgDrawingParams;
    1619             :   typedef mozilla::image::DrawResult DrawResult;
    1620             :   typedef class mozilla::gfx::DrawTarget DrawTarget;
    1621             : 
    1622             :   // This is never instantiated directly (it has pure virtual methods), so no
    1623             :   // need to count constructors and destructors.
    1624             :   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    1625             :   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1626             :                 const ActiveScrolledRoot* aActiveScrolledRoot);
    1627             :   /**
    1628             :    * This constructor is only used in rare cases when we need to construct
    1629             :    * temporary items.
    1630             :    */
    1631           0 :   explicit nsDisplayItem(nsIFrame* aFrame)
    1632           0 :     : mFrame(aFrame)
    1633             :     , mClipChain(nullptr)
    1634             :     , mClip(nullptr)
    1635             :     , mActiveScrolledRoot(nullptr)
    1636             :     , mReferenceFrame(nullptr)
    1637             :     , mAnimatedGeometryRoot(nullptr)
    1638             :     , mForceNotVisible(false)
    1639             : #ifdef MOZ_DUMP_PAINTING
    1640           0 :     , mPainted(false)
    1641             : #endif
    1642             :   {
    1643           0 :   }
    1644        2589 :   virtual ~nsDisplayItem() {}
    1645             : 
    1646        2565 :   void* operator new(size_t aSize,
    1647             :                      nsDisplayListBuilder* aBuilder) {
    1648        2565 :     return aBuilder->Allocate(aSize);
    1649             :   }
    1650             : 
    1651             : // Contains all the type integers for each display list item type
    1652             : #include "nsDisplayItemTypes.h"
    1653             : 
    1654             :   struct HitTestState {
    1655           9 :     explicit HitTestState() : mInPreserves3D(false) {}
    1656             : 
    1657          18 :     ~HitTestState() {
    1658           9 :       NS_ASSERTION(mItemBuffer.Length() == 0,
    1659             :                    "mItemBuffer should have been cleared");
    1660           9 :     }
    1661             : 
    1662             :     // Handling transform items for preserve 3D frames.
    1663             :     bool mInPreserves3D;
    1664             :     AutoTArray<nsDisplayItem*, 100> mItemBuffer;
    1665             :   };
    1666             : 
    1667             :   /**
    1668             :    * Some consecutive items should be rendered together as a unit, e.g.,
    1669             :    * outlines for the same element. For this, we need a way for items to
    1670             :    * identify their type. We use the type for other purposes too.
    1671             :    */
    1672             :   virtual Type GetType() = 0;
    1673             :   /**
    1674             :    * Pairing this with the GetUnderlyingFrame() pointer gives a key that
    1675             :    * uniquely identifies this display item in the display item tree.
    1676             :    * XXX check nsOptionEventGrabberWrapper/nsXULEventRedirectorWrapper
    1677             :    */
    1678        6715 :   virtual uint32_t GetPerFrameKey() { return uint32_t(GetType()); }
    1679             :   /**
    1680             :    * This is called after we've constructed a display list for event handling.
    1681             :    * When this is called, we've already ensured that aRect intersects the
    1682             :    * item's bounds and that clipping has been taking into account.
    1683             :    *
    1684             :    * @param aRect the point or rect being tested, relative to the reference
    1685             :    * frame. If the width and height are both 1 app unit, it indicates we're
    1686             :    * hit testing a point, not a rect.
    1687             :    * @param aState must point to a HitTestState. If you don't have one,
    1688             :    * just create one with the default constructor and pass it in.
    1689             :    * @param aOutFrames each item appends the frame(s) in this display item that
    1690             :    * the rect is considered over (if any) to aOutFrames.
    1691             :    */
    1692           9 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    1693           9 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {}
    1694             :   /**
    1695             :    * @return the frame that this display item is based on. This is used to sort
    1696             :    * items by z-index and content order and for some other uses. Never
    1697             :    * returns null.
    1698             :    */
    1699       14779 :   inline nsIFrame* Frame() const { return mFrame; }
    1700             :   /**
    1701             :    * Compute the used z-index of our frame; returns zero for elements to which
    1702             :    * z-index does not apply, and for z-index:auto.
    1703             :    * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex.
    1704             :    */
    1705             :   virtual int32_t ZIndex() const;
    1706             :   /**
    1707             :    * The default bounds is the frame border rect.
    1708             :    * @param aSnap *aSnap is set to true if the returned rect will be
    1709             :    * snapped to nearest device pixel edges during actual drawing.
    1710             :    * It might be set to false and snap anyway, so code computing the set of
    1711             :    * pixels affected by this display item needs to round outwards to pixel
    1712             :    * boundaries when *aSnap is set to false.
    1713             :    * This does not take the item's clipping into account.
    1714             :    * @return a rectangle relative to aBuilder->ReferenceFrame() that
    1715             :    * contains the area drawn by this display item
    1716             :    */
    1717         269 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
    1718             :   {
    1719         269 :     *aSnap = false;
    1720         269 :     return nsRect(ToReferenceFrame(), Frame()->GetSize());
    1721             :   }
    1722             : 
    1723         219 :   virtual nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
    1724             :   {
    1725         219 :     *aSnap = false;
    1726         219 :     return nsRegion();
    1727             :   }
    1728             : 
    1729             :   /**
    1730             :    * Returns true if nothing will be rendered inside aRect, false if uncertain.
    1731             :    * aRect is assumed to be contained in this item's bounds.
    1732             :    */
    1733         294 :   virtual bool IsInvisibleInRect(const nsRect& aRect)
    1734             :   {
    1735         294 :     return false;
    1736             :   }
    1737             :   /**
    1738             :    * Returns the result of GetBounds intersected with the item's clip.
    1739             :    * The intersection is approximate since rounded corners are not taking into
    1740             :    * account.
    1741             :    */
    1742             :   nsRect GetClippedBounds(nsDisplayListBuilder* aBuilder);
    1743         609 :   nsRect GetBorderRect() {
    1744         609 :     return nsRect(ToReferenceFrame(), Frame()->GetSize());
    1745             :   }
    1746          25 :   nsRect GetPaddingRect() {
    1747          25 :     return Frame()->GetPaddingRectRelativeToSelf() + ToReferenceFrame();
    1748             :   }
    1749         179 :   nsRect GetContentRect() {
    1750         179 :     return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
    1751             :   }
    1752             : 
    1753             :   /**
    1754             :    * Checks if the frame(s) owning this display item have been marked as invalid,
    1755             :    * and needing repainting.
    1756             :    */
    1757        1075 :   virtual bool IsInvalid(nsRect& aRect) {
    1758        1075 :     bool result = mFrame ? mFrame->IsInvalid(aRect) : false;
    1759        1075 :     aRect += ToReferenceFrame();
    1760        1075 :     return result;
    1761             :   }
    1762             : 
    1763             :   /**
    1764             :    * Creates and initializes an nsDisplayItemGeometry object that retains the current
    1765             :    * areas covered by this display item. These need to retain enough information
    1766             :    * such that they can be compared against a future nsDisplayItem of the same type,
    1767             :    * and determine if repainting needs to happen.
    1768             :    *
    1769             :    * Subclasses wishing to store more information need to override both this
    1770             :    * and ComputeInvalidationRegion, as well as implementing an nsDisplayItemGeometry
    1771             :    * subclass.
    1772             :    *
    1773             :    * The default implementation tracks both the display item bounds, and the frame's
    1774             :    * border rect.
    1775             :    */
    1776         139 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
    1777             :   {
    1778         139 :     return new nsDisplayItemGenericGeometry(this, aBuilder);
    1779             :   }
    1780             : 
    1781             :   /**
    1782             :    * Compares an nsDisplayItemGeometry object from a previous paint against the
    1783             :    * current item. Computes if the geometry of the item has changed, and the
    1784             :    * invalidation area required for correct repainting.
    1785             :    *
    1786             :    * The existing geometry will have been created from a display item with a
    1787             :    * matching GetPerFrameKey()/mFrame pair to the current item.
    1788             :    *
    1789             :    * The default implementation compares the display item bounds, and the frame's
    1790             :    * border rect, and invalidates the entire bounds if either rect changes.
    1791             :    *
    1792             :    * @param aGeometry The geometry of the matching display item from the
    1793             :    * previous paint.
    1794             :    * @param aInvalidRegion Output param, the region to invalidate, or
    1795             :    * unchanged if none.
    1796             :    */
    1797         296 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    1798             :                                          const nsDisplayItemGeometry* aGeometry,
    1799             :                                          nsRegion* aInvalidRegion)
    1800             :   {
    1801         296 :     const nsDisplayItemGenericGeometry* geometry = static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
    1802             :     bool snap;
    1803        1148 :     if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
    1804         852 :         !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
    1805          18 :       aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
    1806             :     }
    1807         296 :   }
    1808             : 
    1809             :   /**
    1810             :    * An alternative default implementation of ComputeInvalidationRegion,
    1811             :    * that instead invalidates only the changed area between the two items.
    1812             :    */
    1813         167 :   void ComputeInvalidationRegionDifference(nsDisplayListBuilder* aBuilder,
    1814             :                                            const nsDisplayItemBoundsGeometry* aGeometry,
    1815             :                                            nsRegion* aInvalidRegion)
    1816             :   {
    1817             :     bool snap;
    1818         334 :     nsRect bounds = GetBounds(aBuilder, &snap);
    1819             : 
    1820         167 :     if (!aGeometry->mBounds.IsEqualInterior(bounds)) {
    1821             :       nscoord radii[8];
    1822          12 :       if (aGeometry->mHasRoundedCorners ||
    1823           3 :           Frame()->GetBorderRadii(radii)) {
    1824           6 :         aInvalidRegion->Or(aGeometry->mBounds, bounds);
    1825             :       } else {
    1826           3 :         aInvalidRegion->Xor(aGeometry->mBounds, bounds);
    1827             :       }
    1828             :     }
    1829         167 :   }
    1830             : 
    1831             :   /**
    1832             :    * Called when the area rendered by this display item has changed (been
    1833             :    * invalidated or changed geometry) since the last paint. This includes
    1834             :    * when the display item was not rendered at all in the last paint.
    1835             :    * It does NOT get called when a display item was being rendered and no
    1836             :    * longer is, because generally that means there is no display item to
    1837             :    * call this method on.
    1838             :    */
    1839         225 :   virtual void NotifyRenderingChanged() {}
    1840             : 
    1841             :   /**
    1842             :    * @param aSnap set to true if the edges of the rectangles of the opaque
    1843             :    * region would be snapped to device pixels when drawing
    1844             :    * @return a region of the item that is opaque --- that is, every pixel
    1845             :    * that is visible is painted with an opaque
    1846             :    * color. This is useful for determining when one piece
    1847             :    * of content completely obscures another so that we can do occlusion
    1848             :    * culling.
    1849             :    * This does not take clipping into account.
    1850             :    */
    1851         926 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    1852             :                                    bool* aSnap)
    1853             :   {
    1854         926 :     *aSnap = false;
    1855         926 :     return nsRegion();
    1856             :   }
    1857             :   /**
    1858             :    * @return Some(nscolor) if the item is guaranteed to paint every pixel in its
    1859             :    * bounds with the same (possibly translucent) color
    1860             :    */
    1861         169 :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder)
    1862         169 :   { return mozilla::Nothing(); }
    1863             :   /**
    1864             :    * @return true if the contents of this item are rendered fixed relative
    1865             :    * to the nearest viewport.
    1866             :    */
    1867          76 :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
    1868          76 :   { return false; }
    1869             : 
    1870        3157 :   virtual bool ClearsBackground()
    1871        3157 :   { return false; }
    1872             : 
    1873         172 :   virtual bool ProvidesFontSmoothingBackgroundColor(nscolor* aColor)
    1874         172 :   { return false; }
    1875             : 
    1876             :   /**
    1877             :    * Returns true if all layers that can be active should be forced to be
    1878             :    * active. Requires setting the pref layers.force-active=true.
    1879             :    */
    1880             :   static bool ForceActiveLayers();
    1881             : 
    1882             :   /**
    1883             :    * @return LAYER_NONE if BuildLayer will return null. In this case
    1884             :    * there is no layer for the item, and Paint should be called instead
    1885             :    * to paint the content using Thebes.
    1886             :    * Return LAYER_INACTIVE if there is a layer --- BuildLayer will
    1887             :    * not return null (unless there's an error) --- but the layer contents
    1888             :    * are not changing frequently. In this case it makes sense to composite
    1889             :    * the layer into a PaintedLayer with other content, so we don't have to
    1890             :    * recomposite it every time we paint.
    1891             :    * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all
    1892             :    * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also,
    1893             :    * all descendant display item frames must have an active scrolled root
    1894             :    * that's either the same as this item's frame's active scrolled root, or
    1895             :    * a descendant of this item's frame. This ensures that the entire
    1896             :    * set of display items can be collapsed onto a single PaintedLayer.
    1897             :    * Return LAYER_ACTIVE if the layer is active, that is, its contents are
    1898             :    * changing frequently. In this case it makes sense to keep the layer
    1899             :    * as a separate buffer in VRAM and composite it into the destination
    1900             :    * every time we paint.
    1901             :    *
    1902             :    * Users of GetLayerState should check ForceActiveLayers() and if it returns
    1903             :    * true, change a returned value of LAYER_INACTIVE to LAYER_ACTIVE.
    1904             :    */
    1905        1193 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    1906             :                                    LayerManager* aManager,
    1907             :                                    const ContainerLayerParameters& aParameters)
    1908        1193 :   { return mozilla::LAYER_NONE; }
    1909             :   /**
    1910             :    * Return true to indicate the layer should be constructed even if it's
    1911             :    * completely invisible.
    1912             :    */
    1913           0 :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder)
    1914           0 :   { return false; }
    1915             :   /**
    1916             :    * Actually paint this item to some rendering context.
    1917             :    * Content outside mVisibleRect need not be painted.
    1918             :    * aCtx must be set up as for nsDisplayList::Paint.
    1919             :    */
    1920           0 :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {}
    1921             : 
    1922             : #ifdef MOZ_DUMP_PAINTING
    1923             :   /**
    1924             :    * Mark this display item as being painted via FrameLayerBuilder::DrawPaintedLayer.
    1925             :    */
    1926           0 :   bool Painted() { return mPainted; }
    1927             : 
    1928             :   /**
    1929             :    * Check if this display item has been painted.
    1930             :    */
    1931           0 :   void SetPainted() { mPainted = true; }
    1932             : #endif
    1933             : 
    1934             :   /**
    1935             :    * Get the layer drawn by this display item. Call this only if
    1936             :    * GetLayerState() returns something other than LAYER_NONE.
    1937             :    * If GetLayerState returned LAYER_NONE then Paint will be called
    1938             :    * instead.
    1939             :    * This is called while aManager is in the construction phase.
    1940             :    *
    1941             :    * The caller (nsDisplayList) is responsible for setting the visible
    1942             :    * region of the layer.
    1943             :    *
    1944             :    * @param aContainerParameters should be passed to
    1945             :    * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is
    1946             :    * constructed.
    1947             :    */
    1948           0 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    1949             :                                              LayerManager* aManager,
    1950             :                                              const ContainerLayerParameters& aContainerParameters)
    1951           0 :   { return nullptr; }
    1952             : 
    1953             :   /**
    1954             :     * Function to create the WebRenderCommands without
    1955             :     * Layer. For layers mode, aManager->IsLayersFreeTransaction()
    1956             :     * should be false to prevent doing GetLayerState again. For
    1957             :     * layers-free mode, we should check if the layer state is
    1958             :     * active first and have an early return if the layer state is
    1959             :     * not active.
    1960             :     *
    1961             :     * @return true if successfully creating webrender commands.
    1962             :     */
    1963           0 :    virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    1964             :                                         const StackingContextHelper& aSc,
    1965             :                                         nsTArray<WebRenderParentCommand>& aParentCommands,
    1966             :                                         mozilla::layers::WebRenderLayerManager* aManager,
    1967           0 :                                         nsDisplayListBuilder* aDisplayListBuilder) { return false; }
    1968             : 
    1969             :   /**
    1970             :    * Builds a DisplayItemLayer and sets the display item to this.
    1971             :    */
    1972             :    already_AddRefed<Layer>
    1973             :    BuildDisplayItemLayer(nsDisplayListBuilder* aBuilder,
    1974             :                          LayerManager* aManager,
    1975             :                          const ContainerLayerParameters& aContainerParameters);
    1976             : 
    1977             :   /**
    1978             :    * On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
    1979             :    * which may be visible. If the display item opaquely covers an area, it
    1980             :    * can remove that area from aVisibleRegion before returning.
    1981             :    * nsDisplayList::ComputeVisibility automatically subtracts the region
    1982             :    * returned by GetOpaqueRegion, and automatically removes items whose bounds
    1983             :    * do not intersect the visible area, so implementations of
    1984             :    * nsDisplayItem::ComputeVisibility do not need to do these things.
    1985             :    * nsDisplayList::ComputeVisibility will already have set mVisibleRect on
    1986             :    * this item to the intersection of *aVisibleRegion and this item's bounds.
    1987             :    * We rely on that, so this should only be called by
    1988             :    * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
    1989             :    * aAllowVisibleRegionExpansion is a rect where we are allowed to
    1990             :    * expand the visible region and is only used for making sure the
    1991             :    * background behind a plugin is visible.
    1992             :    * This method needs to be idempotent.
    1993             :    *
    1994             :    * @return true if the item is visible, false if no part of the item
    1995             :    * is visible.
    1996             :    */
    1997             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1998             :                                  nsRegion* aVisibleRegion);
    1999             : 
    2000             :   /**
    2001             :    * Try to merge with the other item (which is below us in the display
    2002             :    * list). This gets used by nsDisplayClip to coalesce clipping operations
    2003             :    * (optimization), by nsDisplayOpacity to merge rendering for the same
    2004             :    * content element into a single opacity group (correctness), and will be
    2005             :    * used by nsDisplayOutline to merge multiple outlines for the same element
    2006             :    * (also for correctness).
    2007             :    * @return true if the merge was successful and the other item should be deleted
    2008             :    */
    2009        1132 :   virtual bool TryMerge(nsDisplayItem* aItem) {
    2010        1132 :     return false;
    2011             :   }
    2012             : 
    2013             :   /**
    2014             :    * Appends the underlying frames of all display items that have been
    2015             :    * merged into this one (excluding  this item's own underlying frame)
    2016             :    * to aFrames.
    2017             :    */
    2018        1050 :   virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) {}
    2019             : 
    2020             :   /**
    2021             :    * During the visibility computation and after TryMerge, display lists may
    2022             :    * return true here to flatten themselves away, removing them. This
    2023             :    * flattening is distinctly different from FlattenTo, which occurs before
    2024             :    * items are merged together.
    2025             :    */
    2026        1688 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
    2027        1688 :     return false;
    2028             :   }
    2029             : 
    2030             :   /**
    2031             :    * If this has a child list where the children are in the same coordinate
    2032             :    * system as this item (i.e., they have the same reference frame),
    2033             :    * return the list.
    2034             :    */
    2035        2094 :   virtual nsDisplayList* GetSameCoordinateSystemChildren() { return nullptr; }
    2036           0 :   virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) {}
    2037             :   /**
    2038             :    * Do UpdateBounds() for items with frames establishing or extending
    2039             :    * 3D rendering context.
    2040             :    *
    2041             :    * This function is called by UpdateBoundsFor3D() of
    2042             :    * nsDisplayTransform(), and it is called by
    2043             :    * BuildDisplayListForStackingContext() on transform items
    2044             :    * establishing 3D rendering context.
    2045             :    *
    2046             :    * The bounds of a transform item with the frame establishing 3D
    2047             :    * rendering context should be computed by calling
    2048             :    * DoUpdateBoundsPreserves3D() on all descendants that participate
    2049             :    * the same 3d rendering context.
    2050             :    */
    2051           0 :   virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) {}
    2052             : 
    2053             :   /**
    2054             :    * If this has a child list, return it, even if the children are in
    2055             :    * a different coordinate system to this item.
    2056             :    */
    2057          96 :   virtual nsDisplayList* GetChildren() { return nullptr; }
    2058             : 
    2059             :   /**
    2060             :    * Returns the visible rect.
    2061             :    */
    2062        4810 :   const nsRect& GetVisibleRect() const { return mVisibleRect; }
    2063             : 
    2064             :   /**
    2065             :    * Returns the visible rect for the children, relative to their
    2066             :    * reference frame. Can be different from mVisibleRect for nsDisplayTransform,
    2067             :    * since the reference frame for the children is different from the reference
    2068             :    * frame for the item itself.
    2069             :    */
    2070         171 :   virtual const nsRect& GetVisibleRectForChildren() const { return mVisibleRect; }
    2071             : 
    2072             :   /**
    2073             :    * Stores the given opacity value to be applied when drawing. It is an error to
    2074             :    * call this if CanApplyOpacity returned false.
    2075             :    */
    2076           0 :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    2077             :                             float aOpacity,
    2078             :                             const DisplayItemClipChain* aClip) {
    2079           0 :     NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity not supported on this type");
    2080           0 :   }
    2081             :   /**
    2082             :    * Returns true if this display item would return true from ApplyOpacity without
    2083             :    * actually applying the opacity. Otherwise returns false.
    2084             :    */
    2085          64 :   virtual bool CanApplyOpacity() const {
    2086          64 :     return false;
    2087             :   }
    2088             : 
    2089             :   /**
    2090             :    * For debugging and stuff
    2091             :    */
    2092             :   virtual const char* Name() = 0;
    2093             : 
    2094           0 :   virtual void WriteDebugInfo(std::stringstream& aStream) {}
    2095             : 
    2096        6336 :   nsDisplayItem* GetAbove() { return mAbove; }
    2097             : 
    2098             :   /**
    2099             :    * Like ComputeVisibility, but does the work that nsDisplayList
    2100             :    * does per-item:
    2101             :    * -- Intersects GetBounds with aVisibleRegion and puts the result
    2102             :    * in mVisibleRect
    2103             :    * -- Subtracts bounds from aVisibleRegion if the item is opaque
    2104             :    */
    2105             :   bool RecomputeVisibility(nsDisplayListBuilder* aBuilder,
    2106             :                            nsRegion* aVisibleRegion);
    2107             : 
    2108             :   /**
    2109             :    * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())
    2110             :    */
    2111        4866 :   const nsPoint& ToReferenceFrame() const {
    2112        4866 :     NS_ASSERTION(mFrame, "No frame?");
    2113        4866 :     return mToReferenceFrame;
    2114             :   }
    2115             :   /**
    2116             :    * @return the root of the display list's frame (sub)tree, whose origin
    2117             :    * establishes the coordinate system for the display list
    2118             :    */
    2119        2456 :   const nsIFrame* ReferenceFrame() const { return mReferenceFrame; }
    2120             : 
    2121             :   /**
    2122             :    * Returns the reference frame for display item children of this item.
    2123             :    */
    2124         171 :   virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
    2125             : 
    2126        2242 :   AnimatedGeometryRoot* GetAnimatedGeometryRoot() const {
    2127        2242 :     MOZ_ASSERT(mAnimatedGeometryRoot, "Must have cached AGR before accessing it!");
    2128        2242 :     return mAnimatedGeometryRoot;
    2129             :   }
    2130             : 
    2131           0 :   virtual struct AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const {
    2132           0 :     return GetAnimatedGeometryRoot();
    2133             :   }
    2134             : 
    2135             :   /**
    2136             :    * Checks if this display item (or any children) contains content that might
    2137             :    * be rendered with component alpha (e.g. subpixel antialiasing). Returns the
    2138             :    * bounds of the area that needs component alpha, or an empty rect if nothing
    2139             :    * in the item does.
    2140             :    */
    2141         311 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { return nsRect(); }
    2142             : 
    2143             :   /**
    2144             :    * Disable usage of component alpha. Currently only relevant for items that have text.
    2145             :    */
    2146           0 :   virtual void DisableComponentAlpha() {}
    2147             : 
    2148             :   /**
    2149             :    * Check if we can add async animations to the layer for this display item.
    2150             :    */
    2151           0 :   virtual bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
    2152           0 :     return false;
    2153             :   }
    2154             : 
    2155         139 :   virtual bool SupportsOptimizingToImage() { return false; }
    2156             : 
    2157        9562 :   const DisplayItemClip& GetClip()
    2158             :   {
    2159        9562 :     return mClip ? *mClip : DisplayItemClip::NoClip();
    2160             :   }
    2161             :   void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClipChain* aOther);
    2162             : 
    2163             :   void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) { mActiveScrolledRoot = aActiveScrolledRoot; }
    2164        4350 :   const ActiveScrolledRoot* GetActiveScrolledRoot() const { return mActiveScrolledRoot; }
    2165             : 
    2166             :   virtual void SetClipChain(const DisplayItemClipChain* aClipChain);
    2167        1519 :   const DisplayItemClipChain* GetClipChain() const { return mClipChain; }
    2168             : 
    2169             :   /**
    2170             :    * Intersect all clips in our clip chain up to (and including) aASR and set
    2171             :    * set the intersection as this item's clip.
    2172             :    */
    2173             :   void FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
    2174             :                          const ActiveScrolledRoot* aASR);
    2175             : 
    2176          76 :   bool BackfaceIsHidden() {
    2177          76 :     return mFrame->BackfaceIsHidden();
    2178             :   }
    2179             : 
    2180             : protected:
    2181             :   friend class nsDisplayList;
    2182             : 
    2183             :   nsDisplayItem() { mAbove = nullptr; }
    2184             : 
    2185             :   typedef bool (*PrefFunc)(void);
    2186             :   bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc);
    2187             : 
    2188             :   nsIFrame* mFrame;
    2189             :   const DisplayItemClipChain* mClipChain;
    2190             :   const DisplayItemClip* mClip;
    2191             :   const ActiveScrolledRoot* mActiveScrolledRoot;
    2192             :   // Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
    2193             :   const nsIFrame* mReferenceFrame;
    2194             :   struct AnimatedGeometryRoot* mAnimatedGeometryRoot;
    2195             :   // Result of ToReferenceFrame(mFrame), if mFrame is non-null
    2196             :   nsPoint   mToReferenceFrame;
    2197             :   // This is the rectangle that needs to be painted.
    2198             :   // Display item construction sets this to the dirty rect.
    2199             :   // nsDisplayList::ComputeVisibility sets this to the visible region
    2200             :   // of the item by intersecting the current visible region with the bounds
    2201             :   // of the item. Paint implementations can use this to limit their drawing.
    2202             :   // Guaranteed to be contained in GetBounds().
    2203             :   nsRect    mVisibleRect;
    2204             :   bool      mForceNotVisible;
    2205             : #ifdef MOZ_DUMP_PAINTING
    2206             :   // True if this frame has been painted.
    2207             :   bool      mPainted;
    2208             : #endif
    2209             : };
    2210             : 
    2211             : /**
    2212             :  * Manages a singly-linked list of display list items.
    2213             :  *
    2214             :  * mSentinel is the sentinel list value, the first value in the null-terminated
    2215             :  * linked list of items. mTop is the last item in the list (whose 'above'
    2216             :  * pointer is null). This class has no virtual methods. So list objects are just
    2217             :  * two pointers.
    2218             :  *
    2219             :  * Stepping upward through this list is very fast. Stepping downward is very
    2220             :  * slow so we don't support it. The methods that need to step downward
    2221             :  * (HitTest(), ComputeVisibility()) internally build a temporary array of all
    2222             :  * the items while they do the downward traversal, so overall they're still
    2223             :  * linear time. We have optimized for efficient AppendToTop() of both
    2224             :  * items and lists, with minimal codesize. AppendToBottom() is efficient too.
    2225             :  */
    2226             : class nsDisplayList {
    2227             : public:
    2228             :   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
    2229             :   typedef mozilla::layers::Layer Layer;
    2230             :   typedef mozilla::layers::LayerManager LayerManager;
    2231             :   typedef mozilla::layers::PaintedLayer PaintedLayer;
    2232             : 
    2233             :   /**
    2234             :    * Create an empty list.
    2235             :    */
    2236       25326 :   nsDisplayList()
    2237       25326 :     : mIsOpaque(false)
    2238       25326 :     , mForceTransparentSurface(false)
    2239             :   {
    2240       25326 :     mTop = &mSentinel;
    2241       25326 :     mSentinel.mAbove = nullptr;
    2242       25326 :   }
    2243       50652 :   ~nsDisplayList() {
    2244       25326 :     if (mSentinel.mAbove) {
    2245           0 :       NS_WARNING("Nonempty list left over?");
    2246             :     }
    2247       25326 :     DeleteAll();
    2248       25326 :   }
    2249             : 
    2250             :   /**
    2251             :    * Append an item to the top of the list. The item must not currently
    2252             :    * be in a list and cannot be null.
    2253             :    */
    2254        4581 :   void AppendToTop(nsDisplayItem* aItem) {
    2255        4581 :     NS_ASSERTION(aItem, "No item to append!");
    2256        4581 :     NS_ASSERTION(!aItem->mAbove, "Already in a list!");
    2257        4581 :     mTop->mAbove = aItem;
    2258        4581 :     mTop = aItem;
    2259        4581 :   }
    2260             : 
    2261             :   /**
    2262             :    * Append a new item to the top of the list. The intended usage is
    2263             :    * AppendNewToTop(new ...);
    2264             :    */
    2265        2231 :   void AppendNewToTop(nsDisplayItem* aItem) {
    2266        2231 :     if (aItem) {
    2267        2231 :       AppendToTop(aItem);
    2268             :     }
    2269        2231 :   }
    2270             : 
    2271             :   /**
    2272             :    * Append a new item to the bottom of the list. The intended usage is
    2273             :    * AppendNewToBottom(new ...);
    2274             :    */
    2275          26 :   void AppendNewToBottom(nsDisplayItem* aItem) {
    2276          26 :     if (aItem) {
    2277          26 :       AppendToBottom(aItem);
    2278             :     }
    2279          26 :   }
    2280             : 
    2281             :   /**
    2282             :    * Append a new item to the bottom of the list. The item must be non-null
    2283             :    * and not already in a list.
    2284             :    */
    2285         625 :   void AppendToBottom(nsDisplayItem* aItem) {
    2286         625 :     NS_ASSERTION(aItem, "No item to append!");
    2287         625 :     NS_ASSERTION(!aItem->mAbove, "Already in a list!");
    2288         625 :     aItem->mAbove = mSentinel.mAbove;
    2289         625 :     mSentinel.mAbove = aItem;
    2290         625 :     if (mTop == &mSentinel) {
    2291         440 :       mTop = aItem;
    2292             :     }
    2293         625 :   }
    2294             : 
    2295             :   /**
    2296             :    * Removes all items from aList and appends them to the top of this list
    2297             :    */
    2298       11050 :   void AppendToTop(nsDisplayList* aList) {
    2299       11050 :     if (aList->mSentinel.mAbove) {
    2300        3999 :       mTop->mAbove = aList->mSentinel.mAbove;
    2301        3999 :       mTop = aList->mTop;
    2302        3999 :       aList->mTop = &aList->mSentinel;
    2303        3999 :       aList->mSentinel.mAbove = nullptr;
    2304             :     }
    2305       11050 :   }
    2306             : 
    2307             :   /**
    2308             :    * Removes all items from aList and prepends them to the bottom of this list
    2309             :    */
    2310         349 :   void AppendToBottom(nsDisplayList* aList) {
    2311         349 :     if (aList->mSentinel.mAbove) {
    2312         349 :       aList->mTop->mAbove = mSentinel.mAbove;
    2313         349 :       mSentinel.mAbove = aList->mSentinel.mAbove;
    2314         349 :       if (mTop == &mSentinel) {
    2315          24 :         mTop = aList->mTop;
    2316             :       }
    2317             : 
    2318         349 :       aList->mTop = &aList->mSentinel;
    2319         349 :       aList->mSentinel.mAbove = nullptr;
    2320             :     }
    2321         349 :   }
    2322             : 
    2323             :   /**
    2324             :    * Remove an item from the bottom of the list and return it.
    2325             :    */
    2326             :   nsDisplayItem* RemoveBottom();
    2327             : 
    2328             :   /**
    2329             :    * Remove all items from the list and call their destructors.
    2330             :    */
    2331             :   void DeleteAll();
    2332             : 
    2333             :   /**
    2334             :    * @return the item at the top of the list, or null if the list is empty
    2335             :    */
    2336           0 :   nsDisplayItem* GetTop() const {
    2337           0 :     return mTop != &mSentinel ? static_cast<nsDisplayItem*>(mTop) : nullptr;
    2338             :   }
    2339             :   /**
    2340             :    * @return the item at the bottom of the list, or null if the list is empty
    2341             :    */
    2342        6348 :   nsDisplayItem* GetBottom() const { return mSentinel.mAbove; }
    2343        1477 :   bool IsEmpty() const { return mTop == &mSentinel; }
    2344             : 
    2345             :   /**
    2346             :    * This is *linear time*!
    2347             :    * @return the number of items in the list
    2348             :    */
    2349             :   uint32_t Count() const;
    2350             :   /**
    2351             :    * Stable sort the list by the z-order of GetUnderlyingFrame() on
    2352             :    * each item. 'auto' is counted as zero.
    2353             :    * It is assumed that the list is already in content document order.
    2354             :    */
    2355             :   void SortByZOrder();
    2356             :   /**
    2357             :    * Stable sort the list by the tree order of the content of
    2358             :    * GetUnderlyingFrame() on each item. z-index is ignored.
    2359             :    * @param aCommonAncestor a common ancestor of all the content elements
    2360             :    * associated with the display items, for speeding up tree order
    2361             :    * checks, or nullptr if not known; it's only a hint, if it is not an
    2362             :    * ancestor of some elements, then we lose performance but not correctness
    2363             :    */
    2364             :   void SortByContentOrder(nsIContent* aCommonAncestor);
    2365             : 
    2366             :   /**
    2367             :    * Sort the display list using a stable sort. Take care, because some of the
    2368             :    * items might be nsDisplayLists themselves.
    2369             :    * aComparator(Item item1, Item item2) should return true if item1 should go
    2370             :    * before item2.
    2371             :    * We sort the items into increasing order.
    2372             :    */
    2373             :   template<typename Item, typename Comparator>
    2374        1226 :   void Sort(const Comparator& aComparator) {
    2375        2452 :     nsTArray<Item> items;
    2376             : 
    2377        2058 :     while (nsDisplayItem* item = RemoveBottom()) {
    2378         416 :       items.AppendElement(Item(item));
    2379             :     }
    2380             : 
    2381        1226 :     std::stable_sort(items.begin(), items.end(), aComparator);
    2382             : 
    2383        1642 :     for (Item& item : items) {
    2384         416 :       AppendToTop(item);
    2385             :     }
    2386        1226 :   }
    2387             : 
    2388             :   /**
    2389             :    * Compute visiblity for the items in the list.
    2390             :    * We put this logic here so it can be shared by top-level
    2391             :    * painting and also display items that maintain child lists.
    2392             :    * This is also a good place to put ComputeVisibility-related logic
    2393             :    * that must be applied to every display item. In particular, this
    2394             :    * sets mVisibleRect on each display item.
    2395             :    * This sets mIsOpaque if the entire visible area of this list has
    2396             :    * been removed from aVisibleRegion when we return.
    2397             :    * This does not remove any items from the list, so we can recompute
    2398             :    * visiblity with different regions later (see
    2399             :    * FrameLayerBuilder::DrawPaintedLayer).
    2400             :    * This method needs to be idempotent.
    2401             :    *
    2402             :    * @param aVisibleRegion the area that is visible, relative to the
    2403             :    * reference frame; on return, this contains the area visible under the list.
    2404             :    * I.e., opaque contents of this list are subtracted from aVisibleRegion.
    2405             :    * @param aListVisibleBounds must be equal to the bounds of the intersection
    2406             :    * of aVisibleRegion and GetBounds() for this list.
    2407             :    * @return true if any item in the list is visible.
    2408             :    */
    2409             :   bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
    2410             :                                    nsRegion* aVisibleRegion,
    2411             :                                    const nsRect& aListVisibleBounds);
    2412             : 
    2413             :   /**
    2414             :    * As ComputeVisibilityForSublist, but computes visibility for a root
    2415             :    * list (a list that does not belong to an nsDisplayItem).
    2416             :    * This method needs to be idempotent.
    2417             :    *
    2418             :    * @param aVisibleRegion the area that is visible
    2419             :    */
    2420             :   bool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
    2421             :                                 nsRegion* aVisibleRegion);
    2422             : 
    2423             :   /**
    2424             :    * Returns true if the visible region output from ComputeVisiblity was
    2425             :    * empty, i.e. everything visible in this list is opaque.
    2426             :    */
    2427         271 :   bool IsOpaque() const {
    2428         271 :     return mIsOpaque;
    2429             :   }
    2430             : 
    2431             :   /**
    2432             :    * Returns true if any display item requires the surface to be transparent.
    2433             :    */
    2434         199 :   bool NeedsTransparentSurface() const {
    2435         199 :     return mForceTransparentSurface;
    2436             :   }
    2437             :   /**
    2438             :    * Paint the list to the rendering context. We assume that (0,0) in aCtx
    2439             :    * corresponds to the origin of the reference frame. For best results,
    2440             :    * aCtx's current transform should make (0,0) pixel-aligned. The
    2441             :    * rectangle in aDirtyRect is painted, which *must* be contained in the
    2442             :    * dirty rect used to construct the display list.
    2443             :    *
    2444             :    * If aFlags contains PAINT_USE_WIDGET_LAYERS and
    2445             :    * ShouldUseWidgetLayerManager() is set, then we will paint using
    2446             :    * the reference frame's widget's layer manager (and ctx may be null),
    2447             :    * otherwise we will use a temporary BasicLayerManager and ctx must
    2448             :    * not be null.
    2449             :    *
    2450             :    * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's
    2451             :    * layer manager has already had BeginTransaction() called on it and
    2452             :    * we should not call it again.
    2453             :    *
    2454             :    * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode
    2455             :    * to avoid short cut optimizations.
    2456             :    *
    2457             :    * This must only be called on the root display list of the display list
    2458             :    * tree.
    2459             :    *
    2460             :    * We return the layer manager used for painting --- mainly so that
    2461             :    * callers can dump its layer tree if necessary.
    2462             :    */
    2463             :   enum {
    2464             :     PAINT_DEFAULT = 0,
    2465             :     PAINT_USE_WIDGET_LAYERS = 0x01,
    2466             :     PAINT_EXISTING_TRANSACTION = 0x04,
    2467             :     PAINT_NO_COMPOSITE = 0x08,
    2468             :     PAINT_COMPRESSED = 0x10
    2469             :   };
    2470             :   already_AddRefed<LayerManager> PaintRoot(nsDisplayListBuilder* aBuilder,
    2471             :                                            gfxContext* aCtx,
    2472             :                                            uint32_t aFlags);
    2473             :   /**
    2474             :    * Get the bounds. Takes the union of the bounds of all children.
    2475             :    * The result is not cached.
    2476             :    */
    2477             :   nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
    2478             : 
    2479             :   /**
    2480             :    * Get this list's bounds, respecting clips relative to aASR. The result is
    2481             :    * the union of each item's clipped bounds with respect to aASR. That means
    2482             :    * that if an item can move asynchronously with an ASR that is a descendant
    2483             :    * of aASR, then the clipped bounds with respect to aASR will be the clip of
    2484             :    * that item for aASR, because the item can move anywhere inside that clip.
    2485             :    * If there is an item in this list which is not bounded with respect to
    2486             :    * aASR (i.e. which does not have "finite bounds" with respect to aASR),
    2487             :    * then this method trigger an assertion failure.
    2488             :    */
    2489             :   nsRect GetClippedBoundsWithRespectToASR(nsDisplayListBuilder* aBuilder,
    2490             :                                           const ActiveScrolledRoot* aASR) const;
    2491             : 
    2492             :   /**
    2493             :    * Find the topmost display item that returns a non-null frame, and return
    2494             :    * the frame.
    2495             :    */
    2496             :   void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    2497             :                nsDisplayItem::HitTestState* aState,
    2498             :                nsTArray<nsIFrame*> *aOutFrames) const;
    2499             :   /**
    2500             :    * Compute the union of the visible rects of the items in the list. The
    2501             :    * result is not cached.
    2502             :    */
    2503             :   nsRect GetVisibleRect() const;
    2504             : 
    2505          78 :   void SetIsOpaque()
    2506             :   {
    2507          78 :     mIsOpaque = true;
    2508          78 :   }
    2509           0 :   void SetNeedsTransparentSurface()
    2510             :   {
    2511           0 :     mForceTransparentSurface = true;
    2512           0 :   }
    2513             : 
    2514             : private:
    2515             :   // This class is only used on stack, so we don't have to worry about leaking
    2516             :   // it.  Don't let us be heap-allocated!
    2517             :   void* operator new(size_t sz) CPP_THROW_NEW;
    2518             : 
    2519             :   nsDisplayItemLink  mSentinel;
    2520             :   nsDisplayItemLink* mTop;
    2521             : 
    2522             :   // This is set to true by FrameLayerBuilder if the final visible region
    2523             :   // is empty (i.e. everything that was visible is covered by some
    2524             :   // opaque content in this list).
    2525             :   bool mIsOpaque;
    2526             :   // This is set to true by FrameLayerBuilder if any display item in this
    2527             :   // list needs to force the surface containing this list to be transparent.
    2528             :   bool mForceTransparentSurface;
    2529             : };
    2530             : 
    2531             : /**
    2532             :  * This is passed as a parameter to nsIFrame::BuildDisplayList. That method
    2533             :  * will put any generated items onto the appropriate list given here. It's
    2534             :  * basically just a collection with one list for each separate stacking layer.
    2535             :  * The lists themselves are external to this object and thus can be shared
    2536             :  * with others. Some of the list pointers may even refer to the same list.
    2537             :  */
    2538             : class nsDisplayListSet {
    2539             : public:
    2540             :   /**
    2541             :    * @return a list where one should place the border and/or background for
    2542             :    * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E)
    2543             :    */
    2544        3122 :   nsDisplayList* BorderBackground() const { return mBorderBackground; }
    2545             :   /**
    2546             :    * @return a list where one should place the borders and/or backgrounds for
    2547             :    * block-level in-flow descendants (step 4 of CSS 2.1 appendix E)
    2548             :    */
    2549        5773 :   nsDisplayList* BlockBorderBackgrounds() const { return mBlockBorderBackgrounds; }
    2550             :   /**
    2551             :    * @return a list where one should place descendant floats (step 5 of
    2552             :    * CSS 2.1 appendix E)
    2553             :    */
    2554        3926 :   nsDisplayList* Floats() const { return mFloats; }
    2555             :   /**
    2556             :    * @return a list where one should place the (pseudo) stacking contexts
    2557             :    * for descendants of this frame (everything from steps 3, 7 and 8
    2558             :    * of CSS 2.1 appendix E)
    2559             :    */
    2560        6479 :   nsDisplayList* PositionedDescendants() const { return mPositioned; }
    2561             :   /**
    2562             :    * @return a list where one should place the outlines
    2563             :    * for this frame and its descendants (step 9 of CSS 2.1 appendix E)
    2564             :    */
    2565        4539 :   nsDisplayList* Outlines() const { return mOutlines; }
    2566             :   /**
    2567             :    * @return a list where one should place all other content
    2568             :    */
    2569        9227 :   nsDisplayList* Content() const { return mContent; }
    2570             : 
    2571        3401 :   nsDisplayListSet(nsDisplayList* aBorderBackground,
    2572             :                    nsDisplayList* aBlockBorderBackgrounds,
    2573             :                    nsDisplayList* aFloats,
    2574             :                    nsDisplayList* aContent,
    2575             :                    nsDisplayList* aPositionedDescendants,
    2576        3401 :                    nsDisplayList* aOutlines) :
    2577             :      mBorderBackground(aBorderBackground),
    2578             :      mBlockBorderBackgrounds(aBlockBorderBackgrounds),
    2579             :      mFloats(aFloats),
    2580             :      mContent(aContent),
    2581             :      mPositioned(aPositionedDescendants),
    2582        3401 :      mOutlines(aOutlines) {
    2583        3401 :   }
    2584             : 
    2585             :   /**
    2586             :    * A copy constructor that lets the caller override the BorderBackground
    2587             :    * list.
    2588             :    */
    2589        2031 :   nsDisplayListSet(const nsDisplayListSet& aLists,
    2590        2031 :                    nsDisplayList* aBorderBackground) :
    2591             :      mBorderBackground(aBorderBackground),
    2592        2031 :      mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds()),
    2593        2031 :      mFloats(aLists.Floats()),
    2594        2031 :      mContent(aLists.Content()),
    2595        2031 :      mPositioned(aLists.PositionedDescendants()),
    2596       10155 :      mOutlines(aLists.Outlines()) {
    2597        2031 :   }
    2598             : 
    2599             :   /**
    2600             :    * Move all display items in our lists to top of the corresponding lists in the
    2601             :    * destination.
    2602             :    */
    2603             :   void MoveTo(const nsDisplayListSet& aDestination) const;
    2604             : 
    2605             : private:
    2606             :   // This class is only used on stack, so we don't have to worry about leaking
    2607             :   // it.  Don't let us be heap-allocated!
    2608             :   void* operator new(size_t sz) CPP_THROW_NEW;
    2609             : 
    2610             : protected:
    2611             :   nsDisplayList* mBorderBackground;
    2612             :   nsDisplayList* mBlockBorderBackgrounds;
    2613             :   nsDisplayList* mFloats;
    2614             :   nsDisplayList* mContent;
    2615             :   nsDisplayList* mPositioned;
    2616             :   nsDisplayList* mOutlines;
    2617             : };
    2618             : 
    2619             : /**
    2620             :  * A specialization of nsDisplayListSet where the lists are actually internal
    2621             :  * to the object, and all distinct.
    2622             :  */
    2623        3230 : struct nsDisplayListCollection : public nsDisplayListSet {
    2624        3230 :   nsDisplayListCollection() :
    2625             :     nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4],
    2626        3230 :                      &mLists[5]) {}
    2627             :   explicit nsDisplayListCollection(nsDisplayList* aBorderBackground) :
    2628             :     nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4],
    2629             :                      &mLists[5]) {}
    2630             : 
    2631             :   /**
    2632             :    * Sort all lists by content order.
    2633             :    */
    2634             :   void SortAllByContentOrder(nsIContent* aCommonAncestor) {
    2635             :     for (int32_t i = 0; i < 6; ++i) {
    2636             :       mLists[i].SortByContentOrder(aCommonAncestor);
    2637             :     }
    2638             :   }
    2639             : 
    2640             : private:
    2641             :   // This class is only used on stack, so we don't have to worry about leaking
    2642             :   // it.  Don't let us be heap-allocated!
    2643             :   void* operator new(size_t sz) CPP_THROW_NEW;
    2644             : 
    2645             :   nsDisplayList mLists[6];
    2646             : };
    2647             : 
    2648             : 
    2649         535 : class nsDisplayImageContainer : public nsDisplayItem {
    2650             : public:
    2651             :   typedef mozilla::LayerIntPoint LayerIntPoint;
    2652             :   typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
    2653             :   typedef mozilla::layers::ImageContainer ImageContainer;
    2654             :   typedef mozilla::layers::ImageLayer ImageLayer;
    2655             : 
    2656         535 :   nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    2657         535 :     : nsDisplayItem(aBuilder, aFrame)
    2658         535 :   {}
    2659             : 
    2660             :   /**
    2661             :    * @return true if this display item can be optimized into an image layer.
    2662             :    * It is an error to call GetContainer() unless you've called
    2663             :    * CanOptimizeToImageLayer() first and it returned true.
    2664             :    */
    2665             :   virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
    2666             :                                        nsDisplayListBuilder* aBuilder);
    2667             : 
    2668             :   already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
    2669             :                                                 nsDisplayListBuilder* aBuilder);
    2670             :   void ConfigureLayer(ImageLayer* aLayer,
    2671             :                       const ContainerLayerParameters& aParameters);
    2672             : 
    2673             :   virtual already_AddRefed<imgIContainer> GetImage() = 0;
    2674             : 
    2675             :   virtual nsRect GetDestRect() = 0;
    2676             : 
    2677          57 :   virtual bool SupportsOptimizingToImage() override { return true; }
    2678             : };
    2679             : 
    2680             : /**
    2681             :  * Use this class to implement not-very-frequently-used display items
    2682             :  * that are not opaque, do not receive events, and are bounded by a frame's
    2683             :  * border-rect.
    2684             :  *
    2685             :  * This should not be used for display items which are created frequently,
    2686             :  * because each item is one or two pointers bigger than an item from a
    2687             :  * custom display item class could be, and fractionally slower. However it does
    2688             :  * save code size. We use this for infrequently-used item types.
    2689             :  */
    2690             : class nsDisplayGeneric : public nsDisplayItem {
    2691             : public:
    2692             :   typedef void (* PaintCallback)(nsIFrame* aFrame, DrawTarget* aDrawTarget,
    2693             :                                  const nsRect& aDirtyRect, nsPoint aFramePt);
    2694             : 
    2695             :   // XXX: should be removed eventually
    2696             :   typedef void (* OldPaintCallback)(nsIFrame* aFrame, gfxContext* aCtx,
    2697             :                                     const nsRect& aDirtyRect, nsPoint aFramePt);
    2698             : 
    2699           0 :   nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    2700             :                    PaintCallback aPaint, const char* aName, Type aType)
    2701           0 :     : nsDisplayItem(aBuilder, aFrame)
    2702             :     , mPaint(aPaint)
    2703             :     , mOldPaint(nullptr)
    2704             :     , mName(aName)
    2705           0 :     , mType(aType)
    2706             :   {
    2707           0 :     MOZ_COUNT_CTOR(nsDisplayGeneric);
    2708           0 :   }
    2709             : 
    2710             :   // XXX: should be removed eventually
    2711           0 :   nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    2712             :                    OldPaintCallback aOldPaint, const char* aName, Type aType)
    2713           0 :     : nsDisplayItem(aBuilder, aFrame)
    2714             :     , mPaint(nullptr)
    2715             :     , mOldPaint(aOldPaint)
    2716             :     , mName(aName)
    2717           0 :     , mType(aType)
    2718             :   {
    2719           0 :     MOZ_COUNT_CTOR(nsDisplayGeneric);
    2720           0 :   }
    2721             : #ifdef NS_BUILD_REFCNT_LOGGING
    2722           0 :   virtual ~nsDisplayGeneric() {
    2723           0 :     MOZ_COUNT_DTOR(nsDisplayGeneric);
    2724           0 :   }
    2725             : #endif
    2726             : 
    2727           0 :   virtual void Paint(nsDisplayListBuilder* aBuilder,
    2728             :                      gfxContext* aCtx) override {
    2729           0 :     MOZ_ASSERT(!!mPaint != !!mOldPaint);
    2730           0 :     if (mPaint) {
    2731           0 :       mPaint(mFrame, aCtx->GetDrawTarget(), mVisibleRect, ToReferenceFrame());
    2732             :     } else {
    2733           0 :       mOldPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame());
    2734             :     }
    2735           0 :   }
    2736           0 :   NS_DISPLAY_DECL_NAME(mName, mType)
    2737             : 
    2738             : protected:
    2739             :   PaintCallback mPaint;
    2740             :   OldPaintCallback mOldPaint;   // XXX: should be removed eventually
    2741             :   const char* mName;
    2742             :   Type mType;
    2743             : };
    2744             : 
    2745             : #if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
    2746             : /**
    2747             :  * This class implements painting of reflow counts.  Ideally, we would simply
    2748             :  * make all the frame names be those returned by nsFrame::GetFrameName
    2749             :  * (except that tosses in the content tag name!)  and support only one color
    2750             :  * and eliminate this class altogether in favor of nsDisplayGeneric, but for
    2751             :  * the time being we can't pass args to a PaintCallback, so just have a
    2752             :  * separate class to do the right thing.  Sadly, this alsmo means we need to
    2753             :  * hack all leaf frame classes to handle this.
    2754             :  *
    2755             :  * XXXbz the color thing is a bit of a mess, but 0 basically means "not set"
    2756             :  * here...  I could switch it all to nscolor, but why bother?
    2757             :  */
    2758             : class nsDisplayReflowCount : public nsDisplayItem {
    2759             : public:
    2760           0 :   nsDisplayReflowCount(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    2761             :                        const char* aFrameName,
    2762             :                        uint32_t aColor = 0)
    2763           0 :     : nsDisplayItem(aBuilder, aFrame),
    2764             :       mFrameName(aFrameName),
    2765           0 :       mColor(aColor)
    2766             :   {
    2767           0 :     MOZ_COUNT_CTOR(nsDisplayReflowCount);
    2768           0 :   }
    2769             : #ifdef NS_BUILD_REFCNT_LOGGING
    2770           0 :   virtual ~nsDisplayReflowCount() {
    2771           0 :     MOZ_COUNT_DTOR(nsDisplayReflowCount);
    2772           0 :   }
    2773             : #endif
    2774             : 
    2775           0 :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override {
    2776           0 :     mFrame->PresContext()->PresShell()->PaintCount(mFrameName, aCtx,
    2777           0 :                                                    mFrame->PresContext(),
    2778             :                                                    mFrame, ToReferenceFrame(),
    2779           0 :                                                    mColor);
    2780           0 :   }
    2781           0 :   NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT)
    2782             : protected:
    2783             :   const char* mFrameName;
    2784             :   nscolor mColor;
    2785             : };
    2786             : 
    2787             : #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)                                     \
    2788             :   PR_BEGIN_MACRO                                                              \
    2789             :     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
    2790             :         PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
    2791             :         aLists.Outlines()->AppendNewToTop(                                    \
    2792             :             new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name));      \
    2793             :     }                                                                         \
    2794             :   PR_END_MACRO
    2795             : 
    2796             : #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)                       \
    2797             :   PR_BEGIN_MACRO                                                              \
    2798             :     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
    2799             :         PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
    2800             :         aLists.Outlines()->AppendNewToTop(                                    \
    2801             :              new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name, _color)); \
    2802             :     }                                                                         \
    2803             :   PR_END_MACRO
    2804             : 
    2805             : /*
    2806             :   Macro to be used for classes that don't actually implement BuildDisplayList
    2807             :  */
    2808             : #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)                   \
    2809             :   void BuildDisplayList(nsDisplayListBuilder*   aBuilder,                 \
    2810             :                         const nsRect&           aDirtyRect,               \
    2811             :                         const nsDisplayListSet& aLists) {                 \
    2812             :     DO_GLOBAL_REFLOW_COUNT_DSP(#_class);                                  \
    2813             :     _super::BuildDisplayList(aBuilder, aDirtyRect, aLists);               \
    2814             :   }
    2815             : 
    2816             : #else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
    2817             : 
    2818             : #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)
    2819             : #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)
    2820             : #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)
    2821             : 
    2822             : #endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
    2823             : 
    2824             : class nsDisplayCaret : public nsDisplayItem {
    2825             : public:
    2826             :   nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame);
    2827             : #ifdef NS_BUILD_REFCNT_LOGGING
    2828             :   virtual ~nsDisplayCaret();
    2829             : #endif
    2830             : 
    2831             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    2832             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    2833           0 :   NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
    2834             : 
    2835             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    2836             :                                    LayerManager* aManager,
    2837             :                                    const ContainerLayerParameters& aParameters) override;
    2838             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    2839             :                                              LayerManager* aManager,
    2840             :                                              const ContainerLayerParameters& aContainerParameters) override;
    2841             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    2842             :                                        const StackingContextHelper& aSc,
    2843             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    2844             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    2845             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    2846             : 
    2847             : protected:
    2848             :   RefPtr<nsCaret> mCaret;
    2849             :   nsRect mBounds;
    2850             : };
    2851             : 
    2852             : /**
    2853             :  * The standard display item to paint the CSS borders of a frame.
    2854             :  */
    2855             : class nsDisplayBorder : public nsDisplayItem {
    2856             : public:
    2857             :   nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    2858             : 
    2859             : #ifdef NS_BUILD_REFCNT_LOGGING
    2860         358 :   virtual ~nsDisplayBorder() {
    2861         179 :     MOZ_COUNT_DTOR(nsDisplayBorder);
    2862         179 :   }
    2863             : #endif
    2864             : 
    2865             :   virtual bool IsInvisibleInRect(const nsRect& aRect) override;
    2866             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    2867             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    2868             :                                    LayerManager* aManager,
    2869             :                                    const ContainerLayerParameters& aParameters) override;
    2870             : 
    2871             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    2872             :                                              LayerManager* aManager,
    2873             :                                              const ContainerLayerParameters& aContainerParameters) override;
    2874             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    2875             :                                        const StackingContextHelper& aSc,
    2876             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    2877             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    2878             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    2879             : 
    2880             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    2881             : 
    2882        1628 :   NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
    2883             : 
    2884             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
    2885             : 
    2886             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    2887             :                                          const nsDisplayItemGeometry* aGeometry,
    2888             :                                          nsRegion* aInvalidRegion) override;
    2889             : 
    2890           0 :   virtual nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
    2891             :   {
    2892           0 :     *aSnap = true;
    2893           0 :     return CalculateBounds(*mFrame->StyleBorder());
    2894             :   }
    2895             : 
    2896             : protected:
    2897             :   void CreateBorderImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    2898             :                                           const StackingContextHelper& aSc,
    2899             :                                           nsTArray<WebRenderParentCommand>& aParentCommands,
    2900             :                                           mozilla::layers::WebRenderLayerManager* aManager,
    2901             :                                           nsDisplayListBuilder* aDisplayListBuilder);
    2902             :   nsRegion CalculateBounds(const nsStyleBorder& aStyleBorder);
    2903             : 
    2904             :   mozilla::Array<mozilla::gfx::Color, 4> mColors;
    2905             :   mozilla::Array<mozilla::LayerCoord, 4> mWidths;
    2906             :   mozilla::Array<mozilla::LayerSize, 4> mCorners;
    2907             :   mozilla::Array<uint8_t, 4> mBorderStyles;
    2908             :   mozilla::LayerRect mRect;
    2909             : 
    2910             :   mozilla::Maybe<nsCSSBorderRenderer> mBorderRenderer;
    2911             :   mozilla::Maybe<nsCSSBorderImageRenderer> mBorderImageRenderer;
    2912             : 
    2913             :   nsRect mBounds;
    2914             : };
    2915             : 
    2916             : /**
    2917             :  * A simple display item that just renders a solid color across the
    2918             :  * specified bounds. For canvas frames (in the CSS sense) we split off the
    2919             :  * drawing of the background color into this class (from nsDisplayBackground
    2920             :  * via nsDisplayCanvasBackground). This is done so that we can always draw a
    2921             :  * background color to avoid ugly flashes of white when we can't draw a full
    2922             :  * frame tree (ie when a page is loading). The bounds can differ from the
    2923             :  * frame's bounds -- this is needed when a frame/iframe is loading and there
    2924             :  * is not yet a frame tree to go in the frame/iframe so we use the subdoc
    2925             :  * frame of the parent document as a standin.
    2926             :  */
    2927          46 : class nsDisplaySolidColorBase : public nsDisplayItem {
    2928             : public:
    2929          46 :   nsDisplaySolidColorBase(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nscolor aColor)
    2930          46 :     : nsDisplayItem(aBuilder, aFrame), mColor(aColor)
    2931          46 :   {}
    2932             : 
    2933           3 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    2934             :   {
    2935           3 :     return new nsDisplaySolidColorGeometry(this, aBuilder, mColor);
    2936             :   }
    2937             : 
    2938          23 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    2939             :                                          const nsDisplayItemGeometry* aGeometry,
    2940             :                                          nsRegion* aInvalidRegion) override
    2941             :   {
    2942             :     const nsDisplaySolidColorGeometry* geometry =
    2943          23 :       static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
    2944          23 :     if (mColor != geometry->mColor) {
    2945             :       bool dummy;
    2946           0 :       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
    2947           0 :       return;
    2948             :     }
    2949          23 :     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
    2950             :   }
    2951             : 
    2952          47 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    2953             :                                    bool* aSnap) override {
    2954          47 :     *aSnap = false;
    2955          47 :     nsRegion result;
    2956          47 :     if (NS_GET_A(mColor) == 255) {
    2957          29 :       result = GetBounds(aBuilder, aSnap);
    2958             :     }
    2959          47 :     return result;
    2960             :   }
    2961             : 
    2962          46 :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override
    2963             :   {
    2964          46 :     return mozilla::Some(mColor);
    2965             :   }
    2966             : 
    2967             : protected:
    2968             :   nscolor mColor;
    2969             : };
    2970             : 
    2971             : class nsDisplaySolidColor : public nsDisplaySolidColorBase {
    2972             : public:
    2973          26 :   nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    2974             :                       const nsRect& aBounds, nscolor aColor)
    2975          26 :     : nsDisplaySolidColorBase(aBuilder, aFrame, aColor), mBounds(aBounds)
    2976             :   {
    2977          26 :     NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
    2978          26 :     MOZ_COUNT_CTOR(nsDisplaySolidColor);
    2979          26 :   }
    2980             : #ifdef NS_BUILD_REFCNT_LOGGING
    2981          52 :   virtual ~nsDisplaySolidColor() {
    2982          26 :     MOZ_COUNT_DTOR(nsDisplaySolidColor);
    2983          26 :   }
    2984             : #endif
    2985             : 
    2986             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    2987             : 
    2988             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    2989             :                                    LayerManager* aManager,
    2990             :                                    const ContainerLayerParameters& aParameters) override;
    2991             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    2992             :                                              LayerManager* aManager,
    2993             :                                              const ContainerLayerParameters& aContainerParameters) override;
    2994             : 
    2995             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    2996             : 
    2997             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    2998             : 
    2999         232 :   NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
    3000             : 
    3001             : private:
    3002             :   nsRect  mBounds;
    3003             : };
    3004             : 
    3005             : /**
    3006             :  * A display item that renders a solid color over a region. This is not
    3007             :  * exposed through CSS, its only purpose is efficient invalidation of
    3008             :  * the find bar highlighter dimmer.
    3009             :  */
    3010             : class nsDisplaySolidColorRegion : public nsDisplayItem {
    3011             :   typedef mozilla::gfx::Color Color;
    3012             : 
    3013             : public:
    3014           0 :   nsDisplaySolidColorRegion(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3015             :                             const nsRegion& aRegion, nscolor aColor)
    3016           0 :     : nsDisplayItem(aBuilder, aFrame), mRegion(aRegion), mColor(Color::FromABGR(aColor))
    3017             :   {
    3018           0 :     NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColorRegions!");
    3019           0 :     MOZ_COUNT_CTOR(nsDisplaySolidColorRegion);
    3020           0 :   }
    3021             : #ifdef NS_BUILD_REFCNT_LOGGING
    3022           0 :   virtual ~nsDisplaySolidColorRegion() {
    3023           0 :     MOZ_COUNT_DTOR(nsDisplaySolidColorRegion);
    3024           0 :   }
    3025             : #endif
    3026             : 
    3027           0 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3028             :   {
    3029           0 :     return new nsDisplaySolidColorRegionGeometry(this, aBuilder, mRegion, mColor);
    3030             :   }
    3031             : 
    3032           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3033             :                                          const nsDisplayItemGeometry* aGeometry,
    3034             :                                          nsRegion* aInvalidRegion) override
    3035             :   {
    3036             :     const nsDisplaySolidColorRegionGeometry* geometry =
    3037           0 :       static_cast<const nsDisplaySolidColorRegionGeometry*>(aGeometry);
    3038           0 :     if (mColor == geometry->mColor) {
    3039           0 :       aInvalidRegion->Xor(geometry->mRegion, mRegion);
    3040             :     } else {
    3041           0 :       aInvalidRegion->Or(geometry->mRegion.GetBounds(), mRegion.GetBounds());
    3042             :     }
    3043           0 :   }
    3044             : 
    3045             : protected:
    3046             : 
    3047             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    3048             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3049             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    3050             : 
    3051           0 :   NS_DISPLAY_DECL_NAME("SolidColorRegion", TYPE_SOLID_COLOR_REGION)
    3052             : 
    3053             : private:
    3054             :   nsRegion mRegion;
    3055             :   Color mColor;
    3056             : };
    3057             : 
    3058             : /**
    3059             :  * A display item to paint one background-image for a frame. Each background
    3060             :  * image layer gets its own nsDisplayBackgroundImage.
    3061             :  */
    3062             : class nsDisplayBackgroundImage : public nsDisplayImageContainer {
    3063             : public:
    3064             :   typedef mozilla::StyleGeometryBox StyleGeometryBox;
    3065             : 
    3066         194 :   struct InitData {
    3067             :     nsDisplayListBuilder* builder;
    3068             :     nsIFrame* frame;
    3069             :     const nsStyleBackground* backgroundStyle;
    3070             :     nsCOMPtr<imgIContainer> image;
    3071             :     nsRect backgroundRect;
    3072             :     nsRect fillArea;
    3073             :     nsRect destArea;
    3074             :     uint32_t layer;
    3075             :     bool isRasterImage;
    3076             :     bool shouldFixToViewport;
    3077             :   };
    3078             : 
    3079             :   /**
    3080             :    * aLayer signifies which background layer this item represents.
    3081             :    * aIsThemed should be the value of aFrame->IsThemed.
    3082             :    * aBackgroundStyle should be the result of
    3083             :    * nsCSSRendering::FindBackground, or null if FindBackground returned false.
    3084             :    * aBackgroundRect is relative to aFrame.
    3085             :    */
    3086             :   enum class LayerizeFixed : uint8_t {
    3087             :     ALWAYS_LAYERIZE_FIXED_BACKGROUND,
    3088             :     DO_NOT_LAYERIZE_FIXED_BACKGROUND_IF_AVOIDING_COMPONENT_ALPHA_LAYERS
    3089             :   };
    3090             :   static InitData GetInitData(nsDisplayListBuilder* aBuilder,
    3091             :                               nsIFrame* aFrame,
    3092             :                               uint32_t aLayer,
    3093             :                               const nsRect& aBackgroundRect,
    3094             :                               const nsStyleBackground* aBackgroundStyle,
    3095             :                               LayerizeFixed aLayerizeFixed);
    3096             : 
    3097             :   explicit nsDisplayBackgroundImage(const InitData& aInitData);
    3098             :   virtual ~nsDisplayBackgroundImage();
    3099             : 
    3100             :   // This will create and append new items for all the layers of the
    3101             :   // background. Returns whether we appended a themed background.
    3102             :   // aAllowWillPaintBorderOptimization should usually be left at true, unless
    3103             :   // aFrame has special border drawing that causes opaque borders to not
    3104             :   // actually be opaque.
    3105             :   static bool AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
    3106             :                                          nsIFrame* aFrame,
    3107             :                                          const nsRect& aBackgroundRect,
    3108             :                                          nsDisplayList* aList,
    3109             :                                          bool aAllowWillPaintBorderOptimization = true,
    3110             :                                          nsStyleContext* aStyleContext = nullptr,
    3111             :                                          const nsRect& aBackgroundOriginRect = nsRect(),
    3112             :                                          nsIFrame* aSecondaryReferenceFrame = nullptr);
    3113             : 
    3114             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3115             :                                    LayerManager* aManager,
    3116             :                                    const ContainerLayerParameters& aParameters) override;
    3117             : 
    3118             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3119             :                                              LayerManager* aManager,
    3120             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3121             : 
    3122             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3123             :                                        const StackingContextHelper& aSc,
    3124             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    3125             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3126             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3127             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    3128             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    3129             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    3130             :                                  nsRegion* aVisibleRegion) override;
    3131             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3132             :                                    bool* aSnap) override;
    3133             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
    3134             :   /**
    3135             :    * GetBounds() returns the background painting area.
    3136             :    */
    3137             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    3138             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3139             :   virtual uint32_t GetPerFrameKey() override;
    3140        1530 :   NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
    3141             : 
    3142             :   /**
    3143             :    * Return the background positioning area.
    3144             :    * (GetBounds() returns the background painting area.)
    3145             :    * Can be called only when mBackgroundStyle is non-null.
    3146             :    */
    3147             :   nsRect GetPositioningArea();
    3148             : 
    3149             :   /**
    3150             :    * Returns true if existing rendered pixels of this display item may need
    3151             :    * to be redrawn if the positioning area size changes but its position does
    3152             :    * not.
    3153             :    * If false, only the changed painting area needs to be redrawn when the
    3154             :    * positioning area size changes but its position does not.
    3155             :    */
    3156             :   bool RenderingMightDependOnPositioningAreaSizeChange();
    3157             : 
    3158          16 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3159             :   {
    3160          16 :     return new nsDisplayBackgroundGeometry(this, aBuilder);
    3161             :   }
    3162             : 
    3163             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3164             :                                          const nsDisplayItemGeometry* aGeometry,
    3165             :                                          nsRegion* aInvalidRegion) override;
    3166             : 
    3167             :   virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
    3168             :                                        nsDisplayListBuilder* aBuilder) override;
    3169             :   virtual already_AddRefed<imgIContainer> GetImage() override;
    3170             :   virtual nsRect GetDestRect() override;
    3171             : 
    3172             :   static nsRegion GetInsideClipRegion(nsDisplayItem* aItem,
    3173             :                                       StyleGeometryBox aClip,
    3174             :                                       const nsRect& aRect,
    3175             :                                       const nsRect& aBackgroundRect);
    3176             : 
    3177           0 :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override { return mShouldFixToViewport; }
    3178             : 
    3179             : protected:
    3180             :   typedef class mozilla::layers::ImageContainer ImageContainer;
    3181             :   typedef class mozilla::layers::ImageLayer ImageLayer;
    3182             : 
    3183             :   bool CanBuildWebRenderDisplayItems(LayerManager* aManager);
    3184             :   bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
    3185             :   nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder);
    3186             : 
    3187             :   void PaintInternal(nsDisplayListBuilder* aBuilder, gfxContext* aCtx,
    3188             :                      const nsRect& aBounds, nsRect* aClipRect);
    3189             : 
    3190         310 :   virtual nsIFrame* StyleFrame() { return mFrame; }
    3191             : 
    3192             :   // Determine whether we want to be separated into our own layer, independent
    3193             :   // of whether this item can actually be layerized.
    3194             :   enum ImageLayerization {
    3195             :     WHENEVER_POSSIBLE,
    3196             :     ONLY_FOR_SCALING,
    3197             :     NO_LAYER_NEEDED
    3198             :   };
    3199             :   ImageLayerization ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
    3200             :                                          LayerManager* aManager);
    3201             : 
    3202             :   // Cache the result of nsCSSRendering::FindBackground. Always null if
    3203             :   // mIsThemed is true or if FindBackground returned false.
    3204             :   const nsStyleBackground* mBackgroundStyle;
    3205             :   nsCOMPtr<imgIContainer> mImage;
    3206             :   nsRect mBackgroundRect; // relative to the reference frame
    3207             :   nsRect mFillRect;
    3208             :   nsRect mDestRect;
    3209             :   /* Bounds of this display item */
    3210             :   nsRect mBounds;
    3211             :   uint32_t mLayer;
    3212             :   bool mIsRasterImage;
    3213             :   /* Whether the image should be treated as fixed to the viewport. */
    3214             :   bool mShouldFixToViewport;
    3215             :   uint32_t mImageFlags;
    3216             : };
    3217             : 
    3218             : enum class TableType : uint8_t {
    3219             :   TABLE,
    3220             :   TABLE_COL,
    3221             :   TABLE_COL_GROUP,
    3222             :   TABLE_ROW,
    3223             :   TABLE_ROW_GROUP,
    3224             :   TABLE_CELL,
    3225             : 
    3226             :   TABLE_TYPE_MAX
    3227             : };
    3228             : 
    3229             : enum class TableTypeBits : uint8_t {
    3230             :   COUNT = 3
    3231             : };
    3232             : 
    3233             : static_assert(
    3234             :   static_cast<uint8_t>(TableType::TABLE_TYPE_MAX) < (1 << (static_cast<uint8_t>(TableTypeBits::COUNT) + 1)),
    3235             :   "TableType cannot fit with TableTypeBits::COUNT");
    3236             : TableType GetTableTypeFromFrame(nsIFrame* aFrame);
    3237             : 
    3238             : /**
    3239             :  * A display item to paint background image for table. For table parts, such
    3240             :  * as row, row group, col, col group, when drawing its background, we'll
    3241             :  * create separate background image display item for its containning cell.
    3242             :  * Those background image display items will reference to same DisplayItemData
    3243             :  * if we keep the mFrame point to cell's ancestor frame. We don't want to this
    3244             :  * happened bacause share same DisplatItemData will cause many bugs. So that
    3245             :  * we let mFrame point to cell frame and store the table type of the ancestor
    3246             :  * frame. And use mFrame and table type as key to generate DisplayItemData to
    3247             :  * avoid sharing DisplayItemData.
    3248             :  *
    3249             :  * Also store ancestor frame as mStyleFrame for all rendering informations.
    3250             :  */
    3251           0 : class nsDisplayTableBackgroundImage : public nsDisplayBackgroundImage {
    3252             : public:
    3253             :   nsDisplayTableBackgroundImage(const InitData& aInitData, nsIFrame* aCellFrame);
    3254             : 
    3255           0 :   virtual uint32_t GetPerFrameKey() override {
    3256           0 :     return (static_cast<uint8_t>(mTableType) << nsDisplayItem::TYPE_BITS) |
    3257           0 :            nsDisplayItem::GetPerFrameKey();
    3258             :   }
    3259             : 
    3260             :   virtual bool IsInvalid(nsRect& aRect) override;
    3261             : protected:
    3262           0 :   virtual nsIFrame* StyleFrame() override { return mStyleFrame; }
    3263             : 
    3264             :   nsIFrame* mStyleFrame;
    3265             :   TableType mTableType;
    3266             : };
    3267             : 
    3268             : /**
    3269             :  * A display item to paint the native theme background for a frame.
    3270             :  */
    3271             : class nsDisplayThemedBackground : public nsDisplayItem {
    3272             : public:
    3273             :   nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3274             :                             const nsRect& aBackgroundRect);
    3275             :   virtual ~nsDisplayThemedBackground();
    3276             : 
    3277             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    3278             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    3279             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3280             :                                    bool* aSnap) override;
    3281             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
    3282             :   virtual bool ProvidesFontSmoothingBackgroundColor(nscolor* aColor) override;
    3283             : 
    3284             :   /**
    3285             :    * GetBounds() returns the background painting area.
    3286             :    */
    3287             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    3288             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3289         406 :   NS_DISPLAY_DECL_NAME("ThemedBackground", TYPE_THEMED_BACKGROUND)
    3290             : 
    3291             :   /**
    3292             :    * Return the background positioning area.
    3293             :    * (GetBounds() returns the background painting area.)
    3294             :    * Can be called only when mBackgroundStyle is non-null.
    3295             :    */
    3296             :   nsRect GetPositioningArea();
    3297             : 
    3298             :   /**
    3299             :    * Return whether our frame's document does not have the state
    3300             :    * NS_DOCUMENT_STATE_WINDOW_INACTIVE.
    3301             :    */
    3302             :   bool IsWindowActive();
    3303             : 
    3304           4 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3305             :   {
    3306           4 :     return new nsDisplayThemedBackgroundGeometry(this, aBuilder);
    3307             :   }
    3308             : 
    3309             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3310             :                                          const nsDisplayItemGeometry* aGeometry,
    3311             :                                          nsRegion* aInvalidRegion) override;
    3312             : 
    3313             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    3314             : protected:
    3315             :   nsRect GetBoundsInternal();
    3316             : 
    3317             :   void PaintInternal(nsDisplayListBuilder* aBuilder, gfxContext* aCtx,
    3318             :                      const nsRect& aBounds, nsRect* aClipRect);
    3319             : 
    3320             :   nsRect mBackgroundRect;
    3321             :   nsRect mBounds;
    3322             :   nsITheme::Transparency mThemeTransparency;
    3323             :   uint8_t mAppearance;
    3324             : };
    3325             : 
    3326         292 : class nsDisplayBackgroundColor : public nsDisplayItem
    3327             : {
    3328             :   typedef mozilla::gfx::Color Color;
    3329             : 
    3330             : public:
    3331         292 :   nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3332             :                            const nsRect& aBackgroundRect,
    3333             :                            const nsStyleBackground* aBackgroundStyle,
    3334             :                            nscolor aColor)
    3335         292 :     : nsDisplayItem(aBuilder, aFrame)
    3336             :     , mBackgroundRect(aBackgroundRect)
    3337             :     , mBackgroundStyle(aBackgroundStyle)
    3338         292 :     , mColor(Color::FromABGR(aColor))
    3339         292 :   { }
    3340             : 
    3341             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3342             :                                    LayerManager* aManager,
    3343             :                                    const ContainerLayerParameters& aParameters) override;
    3344             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3345             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3346             :                                              LayerManager* aManager,
    3347             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3348             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3349             :                                        const StackingContextHelper& aSc,
    3350             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    3351             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3352             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3353             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3354             :                                    bool* aSnap) override;
    3355             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
    3356             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    3357             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    3358             : 
    3359             :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    3360             :                             float aOpacity,
    3361             :                             const DisplayItemClipChain* aClip) override;
    3362             :   virtual bool CanApplyOpacity() const override;
    3363             : 
    3364         862 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
    3365             :   {
    3366         862 :     *aSnap = true;
    3367         862 :     return mBackgroundRect;
    3368             :   }
    3369             : 
    3370          19 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3371             :   {
    3372          38 :     return new nsDisplaySolidColorGeometry(this, aBuilder, mColor.ToABGR());
    3373             :   }
    3374             : 
    3375         144 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3376             :                                          const nsDisplayItemGeometry* aGeometry,
    3377             :                                          nsRegion* aInvalidRegion) override
    3378             :   {
    3379         144 :     const nsDisplaySolidColorGeometry* geometry = static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
    3380         144 :     if (mColor.ToABGR() != geometry->mColor) {
    3381             :       bool dummy;
    3382           0 :       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
    3383           0 :       return;
    3384             :     }
    3385         144 :     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
    3386             :   }
    3387             : 
    3388        1508 :   NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
    3389             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    3390             : 
    3391             : protected:
    3392             :   const nsRect mBackgroundRect;
    3393             :   const nsStyleBackground* mBackgroundStyle;
    3394             :   mozilla::gfx::Color mColor;
    3395             : };
    3396             : 
    3397           0 : class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor
    3398             : {
    3399             : public:
    3400           0 :   nsDisplayTableBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3401             :                                 const nsRect& aBackgroundRect,
    3402             :                                 const nsStyleBackground* aBackgroundStyle,
    3403             :                                 nscolor aColor,
    3404             :                                 nsIFrame* aAncestorFrame)
    3405           0 :     : nsDisplayBackgroundColor(aBuilder, aFrame, aBackgroundRect, aBackgroundStyle, aColor)
    3406           0 :     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
    3407           0 :   { }
    3408             : 
    3409           0 :   virtual uint32_t GetPerFrameKey() override {
    3410           0 :     return (static_cast<uint8_t>(mTableType) << nsDisplayItem::TYPE_BITS) |
    3411           0 :            nsDisplayItem::GetPerFrameKey();
    3412             :   }
    3413             : protected:
    3414             :   TableType mTableType;
    3415             : };
    3416             : 
    3417           0 : class nsDisplayClearBackground : public nsDisplayItem
    3418             : {
    3419             : public:
    3420           0 :   nsDisplayClearBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    3421           0 :     : nsDisplayItem(aBuilder, aFrame)
    3422           0 :   { }
    3423             : 
    3424           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
    3425             :   {
    3426           0 :     *aSnap = true;
    3427           0 :     return nsRect(ToReferenceFrame(), Frame()->GetSize());
    3428             :   }
    3429             : 
    3430           0 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3431             :                                    bool* aSnap) override {
    3432           0 :     *aSnap = false;
    3433           0 :     return GetBounds(aBuilder, aSnap);
    3434             :   }
    3435             : 
    3436           0 :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override
    3437             :   {
    3438           0 :     return mozilla::Some(NS_RGBA(0, 0, 0, 0));
    3439             :   }
    3440             : 
    3441           0 :   virtual bool ClearsBackground() override
    3442             :   {
    3443           0 :     return true;
    3444             :   }
    3445             : 
    3446           0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3447             :                                    LayerManager* aManager,
    3448             :                                    const ContainerLayerParameters& aParameters) override
    3449             :   {
    3450           0 :     return mozilla::LAYER_ACTIVE_FORCE;
    3451             :   }
    3452             : 
    3453             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3454             :                                              LayerManager* aManager,
    3455             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3456             : 
    3457           0 :   NS_DISPLAY_DECL_NAME("ClearBackground", TYPE_CLEAR_BACKGROUND)
    3458             : };
    3459             : 
    3460             : /**
    3461             :  * The standard display item to paint the outer CSS box-shadows of a frame.
    3462             :  */
    3463             : class nsDisplayBoxShadowOuter final : public nsDisplayItem {
    3464             : public:
    3465          48 :   nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    3466          48 :     : nsDisplayItem(aBuilder, aFrame)
    3467          48 :     , mOpacity(1.0) {
    3468          48 :     MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
    3469          48 :     mBounds = GetBoundsInternal();
    3470          48 :   }
    3471             : #ifdef NS_BUILD_REFCNT_LOGGING
    3472          96 :   virtual ~nsDisplayBoxShadowOuter() {
    3473          48 :     MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter);
    3474          48 :   }
    3475             : #endif
    3476             : 
    3477             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3478             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    3479             :   virtual bool IsInvisibleInRect(const nsRect& aRect) override;
    3480             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    3481             :                                  nsRegion* aVisibleRegion) override;
    3482         331 :   NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
    3483             : 
    3484             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3485             :                                          const nsDisplayItemGeometry* aGeometry,
    3486             :                                          nsRegion* aInvalidRegion) override;
    3487             : 
    3488           0 :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    3489             :                             float aOpacity,
    3490             :                             const DisplayItemClipChain* aClip) override
    3491             :   {
    3492           0 :     NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
    3493           0 :     mOpacity = aOpacity;
    3494           0 :     IntersectClip(aBuilder, aClip);
    3495           0 :   }
    3496           0 :   virtual bool CanApplyOpacity() const override
    3497             :   {
    3498           0 :     return true;
    3499             :   }
    3500             : 
    3501           8 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3502             :   {
    3503           8 :     return new nsDisplayBoxShadowOuterGeometry(this, aBuilder, mOpacity);
    3504             :   }
    3505             : 
    3506             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3507             :                                    LayerManager* aManager,
    3508             :                                    const ContainerLayerParameters& aParameters) override;
    3509             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3510             :                                              LayerManager* aManager,
    3511             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3512             : 
    3513             :   bool CanBuildWebRenderDisplayItems();
    3514             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3515             :                                        const StackingContextHelper& aSc,
    3516             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    3517             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3518             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3519             :   nsRect GetBoundsInternal();
    3520             : 
    3521             : private:
    3522             :   nsRegion mVisibleRegion;
    3523             :   nsRect mBounds;
    3524             :   float mOpacity;
    3525             : };
    3526             : 
    3527             : /**
    3528             :  * The standard display item to paint the inner CSS box-shadows of a frame.
    3529             :  */
    3530             : class nsDisplayBoxShadowInner : public nsDisplayItem {
    3531             : public:
    3532          24 :   nsDisplayBoxShadowInner(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    3533          24 :     : nsDisplayItem(aBuilder, aFrame) {
    3534          24 :     MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);
    3535          24 :   }
    3536             : #ifdef NS_BUILD_REFCNT_LOGGING
    3537          48 :   virtual ~nsDisplayBoxShadowInner() {
    3538          24 :     MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);
    3539          24 :   }
    3540             : #endif
    3541             : 
    3542             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3543             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    3544             :                                  nsRegion* aVisibleRegion) override;
    3545         219 :   NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
    3546             : 
    3547           2 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3548             :   {
    3549           2 :     return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
    3550             :   }
    3551             : 
    3552          23 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3553             :                                          const nsDisplayItemGeometry* aGeometry,
    3554             :                                          nsRegion* aInvalidRegion) override
    3555             :   {
    3556          23 :     const nsDisplayBoxShadowInnerGeometry* geometry = static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry);
    3557          23 :     if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
    3558             :       // nsDisplayBoxShadowInner is based around the padding rect, but it can
    3559             :       // touch pixels outside of this. We should invalidate the entire bounds.
    3560             :       bool snap;
    3561           1 :       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
    3562             :     }
    3563          23 :   }
    3564             : 
    3565             :   static bool CanCreateWebRenderCommands(nsDisplayListBuilder* aBuilder,
    3566             :                                          nsIFrame* aFrame,
    3567             :                                          nsPoint aReferencePoint);
    3568             :   static void CreateInsetBoxShadowWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3569             :                                                     const StackingContextHelper& aSc,
    3570             :                                                     nsRegion& aVisibleRegion,
    3571             :                                                     nsIFrame* aFrame,
    3572             :                                                     const nsRect aBorderRect);
    3573             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3574             :                                    LayerManager* aManager,
    3575             :                                    const ContainerLayerParameters& aParameters) override;
    3576             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3577             :                                              LayerManager* aManager,
    3578             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3579             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3580             :                                        const StackingContextHelper& aSc,
    3581             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    3582             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3583             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3584             : 
    3585             : private:
    3586             :   nsRegion mVisibleRegion;
    3587             : };
    3588             : 
    3589             : /**
    3590             :  * The standard display item to paint the CSS outline of a frame.
    3591             :  */
    3592             : class nsDisplayOutline : public nsDisplayItem {
    3593             : public:
    3594           0 :   nsDisplayOutline(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
    3595           0 :     nsDisplayItem(aBuilder, aFrame) {
    3596           0 :     MOZ_COUNT_CTOR(nsDisplayOutline);
    3597           0 :   }
    3598             : #ifdef NS_BUILD_REFCNT_LOGGING
    3599           0 :   virtual ~nsDisplayOutline() {
    3600           0 :     MOZ_COUNT_DTOR(nsDisplayOutline);
    3601           0 :   }
    3602             : #endif
    3603             : 
    3604             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3605             :                                    LayerManager* aManager,
    3606             :                                    const ContainerLayerParameters& aParameters) override;
    3607             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3608             :                                              LayerManager* aManager,
    3609             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3610             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3611             :                                        const StackingContextHelper& aSc,
    3612             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    3613             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3614             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3615             :   virtual bool IsInvisibleInRect(const nsRect& aRect) override;
    3616             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    3617             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3618           0 :   NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
    3619             : 
    3620             :   mozilla::Maybe<nsCSSBorderRenderer> mBorderRenderer;
    3621             : };
    3622             : 
    3623             : /**
    3624             :  * A class that lets you receive events within the frame bounds but never paints.
    3625             :  */
    3626             : class nsDisplayEventReceiver : public nsDisplayItem {
    3627             : public:
    3628           0 :   nsDisplayEventReceiver(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    3629           0 :     : nsDisplayItem(aBuilder, aFrame) {
    3630           0 :     MOZ_COUNT_CTOR(nsDisplayEventReceiver);
    3631           0 :   }
    3632             : #ifdef NS_BUILD_REFCNT_LOGGING
    3633           0 :   virtual ~nsDisplayEventReceiver() {
    3634           0 :     MOZ_COUNT_DTOR(nsDisplayEventReceiver);
    3635           0 :   }
    3636             : #endif
    3637             : 
    3638             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    3639             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    3640           0 :   NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER)
    3641             : };
    3642             : 
    3643             : /**
    3644             :  * A display item that tracks event-sensitive regions which will be set
    3645             :  * on the ContainerLayer that eventually contains this item.
    3646             :  *
    3647             :  * One of these is created for each stacking context and pseudo-stacking-context.
    3648             :  * It accumulates regions for event targets contributed by the border-boxes of
    3649             :  * frames in its (pseudo) stacking context. A nsDisplayLayerEventRegions
    3650             :  * eventually contributes its regions to the PaintedLayer it is placed in by
    3651             :  * FrameLayerBuilder. (We don't create a display item for every frame that
    3652             :  * could be an event target (i.e. almost all frames), because that would be
    3653             :  * high overhead.)
    3654             :  *
    3655             :  * We always make leaf layers other than PaintedLayers transparent to events.
    3656             :  * For example, an event targeting a canvas or video will actually target the
    3657             :  * background of that element, which is logically in the PaintedLayer behind the
    3658             :  * CanvasFrame or ImageFrame. We only need to create a
    3659             :  * nsDisplayLayerEventRegions when an element's background could be in front
    3660             :  * of a lower z-order element with its own layer.
    3661             :  */
    3662             : class nsDisplayLayerEventRegions final : public nsDisplayItem {
    3663             : public:
    3664         647 :   nsDisplayLayerEventRegions(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    3665         647 :     : nsDisplayItem(aBuilder, aFrame)
    3666             :   {
    3667         647 :     MOZ_COUNT_CTOR(nsDisplayLayerEventRegions);
    3668         647 :   }
    3669             : #ifdef NS_BUILD_REFCNT_LOGGING
    3670        1294 :   virtual ~nsDisplayLayerEventRegions() {
    3671         647 :     MOZ_COUNT_DTOR(nsDisplayLayerEventRegions);
    3672         647 :   }
    3673             : #endif
    3674        1720 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
    3675             :   {
    3676        1720 :     *aSnap = false;
    3677        1720 :     return nsRect();
    3678             :   }
    3679         461 :   nsRect GetHitRegionBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
    3680             :   {
    3681         461 :     *aSnap = false;
    3682         461 :     return mHitRegion.GetBounds().Union(mMaybeHitRegion.GetBounds());
    3683             :   }
    3684             : 
    3685           0 :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    3686             :                             float aOpacity,
    3687             :                             const DisplayItemClipChain* aClip) override
    3688             :   {
    3689           0 :     NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
    3690           0 :   }
    3691           0 :   virtual bool CanApplyOpacity() const override
    3692             :   {
    3693           0 :     return true;
    3694             :   }
    3695             : 
    3696        1481 :   NS_DISPLAY_DECL_NAME("LayerEventRegions", TYPE_LAYER_EVENT_REGIONS)
    3697             : 
    3698             :   // Indicate that aFrame's border-box contributes to the event regions for
    3699             :   // this layer. aFrame must have the same reference frame as mFrame.
    3700             :   void AddFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    3701             : 
    3702             :   // Indicate that an inactive scrollframe's scrollport should be added to the
    3703             :   // dispatch-to-content region, to ensure that APZ lets content create a
    3704             :   // displayport.
    3705             :   void AddInactiveScrollPort(const nsRect& aRect);
    3706             : 
    3707             :   bool IsEmpty() const;
    3708             : 
    3709             :   int32_t ZIndex() const override;
    3710             :   void SetOverrideZIndex(int32_t aZIndex);
    3711             : 
    3712         461 :   const nsRegion& HitRegion() { return mHitRegion; }
    3713         461 :   const nsRegion& MaybeHitRegion() { return mMaybeHitRegion; }
    3714         461 :   const nsRegion& DispatchToContentHitRegion() { return mDispatchToContentHitRegion; }
    3715         461 :   const nsRegion& NoActionRegion() { return mNoActionRegion; }
    3716         461 :   const nsRegion& HorizontalPanRegion() { return mHorizontalPanRegion; }
    3717         461 :   const nsRegion& VerticalPanRegion() { return mVerticalPanRegion; }
    3718             :   nsRegion CombinedTouchActionRegion();
    3719             : 
    3720             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    3721             : 
    3722             : private:
    3723             :   // Relative to aFrame's reference frame.
    3724             :   // These are the points that are definitely in the hit region.
    3725             :   nsRegion mHitRegion;
    3726             :   // These are points that may or may not be in the hit region. Only main-thread
    3727             :   // event handling can tell for sure (e.g. because complex shapes are present).
    3728             :   nsRegion mMaybeHitRegion;
    3729             :   // These are points that need to be dispatched to the content thread for
    3730             :   // resolution. Always contained in the union of mHitRegion and mMaybeHitRegion.
    3731             :   nsRegion mDispatchToContentHitRegion;
    3732             :   // These are points where panning is disabled, as determined by the touch-action
    3733             :   // property. Always contained in the union of mHitRegion and mMaybeHitRegion.
    3734             :   nsRegion mNoActionRegion;
    3735             :   // These are points where panning is horizontal, as determined by the touch-action
    3736             :   // property. Always contained in the union of mHitRegion and mMaybeHitRegion.
    3737             :   nsRegion mHorizontalPanRegion;
    3738             :   // These are points where panning is vertical, as determined by the touch-action
    3739             :   // property. Always contained in the union of mHitRegion and mMaybeHitRegion.
    3740             :   nsRegion mVerticalPanRegion;
    3741             :   // If these event regions are for an inactive scroll frame, the z-index of
    3742             :   // this display item is overridden to be the largest z-index of the content
    3743             :   // in the scroll frame. This ensures that the event regions item remains on
    3744             :   // top of the content after sorting items by z-index.
    3745             :   mozilla::Maybe<int32_t> mOverrideZIndex;
    3746             : };
    3747             : 
    3748             : /**
    3749             :  * A class that lets you wrap a display list as a display item.
    3750             :  *
    3751             :  * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped
    3752             :  * list has many items, it's not clear which one has the 'underlying frame'.
    3753             :  * Thus we force the creator to specify what the underlying frame is. The
    3754             :  * underlying frame should be the root of a stacking context, because sorting
    3755             :  * a list containing this item will not get at the children.
    3756             :  *
    3757             :  * In some cases (e.g., clipping) we want to wrap a list but we don't have a
    3758             :  * particular underlying frame that is a stacking context root. In that case
    3759             :  * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must
    3760             :  * detect and handle this case.
    3761             :  */
    3762             : class nsDisplayWrapList : public nsDisplayItem {
    3763             : public:
    3764             :   /**
    3765             :    * Takes all the items from aList and puts them in our list.
    3766             :    */
    3767             :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3768             :                     nsDisplayList* aList);
    3769             :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3770             :                     nsDisplayList* aList,
    3771             :                     const ActiveScrolledRoot* aActiveScrolledRoot);
    3772             :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3773             :                     nsDisplayItem* aItem);
    3774           0 :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    3775           0 :     : nsDisplayItem(aBuilder, aFrame), mOverrideZIndex(0), mHasZIndexOverride(false)
    3776             :   {
    3777           0 :     MOZ_COUNT_CTOR(nsDisplayWrapList);
    3778           0 :     mBaseVisibleRect = mVisibleRect;
    3779           0 :   }
    3780             :   virtual ~nsDisplayWrapList();
    3781             :   /**
    3782             :    * Call this if the wrapped list is changed.
    3783             :    */
    3784         562 :   virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
    3785             :   {
    3786         562 :     mBounds = mList.GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot);
    3787             :     // The display list may contain content that's visible outside the visible
    3788             :     // rect (i.e. the current dirty rect) passed in when the item was created.
    3789             :     // This happens when the dirty rect has been restricted to the visual
    3790             :     // overflow rect of a frame for some reason (e.g. when setting up dirty
    3791             :     // rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that
    3792             :     // frame contains placeholders for out-of-flows that aren't descendants of
    3793             :     // the frame.
    3794         562 :     mVisibleRect.UnionRect(mBaseVisibleRect, mList.GetVisibleRect());
    3795         562 :   }
    3796             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    3797             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    3798             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    3799             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3800             :                                    bool* aSnap) override;
    3801             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
    3802             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3803             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    3804             :                                  nsRegion* aVisibleRegion) override;
    3805         517 :   virtual bool TryMerge(nsDisplayItem* aItem) override {
    3806         517 :     return false;
    3807             :   }
    3808         310 :   virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) override
    3809             :   {
    3810         310 :     aFrames->AppendElements(mMergedFrames);
    3811         310 :   }
    3812         312 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
    3813         312 :     return true;
    3814             :   }
    3815          90 :   virtual bool IsInvalid(nsRect& aRect) override
    3816             :   {
    3817          90 :     if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
    3818          17 :       return true;
    3819             :     }
    3820         146 :     nsRect temp;
    3821          73 :     for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
    3822           0 :       if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) {
    3823           0 :         aRect.SetEmpty();
    3824           0 :         return true;
    3825             :       }
    3826           0 :       aRect = aRect.Union(temp);
    3827             :     }
    3828          73 :     aRect += ToReferenceFrame();
    3829          73 :     return !aRect.IsEmpty();
    3830             :   }
    3831         378 :   NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
    3832             : 
    3833             :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override;
    3834             : 
    3835         520 :   virtual nsDisplayList* GetSameCoordinateSystemChildren() override
    3836             :   {
    3837         520 :     NS_ASSERTION(mList.IsEmpty() || !ReferenceFrame() ||
    3838             :                  !mList.GetBottom()->ReferenceFrame() ||
    3839             :                  mList.GetBottom()->ReferenceFrame() == ReferenceFrame(),
    3840             :                  "Children must have same reference frame");
    3841         520 :     return &mList;
    3842             :   }
    3843          76 :   virtual nsDisplayList* GetChildren() override { return &mList; }
    3844             : 
    3845         493 :   virtual int32_t ZIndex() const override
    3846             :   {
    3847         493 :     return (mHasZIndexOverride) ? mOverrideZIndex : nsDisplayItem::ZIndex();
    3848             :   }
    3849             : 
    3850           0 :   void SetOverrideZIndex(int32_t aZIndex)
    3851             :   {
    3852           0 :     mHasZIndexOverride = true;
    3853           0 :     mOverrideZIndex = aZIndex;
    3854           0 :   }
    3855             : 
    3856             :   void SetVisibleRect(const nsRect& aRect);
    3857             : 
    3858             :   void SetReferenceFrame(const nsIFrame* aFrame);
    3859             : 
    3860             :   /**
    3861             :    * This creates a copy of this item, but wrapping aItem instead of
    3862             :    * our existing list. Only gets called if this item returned nullptr
    3863             :    * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from
    3864             :    * GetUnderlyingFrame().
    3865             :    */
    3866           0 :   virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
    3867             :                                            nsDisplayItem* aItem) {
    3868           0 :     NS_NOTREACHED("We never returned nullptr for GetUnderlyingFrame!");
    3869           0 :     return nullptr;
    3870             :   }
    3871             : 
    3872             : protected:
    3873             :   nsDisplayWrapList() {}
    3874             : 
    3875           0 :   void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther)
    3876             :   {
    3877           0 :     mList.AppendToBottom(&aOther->mList);
    3878           0 :     mBounds.UnionRect(mBounds, aOther->mBounds);
    3879           0 :     mVisibleRect.UnionRect(mVisibleRect, aOther->mVisibleRect);
    3880           0 :     mMergedFrames.AppendElement(aOther->mFrame);
    3881           0 :     mMergedFrames.AppendElements(mozilla::Move(aOther->mMergedFrames));
    3882           0 :   }
    3883             : 
    3884             :   nsDisplayList mList;
    3885             :   // The frames from items that have been merged into this item, excluding
    3886             :   // this item's own frame.
    3887             :   nsTArray<nsIFrame*> mMergedFrames;
    3888             :   nsRect mBounds;
    3889             :   // Visible rect contributed by this display item itself.
    3890             :   // Our mVisibleRect may include the visible areas of children.
    3891             :   nsRect mBaseVisibleRect;
    3892             :   int32_t mOverrideZIndex;
    3893             :   bool mHasZIndexOverride;
    3894             : };
    3895             : 
    3896             : /**
    3897             :  * We call WrapDisplayList on the in-flow lists: BorderBackground(),
    3898             :  * BlockBorderBackgrounds() and Content().
    3899             :  * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(),
    3900             :  * and Floats(). This is done to support special wrapping processing for frames
    3901             :  * that may not be in-flow descendants of the current frame.
    3902             :  */
    3903             : class nsDisplayWrapper {
    3904             : public:
    3905             :   // This is never instantiated directly (it has pure virtual methods), so no
    3906             :   // need to count constructors and destructors.
    3907             : 
    3908           0 :   virtual bool WrapBorderBackground() { return true; }
    3909             :   virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
    3910             :                                   nsIFrame* aFrame, nsDisplayList* aList) = 0;
    3911             :   virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
    3912             :                                   nsDisplayItem* aItem) = 0;
    3913             : 
    3914             :   nsresult WrapLists(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3915             :                      const nsDisplayListSet& aIn, const nsDisplayListSet& aOut);
    3916             :   nsresult WrapListsInPlace(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3917             :                             const nsDisplayListSet& aLists);
    3918             : protected:
    3919           0 :   nsDisplayWrapper() {}
    3920             : };
    3921             : 
    3922             : /**
    3923             :  * The standard display item to paint a stacking context with translucency
    3924             :  * set by the stacking context root frame's 'opacity' style.
    3925             :  */
    3926             : class nsDisplayOpacity : public nsDisplayWrapList {
    3927             : public:
    3928             :   nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3929             :                    nsDisplayList* aList,
    3930             :                    const ActiveScrolledRoot* aActiveScrolledRoot,
    3931             :                    bool aForEventsAndPluginsOnly);
    3932             : #ifdef NS_BUILD_REFCNT_LOGGING
    3933             :   virtual ~nsDisplayOpacity();
    3934             : #endif
    3935             : 
    3936             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3937             :                                    bool* aSnap) override;
    3938             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3939             :                                              LayerManager* aManager,
    3940             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3941             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3942             :                                    LayerManager* aManager,
    3943             :                                    const ContainerLayerParameters& aParameters) override;
    3944             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    3945             :                                  nsRegion* aVisibleRegion) override;
    3946             :   virtual bool TryMerge(nsDisplayItem* aItem) override;
    3947         123 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3948             :                                          const nsDisplayItemGeometry* aGeometry,
    3949             :                                          nsRegion* aInvalidRegion) override
    3950             :   {
    3951             :     // We don't need to compute an invalidation region since we have LayerTreeInvalidation
    3952         123 :   }
    3953         127 :   virtual bool IsInvalid(nsRect& aRect) override
    3954             :   {
    3955         127 :     if (mForEventsAndPluginsOnly) {
    3956          69 :       return false;
    3957             :     }
    3958          58 :     return nsDisplayWrapList::IsInvalid(aRect);
    3959             :   }
    3960             :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    3961             :                             float aOpacity,
    3962             :                             const DisplayItemClipChain* aClip) override;
    3963             :   virtual bool CanApplyOpacity() const override;
    3964             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
    3965             :   static bool NeedsActiveLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    3966        2458 :   NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
    3967             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    3968             : 
    3969             :   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
    3970             : 
    3971             : private:
    3972             :   float mOpacity;
    3973             :   bool mForEventsAndPluginsOnly;
    3974             : };
    3975             : 
    3976             : class nsDisplayBlendMode : public nsDisplayWrapList {
    3977             : public:
    3978             :   nsDisplayBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3979             :                         nsDisplayList* aList, uint8_t aBlendMode,
    3980             :                         const ActiveScrolledRoot* aActiveScrolledRoot,
    3981             :                         uint32_t aIndex = 0);
    3982             : #ifdef NS_BUILD_REFCNT_LOGGING
    3983             :   virtual ~nsDisplayBlendMode();
    3984             : #endif
    3985             : 
    3986             :   nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3987             :                            bool* aSnap) override;
    3988             : 
    3989             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3990             :                                              LayerManager* aManager,
    3991             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3992           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3993             :                                          const nsDisplayItemGeometry* aGeometry,
    3994             :                                          nsRegion* aInvalidRegion) override
    3995             :   {
    3996             :     // We don't need to compute an invalidation region since we have LayerTreeInvalidation
    3997           0 :   }
    3998           0 :   virtual uint32_t GetPerFrameKey() override {
    3999           0 :     return (mIndex << nsDisplayItem::TYPE_BITS) |
    4000           0 :       nsDisplayItem::GetPerFrameKey();
    4001             :   }
    4002             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4003             :                                    LayerManager* aManager,
    4004             :                                    const ContainerLayerParameters& aParameters) override;
    4005             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4006             :                                  nsRegion* aVisibleRegion) override;
    4007             :   virtual bool TryMerge(nsDisplayItem* aItem) override;
    4008           0 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
    4009           0 :     return false;
    4010             :   }
    4011           0 :   NS_DISPLAY_DECL_NAME("BlendMode", TYPE_BLEND_MODE)
    4012             : 
    4013             : private:
    4014             :   uint8_t mBlendMode;
    4015             :   uint32_t mIndex;
    4016             : };
    4017             : 
    4018             : class nsDisplayBlendContainer : public nsDisplayWrapList {
    4019             : public:
    4020             :     static nsDisplayBlendContainer*
    4021             :     CreateForMixBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4022             :                           nsDisplayList* aList,
    4023             :                           const ActiveScrolledRoot* aActiveScrolledRoot);
    4024             : 
    4025             :     static nsDisplayBlendContainer*
    4026             :     CreateForBackgroundBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4027             :                                  nsDisplayList* aList,
    4028             :                                  const ActiveScrolledRoot* aActiveScrolledRoot);
    4029             : 
    4030             : #ifdef NS_BUILD_REFCNT_LOGGING
    4031             :     virtual ~nsDisplayBlendContainer();
    4032             : #endif
    4033             : 
    4034             :     virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4035             :                                                LayerManager* aManager,
    4036             :                                                const ContainerLayerParameters& aContainerParameters) override;
    4037             :     virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4038             :                                      LayerManager* aManager,
    4039             :                                      const ContainerLayerParameters& aParameters) override;
    4040             :     virtual bool TryMerge(nsDisplayItem* aItem) override;
    4041           0 :     virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
    4042           0 :       return false;
    4043             :     }
    4044           0 :     virtual uint32_t GetPerFrameKey() override {
    4045           0 :       return (mIsForBackground ? 1 << nsDisplayItem::TYPE_BITS : 0) |
    4046           0 :         nsDisplayItem::GetPerFrameKey();
    4047             :     }
    4048           0 :     NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
    4049             : 
    4050             : private:
    4051             :     nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4052             :                             nsDisplayList* aList,
    4053             :                             const ActiveScrolledRoot* aActiveScrolledRoot,
    4054             :                             bool aIsForBackground);
    4055             : 
    4056             :     // Used to distinguish containers created at building stacking
    4057             :     // context or appending background.
    4058             :     bool mIsForBackground;
    4059             : };
    4060             : 
    4061             : /**
    4062             :  * A display item that has no purpose but to ensure its contents get
    4063             :  * their own layer.
    4064             :  */
    4065             : class nsDisplayOwnLayer : public nsDisplayWrapList {
    4066             : public:
    4067             :   typedef mozilla::layers::ScrollThumbData ScrollThumbData;
    4068             : 
    4069             :   /**
    4070             :    * nsDisplayOwnLayer constructor flags
    4071             :    */
    4072             :   enum {
    4073             :     GENERATE_SUBDOC_INVALIDATIONS = 0x01,
    4074             :     VERTICAL_SCROLLBAR = 0x02,
    4075             :     HORIZONTAL_SCROLLBAR = 0x04,
    4076             :     GENERATE_SCROLLABLE_LAYER = 0x08,
    4077             :     SCROLLBAR_CONTAINER = 0x10
    4078             :   };
    4079             : 
    4080             :   /**
    4081             :    * @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
    4082             :    * Add UserData to the created ContainerLayer, so that invalidations
    4083             :    * for this layer are send to our nsPresContext.
    4084             :    * GENERATE_SCROLLABLE_LAYER : only valid on nsDisplaySubDocument (and
    4085             :    * subclasses), indicates this layer is to be a scrollable layer, so call
    4086             :    * ComputeFrameMetrics, etc.
    4087             :    * @param aScrollTarget when VERTICAL_SCROLLBAR or HORIZONTAL_SCROLLBAR
    4088             :    * is set in the flags, this parameter should be the ViewID of the
    4089             :    * scrollable content this scrollbar is for.
    4090             :    */
    4091             :   nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4092             :                     nsDisplayList* aList,
    4093             :                     const ActiveScrolledRoot* aActiveScrolledRoot,
    4094             :                     uint32_t aFlags = 0,
    4095             :                     ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
    4096             :                     const ScrollThumbData& aThumbData = ScrollThumbData{},
    4097             :                     bool aForceActive = true);
    4098             : #ifdef NS_BUILD_REFCNT_LOGGING
    4099             :   virtual ~nsDisplayOwnLayer();
    4100             : #endif
    4101             :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override;
    4102             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4103             :                                              LayerManager* aManager,
    4104             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4105             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4106             :                                    LayerManager* aManager,
    4107             :                                    const ContainerLayerParameters& aParameters) override;
    4108          39 :   virtual bool TryMerge(nsDisplayItem* aItem) override
    4109             :   {
    4110             :     // Don't allow merging, each sublist must have its own layer
    4111          39 :     return false;
    4112             :   }
    4113          28 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
    4114          28 :     return false;
    4115             :   }
    4116             :   uint32_t GetFlags() { return mFlags; }
    4117             :   bool IsScrollThumbLayer() const;
    4118         389 :   NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
    4119             : protected:
    4120             :   uint32_t mFlags;
    4121             :   ViewID mScrollTarget;
    4122             :   // If this nsDisplayOwnLayer represents a scroll thumb layer, mThumbData
    4123             :   // stores information about the scroll thumb. Otherwise, mThumbData will be
    4124             :   // default-constructed (in particular with mDirection == ScrollDirection::NONE)
    4125             :   // and can be ignored.
    4126             :   ScrollThumbData mThumbData;
    4127             :   bool mForceActive;
    4128             : };
    4129             : 
    4130             : /**
    4131             :  * A display item for subdocuments. This is more or less the same as nsDisplayOwnLayer,
    4132             :  * except that it always populates the FrameMetrics instance on the ContainerLayer it
    4133             :  * builds.
    4134             :  */
    4135             : class nsDisplaySubDocument : public nsDisplayOwnLayer {
    4136             : public:
    4137             :   nsDisplaySubDocument(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4138             :                        nsDisplayList* aList, uint32_t aFlags);
    4139             : #ifdef NS_BUILD_REFCNT_LOGGING
    4140             :   virtual ~nsDisplaySubDocument();
    4141             : #endif
    4142             : 
    4143             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4144             :                                              LayerManager* aManager,
    4145             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4146             : 
    4147             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    4148             : 
    4149             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4150             :                                  nsRegion* aVisibleRegion) override;
    4151             : 
    4152             :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override;
    4153             : 
    4154             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    4155             : 
    4156           0 :   NS_DISPLAY_DECL_NAME("SubDocument", TYPE_SUBDOCUMENT)
    4157             : 
    4158             :   mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(Layer* aLayer,
    4159             :                                                            const ContainerLayerParameters& aContainerParameters);
    4160             : 
    4161             : protected:
    4162             :   ViewID mScrollParentId;
    4163             :   bool mForceDispatchToContentRegion;
    4164             : };
    4165             : 
    4166             : /**
    4167             :  * A display item for subdocuments to capture the resolution from the presShell
    4168             :  * and ensure that it gets applied to all the right elements. This item creates
    4169             :  * a container layer.
    4170             :  */
    4171             : class nsDisplayResolution : public nsDisplaySubDocument {
    4172             : public:
    4173             :   nsDisplayResolution(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4174             :                       nsDisplayList* aList, uint32_t aFlags);
    4175             : #ifdef NS_BUILD_REFCNT_LOGGING
    4176             :   virtual ~nsDisplayResolution();
    4177             : #endif
    4178             :   virtual void HitTest(nsDisplayListBuilder* aBuilder,
    4179             :                        const nsRect& aRect,
    4180             :                        HitTestState* aState,
    4181             :                        nsTArray<nsIFrame*> *aOutFrames) override;
    4182             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4183             :                                              LayerManager* aManager,
    4184             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4185           0 :   NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
    4186             : };
    4187             : 
    4188             : /**
    4189             :  * A display item used to represent sticky position elements. The contents
    4190             :  * gets its own layer and creates a stacking context, and the layer will have
    4191             :  * position-related metadata set on it.
    4192             :  */
    4193             : class nsDisplayStickyPosition : public nsDisplayOwnLayer {
    4194             : public:
    4195             :   nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4196             :                           nsDisplayList* aList,
    4197             :                           const ActiveScrolledRoot* aActiveScrolledRoot);
    4198             : #ifdef NS_BUILD_REFCNT_LOGGING
    4199             :   virtual ~nsDisplayStickyPosition();
    4200             : #endif
    4201             : 
    4202             :   void SetClipChain(const DisplayItemClipChain* aClipChain) override;
    4203             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4204             :                                              LayerManager* aManager,
    4205             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4206           0 :   NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
    4207           0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4208             :                                    LayerManager* aManager,
    4209             :                                    const ContainerLayerParameters& aParameters) override
    4210             :   {
    4211           0 :     return mozilla::LAYER_ACTIVE;
    4212             :   }
    4213             :   virtual bool TryMerge(nsDisplayItem* aItem) override;
    4214             : };
    4215             : 
    4216             : class nsDisplayFixedPosition : public nsDisplayOwnLayer {
    4217             : public:
    4218             :   nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4219             :                          nsDisplayList* aList,
    4220             :                          const ActiveScrolledRoot* aActiveScrolledRoot);
    4221             : 
    4222             :   static nsDisplayFixedPosition* CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
    4223             :                                                           nsIFrame* aFrame,
    4224             :                                                           nsDisplayBackgroundImage* aImage,
    4225             :                                                           uint32_t aIndex);
    4226             : 
    4227             : 
    4228             : #ifdef NS_BUILD_REFCNT_LOGGING
    4229             :   virtual ~nsDisplayFixedPosition();
    4230             : #endif
    4231             : 
    4232             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4233             :                                              LayerManager* aManager,
    4234             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4235           0 :   NS_DISPLAY_DECL_NAME("FixedPosition", TYPE_FIXED_POSITION)
    4236           0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4237             :                                    LayerManager* aManager,
    4238             :                                    const ContainerLayerParameters& aParameters) override
    4239             :   {
    4240           0 :     return mozilla::LAYER_ACTIVE_FORCE;
    4241             :   }
    4242             :   virtual bool TryMerge(nsDisplayItem* aItem) override;
    4243             : 
    4244           0 :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override { return mIsFixedBackground; }
    4245             : 
    4246           0 :   virtual uint32_t GetPerFrameKey() override { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
    4247             : 
    4248           0 :   AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
    4249           0 :     return mAnimatedGeometryRootForScrollMetadata;
    4250             :   }
    4251             : 
    4252             : protected:
    4253             :   // For background-attachment:fixed
    4254             :   nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4255             :                          nsDisplayList* aList, uint32_t aIndex);
    4256             :   void Init(nsDisplayListBuilder* aBuilder);
    4257             : 
    4258             :   AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
    4259             :   uint32_t mIndex;
    4260             :   bool mIsFixedBackground;
    4261             : };
    4262             : 
    4263           0 : class nsDisplayTableFixedPosition : public nsDisplayFixedPosition
    4264             : {
    4265             : public:
    4266             :   static nsDisplayTableFixedPosition* CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
    4267             :                                                                nsIFrame* aFrame,
    4268             :                                                                nsDisplayBackgroundImage* aImage,
    4269             :                                                                uint32_t aIndex,
    4270             :                                                                nsIFrame* aAncestorFrame);
    4271             : 
    4272           0 :   virtual uint32_t GetPerFrameKey() override {
    4273           0 :     return (mIndex << (nsDisplayItem::TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
    4274           0 :            (static_cast<uint8_t>(mTableType) << nsDisplayItem::TYPE_BITS) |
    4275           0 :            nsDisplayItem::GetPerFrameKey();
    4276             :   }
    4277             : protected:
    4278             :   nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4279             :                               nsDisplayList* aList, uint32_t aIndex, nsIFrame* aAncestorFrame);
    4280             : 
    4281             :   TableType mTableType;
    4282             : };
    4283             : 
    4284             : /**
    4285             :  * This creates an empty scrollable layer. It has no child layers.
    4286             :  * It is used to record the existence of a scrollable frame in the layer
    4287             :  * tree.
    4288             :  */
    4289             : class nsDisplayScrollInfoLayer : public nsDisplayWrapList
    4290             : {
    4291             : public:
    4292             :   nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder,
    4293             :                            nsIFrame* aScrolledFrame, nsIFrame* aScrollFrame);
    4294           0 :   NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
    4295             : 
    4296             : 
    4297             : #ifdef NS_BUILD_REFCNT_LOGGING
    4298             :   virtual ~nsDisplayScrollInfoLayer();
    4299             : #endif
    4300             : 
    4301             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4302             :                                              LayerManager* aManager,
    4303             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4304             : 
    4305           0 :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override
    4306           0 :   { return true; }
    4307             : 
    4308           0 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4309             :                                    bool* aSnap) override {
    4310           0 :     *aSnap = false;
    4311           0 :     return nsRegion();
    4312             :   }
    4313             : 
    4314             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4315             :                                    LayerManager* aManager,
    4316             :                                    const ContainerLayerParameters& aParameters) override;
    4317             : 
    4318           0 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
    4319           0 :   { return false; }
    4320             : 
    4321             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    4322             : 
    4323             :   mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(Layer* aLayer,
    4324             :                                                            const ContainerLayerParameters& aContainerParameters);
    4325             : 
    4326             : protected:
    4327             :   nsIFrame* mScrollFrame;
    4328             :   nsIFrame* mScrolledFrame;
    4329             :   ViewID mScrollParentId;
    4330             : };
    4331             : 
    4332             : /**
    4333             :  * nsDisplayZoom is used for subdocuments that have a different full zoom than
    4334             :  * their parent documents. This item creates a container layer.
    4335             :  */
    4336             : class nsDisplayZoom : public nsDisplaySubDocument {
    4337             : public:
    4338             :   /**
    4339             :    * @param aFrame is the root frame of the subdocument.
    4340             :    * @param aList contains the display items for the subdocument.
    4341             :    * @param aAPD is the app units per dev pixel ratio of the subdocument.
    4342             :    * @param aParentAPD is the app units per dev pixel ratio of the parent
    4343             :    * document.
    4344             :    * @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
    4345             :    * Add UserData to the created ContainerLayer, so that invalidations
    4346             :    * for this layer are send to our nsPresContext.
    4347             :    */
    4348             :   nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4349             :                 nsDisplayList* aList,
    4350             :                 int32_t aAPD, int32_t aParentAPD,
    4351             :                 uint32_t aFlags = 0);
    4352             : #ifdef NS_BUILD_REFCNT_LOGGING
    4353             :   virtual ~nsDisplayZoom();
    4354             : #endif
    4355             : 
    4356             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
    4357             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4358             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    4359             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4360             :                                  nsRegion* aVisibleRegion) override;
    4361           0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4362             :                                    LayerManager* aManager,
    4363             :                                    const ContainerLayerParameters& aParameters) override
    4364             :   {
    4365           0 :     return mozilla::LAYER_ACTIVE;
    4366             :   }
    4367           0 :   NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM)
    4368             : 
    4369             :   // Get the app units per dev pixel ratio of the child document.
    4370             :   int32_t GetChildAppUnitsPerDevPixel() { return mAPD; }
    4371             :   // Get the app units per dev pixel ratio of the parent document.
    4372           0 :   int32_t GetParentAppUnitsPerDevPixel() { return mParentAPD; }
    4373             : 
    4374             : private:
    4375             :   int32_t mAPD, mParentAPD;
    4376             : };
    4377             : 
    4378             : class nsDisplaySVGEffects: public nsDisplayWrapList {
    4379             : public:
    4380             :   nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4381             :                       nsDisplayList* aList, bool aHandleOpacity,
    4382             :                       const ActiveScrolledRoot* aActiveScrolledRoot);
    4383             :   nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4384             :                       nsDisplayList* aList, bool aHandleOpacity);
    4385             : #ifdef NS_BUILD_REFCNT_LOGGING
    4386             :   virtual ~nsDisplaySVGEffects();
    4387             : #endif
    4388             : 
    4389             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4390             :                                    bool* aSnap) override;
    4391             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4392             :                        HitTestState* aState,
    4393             :                        nsTArray<nsIFrame*> *aOutFrames) override;
    4394             : 
    4395           7 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
    4396           7 :     return false;
    4397             :   }
    4398             : 
    4399             :   gfxRect BBoxInUserSpace() const;
    4400             :   gfxPoint UserSpaceOffset() const;
    4401             : 
    4402             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4403             :                                          const nsDisplayItemGeometry* aGeometry,
    4404             :                                          nsRegion* aInvalidRegion) override;
    4405             : protected:
    4406             :   bool ValidateSVGFrame();
    4407             : 
    4408             :   // relative to mFrame
    4409             :   nsRect mEffectsBounds;
    4410             :   // True if we need to handle css opacity in this display item.
    4411             :   bool mHandleOpacity;
    4412             : };
    4413             : 
    4414             : /**
    4415             :  * A display item to paint a stacking context with mask and clip effects
    4416             :  * set by the stacking context root frame's style.
    4417             :  */
    4418             : class nsDisplayMask : public nsDisplaySVGEffects {
    4419             : public:
    4420             :   typedef mozilla::layers::ImageLayer ImageLayer;
    4421             : 
    4422             :   nsDisplayMask(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4423             :                 nsDisplayList* aList, bool aHandleOpacity,
    4424             :                 const ActiveScrolledRoot* aActiveScrolledRoot);
    4425             : #ifdef NS_BUILD_REFCNT_LOGGING
    4426             :   virtual ~nsDisplayMask();
    4427             : #endif
    4428             : 
    4429         126 :   NS_DISPLAY_DECL_NAME("Mask", TYPE_MASK)
    4430             : 
    4431             :   virtual bool TryMerge(nsDisplayItem* aItem) override;
    4432             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4433             :                                              LayerManager* aManager,
    4434             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4435             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4436             :                                    LayerManager* aManager,
    4437             :                                    const ContainerLayerParameters& aParameters) override;
    4438             : 
    4439             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4440             :                                  nsRegion* aVisibleRegion) override;
    4441             : 
    4442           2 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    4443             :   {
    4444           2 :     return new nsDisplayMaskGeometry(this, aBuilder);
    4445             :   }
    4446             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4447             :                                          const nsDisplayItemGeometry* aGeometry,
    4448             :                                          nsRegion* aInvalidRegion) override;
    4449             : #ifdef MOZ_DUMP_PAINTING
    4450             :   void PrintEffects(nsACString& aTo);
    4451             : #endif
    4452             : 
    4453             :   void PaintAsLayer(nsDisplayListBuilder* aBuilder,
    4454             :                     gfxContext* aCtx,
    4455             :                     LayerManager* aManager);
    4456             : 
    4457             :   /*
    4458             :    * Paint mask onto aMaskContext in mFrame's coordinate space and
    4459             :    * return whether the mask layer was painted successfully.
    4460             :    */
    4461             :   bool PaintMask(nsDisplayListBuilder* aBuilder, gfxContext* aMaskContext);
    4462             : 
    4463           2 :   const nsTArray<nsRect>& GetDestRects()
    4464             :   {
    4465           2 :     return mDestRects;
    4466             :   }
    4467             : private:
    4468             :   // According to mask property and the capability of aManager, determine
    4469             :   // whether paint mask onto a dedicate mask layer.
    4470             :   bool ShouldPaintOnMaskLayer(LayerManager* aManager);
    4471             : 
    4472             :   nsTArray<nsRect> mDestRects;
    4473             : };
    4474             : 
    4475             : /**
    4476             :  * A display item to paint a stacking context with filter effects set by the
    4477             :  * stacking context root frame's style.
    4478             :  */
    4479             : class nsDisplayFilter : public nsDisplaySVGEffects {
    4480             : public:
    4481             :   nsDisplayFilter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4482             :                   nsDisplayList* aList, bool aHandleOpacity);
    4483             : #ifdef NS_BUILD_REFCNT_LOGGING
    4484             :   virtual ~nsDisplayFilter();
    4485             : #endif
    4486             : 
    4487           0 :   NS_DISPLAY_DECL_NAME("Filter", TYPE_FILTER)
    4488             : 
    4489             :   virtual bool TryMerge(nsDisplayItem* aItem) override;
    4490             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4491             :                                              LayerManager* aManager,
    4492             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4493             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4494             :                                    LayerManager* aManager,
    4495             :                                    const ContainerLayerParameters& aParameters) override;
    4496           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    4497             :                            bool* aSnap) override {
    4498           0 :     *aSnap = false;
    4499           0 :     return mEffectsBounds + ToReferenceFrame();
    4500             :   }
    4501             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4502             :                                  nsRegion* aVisibleRegion) override;
    4503           0 :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    4504             :   {
    4505           0 :     return new nsDisplayFilterGeometry(this, aBuilder);
    4506             :   }
    4507             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4508             :                                          const nsDisplayItemGeometry* aGeometry,
    4509             :                                          nsRegion* aInvalidRegion) override;
    4510             : #ifdef MOZ_DUMP_PAINTING
    4511             :   void PrintEffects(nsACString& aTo);
    4512             : #endif
    4513             : 
    4514             :   void PaintAsLayer(nsDisplayListBuilder* aBuilder,
    4515             :                     gfxContext* aCtx,
    4516             :                     LayerManager* aManager);
    4517             : };
    4518             : 
    4519             : /* A display item that applies a transformation to all of its descendant
    4520             :  * elements.  This wrapper should only be used if there is a transform applied
    4521             :  * to the root element.
    4522             :  *
    4523             :  * The reason that a "bounds" rect is involved in transform calculations is
    4524             :  * because CSS-transforms allow percentage values for the x and y components
    4525             :  * of <translation-value>s, where percentages are percentages of the element's
    4526             :  * border box.
    4527             :  *
    4528             :  * INVARIANT: The wrapped frame is transformed or we supplied a transform getter
    4529             :  * function.
    4530             :  * INVARIANT: The wrapped frame is non-null.
    4531             :  */
    4532             : class nsDisplayTransform: public nsDisplayItem
    4533             : {
    4534             :   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
    4535             :   typedef mozilla::gfx::Point3D Point3D;
    4536             : 
    4537             :   /*
    4538             :    * Avoid doing UpdateBounds() during construction.
    4539             :    */
    4540             :   class StoreList : public nsDisplayWrapList {
    4541             :   public:
    4542          24 :     StoreList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4543          24 :               nsDisplayList* aList) :
    4544          24 :       nsDisplayWrapList(aBuilder, aFrame, aList) {}
    4545           0 :     StoreList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4546           0 :               nsDisplayItem* aItem) :
    4547           0 :       nsDisplayWrapList(aBuilder, aFrame, aItem) {}
    4548          24 :     virtual ~StoreList() {}
    4549             : 
    4550           0 :     virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override {
    4551             :       // For extending 3d rendering context, the bounds would be
    4552             :       // updated by DoUpdateBoundsPreserves3D(), not here.
    4553           0 :       if (!mFrame->Extend3DContext()) {
    4554           0 :         nsDisplayWrapList::UpdateBounds(aBuilder);
    4555             :       }
    4556           0 :     }
    4557           0 :     virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
    4558           0 :       for (nsDisplayItem *i = mList.GetBottom(); i; i = i->GetAbove()) {
    4559           0 :         i->DoUpdateBoundsPreserves3D(aBuilder);
    4560             :       }
    4561           0 :       nsDisplayWrapList::UpdateBounds(aBuilder);
    4562           0 :     }
    4563             :   };
    4564             : 
    4565             : public:
    4566             :   enum PrerenderDecision {
    4567             :     NoPrerender,
    4568             :     FullPrerender,
    4569             :     PartialPrerender
    4570             :   };
    4571             : 
    4572             :   /**
    4573             :    * Returns a matrix (in pixels) for the current frame. The matrix should be relative to
    4574             :    * the current frame's coordinate space.
    4575             :    *
    4576             :    * @param aFrame The frame to compute the transform for.
    4577             :    * @param aAppUnitsPerPixel The number of app units per graphics unit.
    4578             :    */
    4579             :   typedef Matrix4x4 (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel);
    4580             : 
    4581             :   /* Constructor accepts a display list, empties it, and wraps it up.  It also
    4582             :    * ferries the underlying frame to the nsDisplayItem constructor.
    4583             :    */
    4584             :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    4585             :                      nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
    4586             :                      uint32_t aIndex = 0, bool aAllowAsyncAnimation = false);
    4587             :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    4588             :                      nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect,
    4589             :                      uint32_t aIndex = 0);
    4590             :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    4591             :                      nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
    4592             :                      ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
    4593             :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    4594             :                      nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
    4595             :                      const Matrix4x4& aTransform, uint32_t aIndex = 0);
    4596             : 
    4597             : #ifdef NS_BUILD_REFCNT_LOGGING
    4598          24 :   virtual ~nsDisplayTransform()
    4599          48 :   {
    4600          24 :     MOZ_COUNT_DTOR(nsDisplayTransform);
    4601          24 :   }
    4602             : #endif
    4603             : 
    4604         216 :   NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
    4605             : 
    4606           2 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override
    4607             :   {
    4608           2 :     if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
    4609           2 :       return nsRect();
    4610             :     bool snap;
    4611           0 :     return GetBounds(aBuilder, &snap);
    4612             :   }
    4613             : 
    4614           0 :   virtual nsDisplayList* GetChildren() override { return mStoredList.GetChildren(); }
    4615             : 
    4616             :   virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
    4617             :                        HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames) override;
    4618             :   virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) override;
    4619             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
    4620             :                                    bool* aSnap) override;
    4621             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder *aBuilder) override;
    4622             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4623             :                                    LayerManager* aManager,
    4624             :                                    const ContainerLayerParameters& aParameters) override;
    4625             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4626             :                                              LayerManager* aManager,
    4627             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4628             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4629             :                                        const StackingContextHelper& aSc,
    4630             :                                        nsTArray<WebRenderParentCommand>& aParentCommands,
    4631             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    4632             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    4633             :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override;
    4634             :   virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
    4635             :                                  nsRegion *aVisibleRegion) override;
    4636             :   virtual bool TryMerge(nsDisplayItem *aItem) override;
    4637             : 
    4638          72 :   virtual uint32_t GetPerFrameKey() override { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
    4639             : 
    4640           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4641             :                                          const nsDisplayItemGeometry* aGeometry,
    4642             :                                          nsRegion* aInvalidRegion) override
    4643             :   {
    4644             :     // We don't need to compute an invalidation region since we have LayerTreeInvalidation
    4645           0 :   }
    4646             : 
    4647          24 :   virtual const nsIFrame* ReferenceFrameForChildren() const override {
    4648             :     // If we were created using a transform-getter, then we don't
    4649             :     // belong to a transformed frame, and aren't a reference frame
    4650             :     // for our children.
    4651          24 :     if (!mTransformGetter) {
    4652          24 :       return mFrame;
    4653             :     }
    4654           0 :     return nsDisplayItem::ReferenceFrameForChildren();
    4655             :   }
    4656             : 
    4657           0 :   AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
    4658           0 :     return mAnimatedGeometryRootForScrollMetadata;
    4659             :   }
    4660             : 
    4661          24 :   virtual const nsRect& GetVisibleRectForChildren() const override
    4662             :   {
    4663          24 :     return mChildrenVisibleRect;
    4664             :   }
    4665             : 
    4666             :   enum {
    4667             :     INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS
    4668             :   };
    4669             : 
    4670             :   /**
    4671             :    * We include the perspective matrix from our containing block for the
    4672             :    * purposes of visibility calculations, but we exclude it from the transform
    4673             :    * we set on the layer (for rendering), since there will be an
    4674             :    * nsDisplayPerspective created for that.
    4675             :    */
    4676             :   const Matrix4x4& GetTransform();
    4677             :   Matrix4x4 GetTransformForRendering();
    4678             : 
    4679             :   /**
    4680             :    * Return the transform that is aggregation of all transform on the
    4681             :    * preserves3d chain.
    4682             :    */
    4683             :   const Matrix4x4& GetAccumulatedPreserved3DTransform(nsDisplayListBuilder* aBuilder);
    4684             : 
    4685             :   float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint);
    4686             : 
    4687             :   /**
    4688             :    * TransformRect takes in as parameters a rectangle (in aFrame's coordinate
    4689             :    * space) and returns the smallest rectangle (in aFrame's coordinate space)
    4690             :    * containing the transformed image of that rectangle.  That is, it takes
    4691             :    * the four corners of the rectangle, transforms them according to the
    4692             :    * matrix associated with the specified frame, then returns the smallest
    4693             :    * rectangle containing the four transformed points.
    4694             :    *
    4695             :    * @param untransformedBounds The rectangle (in app units) to transform.
    4696             :    * @param aFrame The frame whose transformation should be applied.  This
    4697             :    *        function raises an assertion if aFrame is null or doesn't have a
    4698             :    *        transform applied to it.
    4699             :    * @param aOrigin The origin of the transform relative to aFrame's local
    4700             :    *        coordinate space.
    4701             :    * @param aBoundsOverride (optional) Rather than using the frame's computed
    4702             :    *        bounding rect as frame bounds, use this rectangle instead.  Pass
    4703             :    *        nullptr (or nothing at all) to use the default.
    4704             :    */
    4705             :   static nsRect TransformRect(const nsRect &aUntransformedBounds,
    4706             :                               const nsIFrame* aFrame,
    4707             :                               const nsRect* aBoundsOverride = nullptr);
    4708             : 
    4709             :   /* UntransformRect is like TransformRect, except that it inverts the
    4710             :    * transform.
    4711             :    */
    4712             :   static bool UntransformRect(const nsRect &aTransformedBounds,
    4713             :                               const nsRect &aChildBounds,
    4714             :                               const nsIFrame* aFrame,
    4715             :                               nsRect *aOutRect);
    4716             : 
    4717             :   bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
    4718             :                               nsRect* aOutRect);
    4719             : 
    4720             :   static Point3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
    4721             :                                            float aAppUnitsPerPixel,
    4722             :                                            const nsRect* aBoundsOverride);
    4723             : 
    4724             :   /*
    4725             :    * Returns true if aFrame has perspective applied from its containing
    4726             :    * block.
    4727             :    * Returns the matrix to append to apply the persective (taking
    4728             :    * perspective-origin into account), relative to aFrames coordinate
    4729             :    * space).
    4730             :    * aOutMatrix is assumed to be the identity matrix, and isn't explicitly
    4731             :    * cleared.
    4732             :    */
    4733             :   static bool ComputePerspectiveMatrix(const nsIFrame* aFrame,
    4734             :                                        float aAppUnitsPerPixel,
    4735             :                                        Matrix4x4& aOutMatrix);
    4736             : 
    4737         194 :   struct FrameTransformProperties
    4738             :   {
    4739             :     FrameTransformProperties(const nsIFrame* aFrame,
    4740             :                              float aAppUnitsPerPixel,
    4741             :                              const nsRect* aBoundsOverride);
    4742           0 :     FrameTransformProperties(nsCSSValueSharedList* aTransformList,
    4743             :                              const Point3D& aToTransformOrigin)
    4744           0 :       : mFrame(nullptr)
    4745             :       , mTransformList(aTransformList)
    4746           0 :       , mToTransformOrigin(aToTransformOrigin)
    4747           0 :     {}
    4748             : 
    4749             :     const nsIFrame* mFrame;
    4750             :     RefPtr<nsCSSValueSharedList> mTransformList;
    4751             :     const Point3D mToTransformOrigin;
    4752             :   };
    4753             : 
    4754             :   /**
    4755             :    * Given a frame with the -moz-transform property or an SVG transform,
    4756             :    * returns the transformation matrix for that frame.
    4757             :    *
    4758             :    * @param aFrame The frame to get the matrix from.
    4759             :    * @param aOrigin Relative to which point this transform should be applied.
    4760             :    * @param aAppUnitsPerPixel The number of app units per graphics unit.
    4761             :    * @param aBoundsOverride [optional] If this is nullptr (the default), the
    4762             :    *        computation will use the value of TransformReferenceBox(aFrame).
    4763             :    *        Otherwise, it will use the value of aBoundsOverride.  This is
    4764             :    *        mostly for internal use and in most cases you will not need to
    4765             :    *        specify a value.
    4766             :    * @param aFlags OFFSET_BY_ORIGIN The resulting matrix will be translated
    4767             :    *        by aOrigin. This translation is applied *before* the CSS transform.
    4768             :    * @param aFlags INCLUDE_PRESERVE3D_ANCESTORS The computed transform will
    4769             :    *        include the transform of any ancestors participating in the same
    4770             :    *        3d rendering context.
    4771             :    * @param aFlags INCLUDE_PERSPECTIVE The resulting matrix will include the
    4772             :    *        perspective transform from the containing block if applicable.
    4773             :    */
    4774             :   enum {
    4775             :     OFFSET_BY_ORIGIN = 1 << 0,
    4776             :     INCLUDE_PRESERVE3D_ANCESTORS = 1 << 1,
    4777             :     INCLUDE_PERSPECTIVE = 1 << 2,
    4778             :   };
    4779             :   static Matrix4x4 GetResultingTransformMatrix(const nsIFrame* aFrame,
    4780             :                                                const nsPoint& aOrigin,
    4781             :                                                float aAppUnitsPerPixel,
    4782             :                                                uint32_t aFlags,
    4783             :                                                const nsRect* aBoundsOverride = nullptr);
    4784             :   static Matrix4x4 GetResultingTransformMatrix(const FrameTransformProperties& aProperties,
    4785             :                                                const nsPoint& aOrigin,
    4786             :                                                float aAppUnitsPerPixel,
    4787             :                                                uint32_t aFlags,
    4788             :                                                const nsRect* aBoundsOverride = nullptr);
    4789             :   /**
    4790             :    * Decide whether we should prerender some or all of the contents of the
    4791             :    * transformed frame even when it's not completely visible (yet).
    4792             :    * Return FullPrerender if the entire contents should be prerendered,
    4793             :    * PartialPrerender if some but not all of the contents should be prerendered,
    4794             :    * or NoPrerender if only the visible area should be rendered.
    4795             :    * |aDirtyRect| is updated to the area that should be prerendered.
    4796             :    */
    4797             :   static PrerenderDecision ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
    4798             :                                                              nsIFrame* aFrame,
    4799             :                                                              nsRect* aDirtyRect);
    4800             :   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
    4801             : 
    4802             :   bool MayBeAnimated(nsDisplayListBuilder* aBuilder);
    4803             : 
    4804             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    4805             : 
    4806             :   // Force the layer created for this item not to extend 3D context.
    4807             :   // See nsIFrame::BuildDisplayListForStackingContext()
    4808           0 :   void SetNoExtendContext() { mNoExtendContext = true; }
    4809             : 
    4810           0 :   virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
    4811           0 :     MOZ_ASSERT(mFrame->Combines3DTransformWithAncestors() ||
    4812             :                IsTransformSeparator());
    4813             :     // Updating is not going through to child 3D context.
    4814           0 :     ComputeBounds(aBuilder);
    4815           0 :   }
    4816             : 
    4817             :   /**
    4818             :    * This function updates bounds for items with a frame establishing
    4819             :    * 3D rendering context.
    4820             :    *
    4821             :    * \see nsDisplayItem::DoUpdateBoundsPreserves3D()
    4822             :    */
    4823          24 :   void UpdateBoundsFor3D(nsDisplayListBuilder* aBuilder) {
    4824          48 :     if (!mFrame->Extend3DContext() ||
    4825          24 :         mFrame->Combines3DTransformWithAncestors() ||
    4826           0 :         IsTransformSeparator()) {
    4827             :       // Not an establisher of a 3D rendering context.
    4828          24 :       return;
    4829             :     }
    4830             :     // Always start updating from an establisher of a 3D rendering context.
    4831             : 
    4832           0 :     nsDisplayListBuilder::AutoAccumulateRect accRect(aBuilder);
    4833           0 :     nsDisplayListBuilder::AutoAccumulateTransform accTransform(aBuilder);
    4834           0 :     accTransform.StartRoot();
    4835           0 :     ComputeBounds(aBuilder);
    4836           0 :     mBounds = aBuilder->GetAccumulatedRect();
    4837           0 :     mHasBounds = true;
    4838             :   }
    4839             : 
    4840             :   /**
    4841             :    * This item is an additional item as the boundary between parent
    4842             :    * and child 3D rendering context.
    4843             :    * \see nsIFrame::BuildDisplayListForStackingContext().
    4844             :    */
    4845           0 :   bool IsTransformSeparator() { return mIsTransformSeparator; }
    4846             :   /**
    4847             :    * This item is the boundary between parent and child 3D rendering
    4848             :    * context.
    4849             :    */
    4850           0 :   bool IsLeafOf3DContext() {
    4851           0 :     return (IsTransformSeparator() ||
    4852           0 :             (!mFrame->Extend3DContext() &&
    4853           0 :              mFrame->Combines3DTransformWithAncestors()));
    4854             :   }
    4855             :   /**
    4856             :    * The backing frame of this item participates a 3D rendering
    4857             :    * context.
    4858             :    */
    4859           0 :   bool IsParticipating3DContext() {
    4860           0 :     return mFrame->Extend3DContext() ||
    4861           0 :       mFrame->Combines3DTransformWithAncestors();
    4862             :   }
    4863             : 
    4864             : private:
    4865             :   void ComputeBounds(nsDisplayListBuilder* aBuilder);
    4866             :   void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
    4867             :   void Init(nsDisplayListBuilder* aBuilder);
    4868             : 
    4869             :   static Matrix4x4 GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties,
    4870             :                                                        const nsPoint& aOrigin,
    4871             :                                                        float aAppUnitsPerPixel,
    4872             :                                                        uint32_t aFlags,
    4873             :                                                        const nsRect* aBoundsOverride);
    4874             : 
    4875             :   StoreList mStoredList;
    4876             :   Matrix4x4 mTransform;
    4877             :   // Accumulated transform of ancestors on the preserves-3d chain.
    4878             :   Matrix4x4 mTransformPreserves3D;
    4879             :   ComputeTransformFunction mTransformGetter;
    4880             :   AnimatedGeometryRoot* mAnimatedGeometryRootForChildren;
    4881             :   AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
    4882             :   nsRect mChildrenVisibleRect;
    4883             :   uint32_t mIndex;
    4884             :   nsRect mBounds;
    4885             :   // True for mBounds is valid.
    4886             :   bool mHasBounds;
    4887             :   // Be forced not to extend 3D context.  Since we don't create a
    4888             :   // transform item, a container layer, for every frames in a
    4889             :   // preserves3d context, the transform items of a child preserves3d
    4890             :   // context may extend the parent context not intented if the root of
    4891             :   // the child preserves3d context doesn't create a transform item.
    4892             :   // With this flags, we force the item not extending 3D context.
    4893             :   bool mNoExtendContext;
    4894             :   // This item is a separator between 3D rendering contexts, and
    4895             :   // mTransform have been presetted by the constructor.
    4896             :   bool mIsTransformSeparator;
    4897             :   // True if mTransformPreserves3D have been initialized.
    4898             :   bool mTransformPreserves3DInited;
    4899             :   // True if async animation of the transform is allowed.
    4900             :   bool mAllowAsyncAnimation;
    4901             : };
    4902             : 
    4903             : /* A display item that applies a perspective transformation to a single
    4904             :  * nsDisplayTransform child item. We keep this as a separate item since the
    4905             :  * perspective-origin is relative to an ancestor of the transformed frame, and
    4906             :  * APZ can scroll the child separately.
    4907             :  */
    4908           0 : class nsDisplayPerspective : public nsDisplayItem
    4909             : {
    4910             :   typedef mozilla::gfx::Point3D Point3D;
    4911             : 
    4912             : public:
    4913           0 :   NS_DISPLAY_DECL_NAME("nsDisplayPerspective", TYPE_PERSPECTIVE)
    4914             : 
    4915             :   nsDisplayPerspective(nsDisplayListBuilder* aBuilder, nsIFrame* aTransformFrame,
    4916             :                        nsIFrame* aPerspectiveFrame,
    4917             :                        nsDisplayList* aList);
    4918             : 
    4919           0 :   virtual uint32_t GetPerFrameKey() override { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
    4920             : 
    4921           0 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4922             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override
    4923             :   {
    4924           0 :     return mList.HitTest(aBuilder, aRect, aState, aOutFrames);
    4925             :   }
    4926             : 
    4927           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
    4928             :   {
    4929           0 :     return mList.GetBounds(aBuilder, aSnap);
    4930             :   }
    4931             : 
    4932           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4933             :                                          const nsDisplayItemGeometry* aGeometry,
    4934             :                                          nsRegion* aInvalidRegion) override
    4935           0 :   {}
    4936             : 
    4937           0 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4938             :                                    bool* aSnap) override
    4939             :   {
    4940           0 :     return mList.GetOpaqueRegion(aBuilder, aSnap);
    4941             :   }
    4942             : 
    4943           0 :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override
    4944             :   {
    4945           0 :     return mList.IsUniform(aBuilder);
    4946             :   }
    4947             : 
    4948             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4949             :                                    LayerManager* aManager,
    4950             :                                    const ContainerLayerParameters& aParameters) override;
    4951             : 
    4952           0 :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override
    4953             :   {
    4954           0 :     if (!mList.GetChildren()->GetTop()) {
    4955           0 :       return false;
    4956             :     }
    4957           0 :     return mList.GetChildren()->GetTop()->ShouldBuildLayerEvenIfInvisible(aBuilder);
    4958             :   }
    4959             : 
    4960             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4961             :                                              LayerManager* aManager,
    4962             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4963             : 
    4964           0 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4965             :                                  nsRegion* aVisibleRegion) override
    4966             :   {
    4967           0 :     mList.RecomputeVisibility(aBuilder, aVisibleRegion);
    4968           0 :     return true;
    4969             :   }
    4970           0 :   virtual nsDisplayList* GetSameCoordinateSystemChildren() override { return mList.GetChildren(); }
    4971           0 :   virtual nsDisplayList* GetChildren() override { return mList.GetChildren(); }
    4972           0 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override
    4973             :   {
    4974           0 :     return mList.GetComponentAlphaBounds(aBuilder);
    4975             :   }
    4976             : 
    4977           0 :   nsIFrame* TransformFrame() { return mTransformFrame; }
    4978             : 
    4979             :   virtual int32_t ZIndex() const override;
    4980             : 
    4981             :   virtual void
    4982           0 :   DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
    4983           0 :     if (mList.GetChildren()->GetTop()) {
    4984           0 :       static_cast<nsDisplayTransform*>(mList.GetChildren()->GetTop())->DoUpdateBoundsPreserves3D(aBuilder);
    4985             :     }
    4986           0 :   }
    4987             : 
    4988             : private:
    4989             :   nsDisplayWrapList mList;
    4990             :   nsIFrame* mTransformFrame;
    4991             :   uint32_t mIndex;
    4992             : };
    4993             : 
    4994             : /**
    4995             :  * This class adds basic support for limiting the rendering (in the inline axis
    4996             :  * of the writing mode) to the part inside the specified edges.  It's a base
    4997             :  * class for the display item classes that do the actual work.
    4998             :  * The two members, mVisIStartEdge and mVisIEndEdge, are relative to the edges
    4999             :  * of the frame's scrollable overflow rectangle and are the amount to suppress
    5000             :  * on each side.
    5001             :  *
    5002             :  * Setting none, both or only one edge is allowed.
    5003             :  * The values must be non-negative.
    5004             :  * The default value for both edges is zero, which means everything is painted.
    5005             :  */
    5006          73 : class nsCharClipDisplayItem : public nsDisplayItem {
    5007             : public:
    5008          73 :   nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    5009          73 :     : nsDisplayItem(aBuilder, aFrame), mVisIStartEdge(0), mVisIEndEdge(0) {}
    5010             : 
    5011           0 :   explicit nsCharClipDisplayItem(nsIFrame* aFrame)
    5012           0 :     : nsDisplayItem(aFrame) {}
    5013             : 
    5014             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
    5015             : 
    5016             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    5017             :                                          const nsDisplayItemGeometry* aGeometry,
    5018             :                                          nsRegion* aInvalidRegion) override;
    5019             : 
    5020             :   struct ClipEdges {
    5021          17 :     ClipEdges(const nsDisplayItem& aItem,
    5022          17 :               nscoord aVisIStartEdge, nscoord aVisIEndEdge) {
    5023          34 :       nsRect r = aItem.Frame()->GetScrollableOverflowRect() +
    5024          51 :                  aItem.ToReferenceFrame();
    5025          17 :       if (aItem.Frame()->GetWritingMode().IsVertical()) {
    5026           0 :         mVisIStart = aVisIStartEdge > 0 ? r.y + aVisIStartEdge : nscoord_MIN;
    5027           0 :         mVisIEnd =
    5028           0 :           aVisIEndEdge > 0 ? std::max(r.YMost() - aVisIEndEdge, mVisIStart)
    5029           0 :                            : nscoord_MAX;
    5030             :       } else {
    5031          17 :         mVisIStart = aVisIStartEdge > 0 ? r.x + aVisIStartEdge : nscoord_MIN;
    5032          17 :         mVisIEnd =
    5033          34 :           aVisIEndEdge > 0 ? std::max(r.XMost() - aVisIEndEdge, mVisIStart)
    5034          17 :                            : nscoord_MAX;
    5035             :       }
    5036          17 :     }
    5037           0 :     void Intersect(nscoord* aVisIStart, nscoord* aVisISize) const {
    5038           0 :       nscoord end = *aVisIStart + *aVisISize;
    5039           0 :       *aVisIStart = std::max(*aVisIStart, mVisIStart);
    5040           0 :       *aVisISize = std::max(std::min(end, mVisIEnd) - *aVisIStart, 0);
    5041           0 :     }
    5042             :     nscoord mVisIStart;
    5043             :     nscoord mVisIEnd;
    5044             :   };
    5045             : 
    5046             :   ClipEdges Edges() const {
    5047             :     return ClipEdges(*this, mVisIStartEdge, mVisIEndEdge);
    5048             :   }
    5049             : 
    5050           0 :   static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) {
    5051           0 :     nsDisplayItem::Type t = aItem->GetType();
    5052             :     return (t == nsDisplayItem::TYPE_TEXT)
    5053           0 :       ? static_cast<nsCharClipDisplayItem*>(aItem) : nullptr;
    5054             :   }
    5055             : 
    5056             :   // Lengths measured from the visual inline start and end sides
    5057             :   // (i.e. left and right respectively in horizontal writing modes,
    5058             :   // regardless of bidi directionality; top and bottom in vertical modes).
    5059             :   nscoord mVisIStartEdge;
    5060             :   nscoord mVisIEndEdge;
    5061             :   // Cached result of mFrame->IsSelected().  Only initialized when needed.
    5062             :   mutable mozilla::Maybe<bool> mIsFrameSelected;
    5063             : };
    5064             : 
    5065             : namespace mozilla {
    5066             : 
    5067             : class PaintTelemetry
    5068             : {
    5069             :  public:
    5070             :   enum class Metric {
    5071             :     DisplayList,
    5072             :     Layerization,
    5073             :     Rasterization,
    5074             :     COUNT,
    5075             :   };
    5076             : 
    5077             :   class AutoRecord
    5078             :   {
    5079             :    public:
    5080             :     explicit AutoRecord(Metric aMetric);
    5081             :     ~AutoRecord();
    5082             : 
    5083          88 :     TimeStamp GetStart() const {
    5084          88 :       return mStart;
    5085             :     }
    5086             :    private:
    5087             :     Metric mMetric;
    5088             :     mozilla::TimeStamp mStart;
    5089             :   };
    5090             : 
    5091             :   class AutoRecordPaint
    5092             :   {
    5093             :    public:
    5094             :     AutoRecordPaint();
    5095             :     ~AutoRecordPaint();
    5096             :    private:
    5097             :     mozilla::TimeStamp mStart;
    5098             :   };
    5099             : 
    5100             :  private:
    5101             :   static uint32_t sPaintLevel;
    5102             :   static uint32_t sMetricLevel;
    5103             :   static mozilla::EnumeratedArray<Metric, Metric::COUNT, double> sMetrics;
    5104             : };
    5105             : 
    5106             : } // namespace mozilla
    5107             : 
    5108             : #endif /*NSDISPLAYLIST_H_*/

Generated by: LCOV version 1.13